118 return _(
"unbreak input profile");
123 return dt_iop_set_description(self, _(
"correct input color profiles meant to be applied on non-linear RGB"),
125 _(
"linear, RGB, display-referred"),
126 _(
"non-linear, RGB"),
127 _(
"non-linear, RGB, display-referred"));
149 memset(&
p, 0,
sizeof(
p));
152 p.grey_point = 18.00f;
153 p.security_factor = 0.0f;
156 p.dynamic_range = 16.0f;
157 p.shadows_range = -12.0f;
162 p.dynamic_range = 14.0f;
163 p.shadows_range = -10.50f;
168 p.dynamic_range = 12.0f;
169 p.shadows_range = -9.0f;
174 p.dynamic_range = 10.0f;
175 p.shadows_range = -7.50f;
180 p.dynamic_range = 8.0f;
181 p.shadows_range = -6.0f;
188 const int new_version)
190 if(old_version == 1 && new_version == 2)
192 typedef struct dt_iop_profilegamma_params_v1_t
196 } dt_iop_profilegamma_params_v1_t;
198 dt_iop_profilegamma_params_v1_t *o = (dt_iop_profilegamma_params_v1_t *)old_params;
204 n->linear = o->linear;
214 const void *
const ivoid,
void *
const ovoid)
234 const float noise = powf(2.0f, -16.0f);
238 float tmp = ((
const float *)ivoid)[
k] / grey;
248 ((
float *)
ovoid)[
k] = tmp;
259 const float *in = ((
float *)ivoid) + (size_t)
ch *
k * roi_out->
width;
262 for(
int j = 0; j < roi_out->
width; j++, in +=
ch,
out +=
ch)
264 for(
int i = 0;
i < 3;
i++)
268 out[
i] = data->
table[CLAMP((
int)(in[
i] * 0x10000ul), 0, 0xffff)];
290 p->grey_point = 100.f * grey;
305 float noise = powf(2.0f, -16.0f);
310 EVmin *= (1.0f +
p->security_factor / 100.0f);
312 p->shadows_range = EVmin;
327 float noise = powf(2.0f, -16.0f);
330 float EVmin =
p->shadows_range;
335 EVmax *= (1.0f +
p->security_factor / 100.0f);
337 p->dynamic_range = EVmax - EVmin;
351 float noise = powf(2.0f, -16.0f);
355 p->grey_point = 100.f * grey;
360 EVmin *= (1.0f +
p->security_factor / 100.0f);
365 EVmax *= (1.0f +
p->security_factor / 100.0f);
367 p->shadows_range = EVmin;
368 p->dynamic_range = EVmax - EVmin;
389 gtk_stack_set_visible_child_name(GTK_STACK(
g->mode_stack),
"log");
393 gtk_stack_set_visible_child_name(GTK_STACK(
g->mode_stack),
"gamma");
396 else if(w ==
g->security_factor)
398 float prev = *(
float *)previous;
399 float ratio = (
p->security_factor - prev) / (prev + 100.0f);
401 float EVmin =
p->shadows_range;
402 EVmin = EVmin + ratio * EVmin;
404 float EVmax =
p->dynamic_range +
p->shadows_range;
405 EVmax = EVmax + ratio * EVmax;
407 p->dynamic_range = EVmax - EVmin;
408 p->shadows_range = EVmin;
420 if (picker ==
g->grey_point)
422 else if(picker ==
g->shadows_range)
424 else if(picker ==
g->dynamic_range)
426 else if(picker ==
g->auto_button)
429 fprintf(stderr,
"[profile_gamma] unknown color picker\n");
438 const float linear =
p->linear;
439 const float gamma =
p->gamma;
441 d->linear =
p->linear;
448 for(
int k = 0;
k < 0x10000;
k++)
d->table[
k] = 1.0 *
k / 0x10000;
455 for(
int k = 0;
k < 0x10000;
k++)
d->table[
k] = powf(1.00 *
k / 0x10000, gamma);
462 a = 1.0 / (1.0 +
linear * (
g - 1));
472 for(
int k = 0;
k < 0x10000;
k++)
476 tmp = c *
k / 0x10000;
478 tmp = powf(a *
k / 0x10000 + b,
g);
485 const float x[4] = { 0.7f, 0.8f, 0.9f, 1.0f };
487 = {
d->table[CLAMP((
int)(
x[0] * 0x10000ul), 0, 0xffff)],
488 d->table[CLAMP((
int)(
x[1] * 0x10000ul), 0, 0xffff)],
489 d->table[CLAMP((
int)(
x[2] * 0x10000ul), 0, 0xffff)],
490 d->table[CLAMP((
int)(
x[3] * 0x10000ul), 0, 0xffff)] };
493 d->dynamic_range =
p->dynamic_range;
494 d->grey_point =
p->grey_point;
495 d->shadows_range =
p->shadows_range;
496 d->security_factor =
p->security_factor;
536 g->mode_stack = gtk_stack_new();
537 gtk_stack_set_homogeneous(GTK_STACK(
g->mode_stack),
FALSE);
545 gtk_widget_set_tooltip_text(
g->linear, _(
"linear part"));
549 gtk_widget_set_tooltip_text(
g->gamma, _(
"gamma exponential factor"));
551 gtk_stack_add_named(GTK_STACK(
g->mode_stack), vbox_gamma,
"gamma");
560 gtk_widget_set_tooltip_text(
g->grey_point, _(
"adjust to match the average luma of the subject"));
566 gtk_widget_set_tooltip_text(
g->shadows_range, _(
"number of stops between middle gray and pure black\nthis is a reading a posemeter would give you on the scene"));
572 gtk_widget_set_tooltip_text(
g->dynamic_range, _(
"number of stops between pure black and pure white\nthis is a reading a posemeter would give you on the scene"));
578 gtk_widget_set_tooltip_text(
g->security_factor, _(
"enlarge or shrink the computed dynamic range\nthis is useful when noise perturbates the measurements"));
582 gtk_widget_set_tooltip_text(
g->auto_button, _(
"make an optimization with some guessing"));
583 gtk_box_pack_start(GTK_BOX(vbox_log),
g->auto_button,
TRUE,
TRUE, 0);
585 gtk_stack_add_named(GTK_STACK(
g->mode_stack), vbox_log,
"log");
591 gtk_widget_set_tooltip_text(
g->mode, _(
"tone mapping method"));
593 gtk_box_pack_start(GTK_BOX(self->
widget),
g->mode_stack,
TRUE,
TRUE, 0);
void dt_bauhaus_slider_set_soft_range(GtkWidget *widget, float soft_min, float soft_max)
void dt_bauhaus_slider_set_digits(GtkWidget *widget, int val)
void dt_bauhaus_slider_set_soft_max(GtkWidget *widget, float val)
void dt_bauhaus_slider_set(GtkWidget *widget, float pos)
void dt_bauhaus_widget_set_label(GtkWidget *widget, const char *label)
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)
@ DEVELOP_BLEND_CS_RGB_DISPLAY
static const dt_aligned_pixel_simd_t const dt_adaptation_t const float p
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 dt_colormatrix_t dt_aligned_pixel_t out
#define dt_free_align(ptr)
static void * dt_calloc_align(size_t size)
#define DT_MODULE_INTROSPECTION(MODVER, PARAMSTYPE)
#define __DT_CLONE_TARGETS__
#define __OMP_PARALLEL_FOR__(...)
#define __OMP_FOR_SIMD__(...)
#define dt_dev_add_history_item(dev, module, enable, redraw)
@ DT_DEV_PIXELPIPE_DISPLAY_MASK
static GtkWidget * dt_ui_section_label_new(const gchar *str)
#define DT_GUI_BOX_SPACING
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, const dt_develop_blend_colorspace_t blend_cst)
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)
@ IOP_FLAGS_INCLUDE_IN_STYLES
@ IOP_FLAGS_SUPPORTS_BLENDING
#define IOP_GUI_ALLOC(module)
GtkWidget * dt_bauhaus_slider_from_params(dt_iop_module_t *self, const char *param)
GtkWidget * dt_bauhaus_combobox_from_params(dt_iop_module_t *self, const char *param)
static void dt_iop_estimate_exp(const float *const x, const float *const y, const int num, float *coeff)
static float dt_iop_eval_exp(const float *const coeff, const float x)
float *const restrict const size_t k
float *const restrict const size_t const size_t ch
static float fastlog2(float x)
static float Log2Thres(float x, float Thres)
const char ** description(struct dt_iop_module_t *self)
void gui_reset(dt_iop_module_t *self)
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)
static void apply_autotune(dt_iop_module_t *self)
void gui_init(dt_iop_module_t *self)
void gui_changed(dt_iop_module_t *self, GtkWidget *w, void *previous)
static void apply_auto_dynamic_range(dt_iop_module_t *self)
void commit_params(dt_iop_module_t *self, dt_iop_params_t *p1, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece)
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 init_presets(dt_iop_module_so_t *self)
void init_pipe(dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece)
dt_iop_profilegamma_mode_t
static void apply_auto_black(dt_iop_module_t *self)
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)
struct _GtkWidget GtkWidget
struct dt_gui_gtk_t * gui
struct dt_bauhaus_t * bauhaus
struct dt_develop_t * develop
dt_iop_buffer_dsc_t dsc_in
struct dt_iop_module_t *void * data
GModule *dt_dev_operation_t op
dt_iop_params_t * default_params
dt_iop_gui_data_t * gui_data
dt_aligned_pixel_t picked_color_min
dt_aligned_pixel_t picked_color_max
dt_aligned_pixel_t picked_color
float unbounded_coeffs[3]
dt_iop_profilegamma_mode_t mode
GtkWidget * security_factor
GtkWidget * dynamic_range
GtkWidget * shadows_range
dt_iop_profilegamma_mode_t mode
Region of interest passed through the pixelpipe.