Ansel 0.0
A darktable fork - bloat + design vision
Loading...
Searching...
No Matches
profile_gamma.c
Go to the documentation of this file.
1/*
2 This file is part of darktable,
3 Copyright (C) 2009-2013, 2016 johannes hanika.
4 Copyright (C) 2010 Alexandre Prokoudine.
5 Copyright (C) 2010 Bruce Guenter.
6 Copyright (C) 2010-2011 Henrik Andersson.
7 Copyright (C) 2010 José Carlos García Sogo.
8 Copyright (C) 2010 Pascal de Bruijn.
9 Copyright (C) 2011 Jérémy Rosen.
10 Copyright (C) 2011 Olivier Tribout.
11 Copyright (C) 2011 Robert Bieber.
12 Copyright (C) 2011-2014, 2016, 2019 Tobias Ellinghaus.
13 Copyright (C) 2012 Richard Wonka.
14 Copyright (C) 2013, 2020 Aldric Renaudin.
15 Copyright (C) 2014-2016 Roman Lebedev.
16 Copyright (C) 2014, 2016-2017 Ulrich Pegelow.
17 Copyright (C) 2015 Pedro Côrte-Real.
18 Copyright (C) 2017 Heiko Bauke.
19 Copyright (C) 2018-2020, 2023, 2025-2026 Aurélien PIERRE.
20 Copyright (C) 2018-2019 Edgardo Hoszowski.
21 Copyright (C) 2018 Matthieu Moy.
22 Copyright (C) 2018 Maurizio Paglia.
23 Copyright (C) 2018-2022 Pascal Obry.
24 Copyright (C) 2018 rawfiner.
25 Copyright (C) 2019 Andreas Schneider.
26 Copyright (C) 2019-2020, 2022 Diederik Ter Rahe.
27 Copyright (C) 2019 Diederik ter Rahe.
28 Copyright (C) 2020-2021 Chris Elston.
29 Copyright (C) 2020 Ralf Brown.
30 Copyright (C) 2021 Dan Torop.
31 Copyright (C) 2022 Hanno Schwalm.
32 Copyright (C) 2022 Martin Bařinka.
33 Copyright (C) 2022 Philipp Lutz.
34
35 darktable is free software: you can redistribute it and/or modify
36 it under the terms of the GNU General Public License as published by
37 the Free Software Foundation, either version 3 of the License, or
38 (at your option) any later version.
39
40 darktable is distributed in the hope that it will be useful,
41 but WITHOUT ANY WARRANTY; without even the implied warranty of
42 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
43 GNU General Public License for more details.
44
45 You should have received a copy of the GNU General Public License
46 along with darktable. If not, see <http://www.gnu.org/licenses/>.
47*/
48#ifdef HAVE_CONFIG_H
49#include "config.h"
50#endif
51#include "bauhaus/bauhaus.h"
53#include "common/darktable.h"
54#include "common/math.h"
55#include "common/opencl.h"
56#include "control/control.h"
57#include "develop/develop.h"
59#include "develop/imageop_gui.h"
60#include "dtgtk/button.h"
61
62#include "gui/gtk.h"
63#include "gui/presets.h"
65#include "iop/iop_api.h"
66#include <assert.h>
67#include <math.h>
68#include <stdlib.h>
69#include <string.h>
70
72
74{
75 PROFILEGAMMA_LOG = 0, // $DESCRIPTION: "logarithmic"
76 PROFILEGAMMA_GAMMA = 1 // $DESCRIPTION: "gamma"
78
80{
81 dt_iop_profilegamma_mode_t mode; // $DEFAULT: PROFILEGAMMA_LOG
82 float linear; // $MIN: 0.0 $MAX: 1.0 $DEFAULT: 0.1
83 float gamma; // $MIN: 0.0 $MAX: 1.0 $DEFAULT: 0.45
84 float dynamic_range; // $MIN: 0.01 $MAX: 32.0 $DEFAULT: 10.0 $DESCRIPTION: "dynamic range"
85 float grey_point; // $MIN: 0.1 $MAX: 100.0 $DEFAULT: 18.0 $DESCRIPTION: "middle gray luma"
86 float shadows_range; // $MIN: -16.0 $MAX: 16.0 $DEFAULT: -5.0 $DESCRIPTION: "black relative exposure"
87 float security_factor; // $MIN: -100.0 $MAX: 100.0 $DEFAULT: 0.0 $DESCRIPTION: "safety factor"
89
102
104{
106 float linear;
107 float gamma;
108 float table[0x10000]; // precomputed look-up table
109 float unbounded_coeffs[3]; // approximation for extrapolation of curve
115
116const char *name()
117{
118 return _("unbreak input profile");
119}
120
121const char **description(struct dt_iop_module_t *self)
122{
123 return dt_iop_set_description(self, _("correct input color profiles meant to be applied on non-linear RGB"),
124 _("corrective"),
125 _("linear, RGB, display-referred"),
126 _("non-linear, RGB"),
127 _("non-linear, RGB, display-referred"));
128}
129
131{
132 return IOP_GROUP_TECHNICAL;
133}
134
140
142{
143 return IOP_CS_RGB;
144}
145
147{
149 memset(&p, 0, sizeof(p));
150
151 p.mode = PROFILEGAMMA_LOG;
152 p.grey_point = 18.00f;
153 p.security_factor = 0.0f;
154
155 // 16 EV preset
156 p.dynamic_range = 16.0f;
157 p.shadows_range = -12.0f;
158 dt_gui_presets_add_generic(_("16 EV dynamic range (generic)"), self->op,
159 self->version(), &p, sizeof(p), 1, DEVELOP_BLEND_CS_RGB_DISPLAY);
160
161 // 14 EV preset
162 p.dynamic_range = 14.0f;
163 p.shadows_range = -10.50f;
164 dt_gui_presets_add_generic(_("14 EV dynamic range (generic)"), self->op,
165 self->version(), &p, sizeof(p), 1, DEVELOP_BLEND_CS_RGB_DISPLAY);
166
167 // 12 EV preset
168 p.dynamic_range = 12.0f;
169 p.shadows_range = -9.0f;
170 dt_gui_presets_add_generic(_("12 EV dynamic range (generic)"), self->op,
171 self->version(), &p, sizeof(p), 1, DEVELOP_BLEND_CS_RGB_DISPLAY);
172
173 // 10 EV preset
174 p.dynamic_range = 10.0f;
175 p.shadows_range = -7.50f;
176 dt_gui_presets_add_generic(_("10 EV dynamic range (generic)"), self->op,
177 self->version(), &p, sizeof(p), 1, DEVELOP_BLEND_CS_RGB_DISPLAY);
178
179 // 08 EV preset
180 p.dynamic_range = 8.0f;
181 p.shadows_range = -6.0f;
182 dt_gui_presets_add_generic(_("08 EV dynamic range (generic)"), self->op,
183 self->version(), &p, sizeof(p), 1, DEVELOP_BLEND_CS_RGB_DISPLAY);
184}
185
186
187int legacy_params(dt_iop_module_t *self, const void *const old_params, const int old_version, void *new_params,
188 const int new_version)
189{
190 if(old_version == 1 && new_version == 2)
191 {
192 typedef struct dt_iop_profilegamma_params_v1_t
193 {
194 float linear;
195 float gamma;
196 } dt_iop_profilegamma_params_v1_t;
197
198 dt_iop_profilegamma_params_v1_t *o = (dt_iop_profilegamma_params_v1_t *)old_params;
201
202 *n = *d; // start with a fresh copy of default parameters
203
204 n->linear = o->linear;
205 n->gamma = o->gamma;
206 n->mode = PROFILEGAMMA_GAMMA;
207 return 0;
208 }
209 return 1;
210}
211
214 const void *const ivoid, void *const ovoid)
215{
216 const dt_iop_roi_t *const roi_out = &piece->roi_out;
218
219 const int ch = piece->dsc_in.channels;
220
221 switch(data->mode)
222 {
223 case PROFILEGAMMA_LOG:
224 {
225 const float grey = data->grey_point / 100.0f;
226
234 const float noise = powf(2.0f, -16.0f);
236 for(size_t k = 0; k < (size_t)ch * roi_out->width * roi_out->height; k++)
237 {
238 float tmp = ((const float *)ivoid)[k] / grey;
239 if (tmp < noise) tmp = noise;
240 tmp = (fastlog2(tmp) - data->shadows_range) / (data->dynamic_range);
241
242 if (tmp < noise)
243 {
244 ((float *)ovoid)[k] = noise;
245 }
246 else
247 {
248 ((float *)ovoid)[k] = tmp;
249 }
250 }
251 break;
252 }
253
255 {
257 for(int k = 0; k < roi_out->height; k++)
258 {
259 const float *in = ((float *)ivoid) + (size_t)ch * k * roi_out->width;
260 float *out = ((float *)ovoid) + (size_t)ch * k * roi_out->width;
261
262 for(int j = 0; j < roi_out->width; j++, in += ch, out += ch)
263 {
264 for(int i = 0; i < 3; i++)
265 {
266 // use base curve for values < 1, else use extrapolation.
267 if(in[i] < 1.0f)
268 out[i] = data->table[CLAMP((int)(in[i] * 0x10000ul), 0, 0xffff)];
269 else
270 out[i] = dt_iop_eval_exp(data->unbounded_coeffs, in[i]);
271 }
272 }
273 }
274 break;
275 }
276 }
277
279 dt_iop_alpha_copy(ivoid, ovoid, roi_out->width, roi_out->height);
280 return 0;
281}
282
284{
285 if(dt_gui_widgets_suppressed()) return;
288
289 float grey = fmax(fmax(self->picked_color[0], self->picked_color[1]), self->picked_color[2]);
290 p->grey_point = 100.f * grey;
291
293 dt_bauhaus_slider_set(g->grey_point, p->grey_point);
295
297}
298
300{
301 if(dt_gui_widgets_suppressed()) return;
304
305 float noise = powf(2.0f, -16.0f);
306
307 // Black
308 float black = fmax(fmax(self->picked_color_min[0], self->picked_color_min[1]), self->picked_color_min[2]);
309 float EVmin = Log2Thres(black / (p->grey_point / 100.0f), noise);
310 EVmin *= (1.0f + p->security_factor / 100.0f);
311
312 p->shadows_range = EVmin;
313
315 dt_bauhaus_slider_set(g->shadows_range, p->shadows_range);
317
319}
320
322{
323 if(dt_gui_widgets_suppressed()) return;
326
327 float noise = powf(2.0f, -16.0f);
328
329 // Black
330 float EVmin = p->shadows_range;
331
332 // White
333 float white = fmax(fmax(self->picked_color_max[0], self->picked_color_max[1]), self->picked_color_max[2]);
334 float EVmax = Log2Thres(white / (p->grey_point / 100.0f), noise);
335 EVmax *= (1.0f + p->security_factor / 100.0f);
336
337 p->dynamic_range = EVmax - EVmin;
338
340 dt_bauhaus_slider_set(g->dynamic_range, p->dynamic_range);
342
344}
345
347{
350
351 float noise = powf(2.0f, -16.0f);
352
353 // Grey
354 float grey = fmax(fmax(self->picked_color[0], self->picked_color[1]), self->picked_color[2]);
355 p->grey_point = 100.f * grey;
356
357 // Black
358 float black = fmax(fmax(self->picked_color_min[0], self->picked_color_min[1]), self->picked_color_min[2]);
359 float EVmin = Log2Thres(black / (p->grey_point / 100.0f), noise);
360 EVmin *= (1.0f + p->security_factor / 100.0f);
361
362 // White
363 float white = fmax(fmax(self->picked_color_max[0], self->picked_color_max[1]), self->picked_color_max[2]);
364 float EVmax = Log2Thres(white / (p->grey_point / 100.0f), noise);
365 EVmax *= (1.0f + p->security_factor / 100.0f);
366
367 p->shadows_range = EVmin;
368 p->dynamic_range = EVmax - EVmin;
369
371 dt_bauhaus_slider_set(g->grey_point, p->grey_point);
372 dt_bauhaus_slider_set(g->shadows_range, p->shadows_range);
373 dt_bauhaus_slider_set(g->dynamic_range, p->dynamic_range);
375
377}
378
379
380void gui_changed(dt_iop_module_t *self, GtkWidget *w, void *previous)
381{
384
385 if(w == g->mode)
386 {
387 /* grey_point/shadows_range/dynamic_range/auto_button live on the "log" stack
388 page. Switching mode can hide that page while a picker stays active,
389 sampling/drawing on the image for a control the user can no longer see or
390 turn off from this widget. */
392
393 if(p->mode == PROFILEGAMMA_LOG)
394 {
395 gtk_stack_set_visible_child_name(GTK_STACK(g->mode_stack), "log");
396 }
397 else
398 {
399 gtk_stack_set_visible_child_name(GTK_STACK(g->mode_stack), "gamma");
400 }
401 }
402 else if(w == g->security_factor)
403 {
404 float prev = *(float *)previous;
405 float ratio = (p->security_factor - prev) / (prev + 100.0f);
406
407 float EVmin = p->shadows_range;
408 EVmin = EVmin + ratio * EVmin;
409
410 float EVmax = p->dynamic_range + p->shadows_range;
411 EVmax = EVmax + ratio * EVmax;
412
413 p->dynamic_range = EVmax - EVmin;
414 p->shadows_range = EVmin;
415
417 dt_bauhaus_slider_set(g->dynamic_range, p->dynamic_range);
418 dt_bauhaus_slider_set(g->shadows_range, p->shadows_range);
420 }
421}
422
424{
426 if (picker == g->grey_point)
427 apply_auto_grey(self);
428 else if(picker == g->shadows_range)
429 apply_auto_black(self);
430 else if(picker == g->dynamic_range)
432 else if(picker == g->auto_button)
433 apply_autotune(self);
434 else
435 fprintf(stderr, "[profile_gamma] unknown color picker\n");
436}
437
440{
443
444 const float linear = p->linear;
445 const float gamma = p->gamma;
446
447 d->linear = p->linear;
448 d->gamma = p->gamma;
449
450 float a, b, c, g;
451 if(gamma == 1.0)
452 {
454 for(int k = 0; k < 0x10000; k++) d->table[k] = 1.0 * k / 0x10000;
455 }
456 else
457 {
458 if(linear == 0.0)
459 {
461 for(int k = 0; k < 0x10000; k++) d->table[k] = powf(1.00 * k / 0x10000, gamma);
462 }
463 else
464 {
465 if(linear < 1.0)
466 {
467 g = gamma * (1.0 - linear) / (1.0 - gamma * linear);
468 a = 1.0 / (1.0 + linear * (g - 1));
469 b = linear * (g - 1) * a;
470 c = powf(a * linear + b, g) / linear;
471 }
472 else
473 {
474 a = b = g = 0.0;
475 c = 1.0;
476 }
478 for(int k = 0; k < 0x10000; k++)
479 {
480 float tmp;
481 if(k < 0x10000 * linear)
482 tmp = c * k / 0x10000;
483 else
484 tmp = powf(a * k / 0x10000 + b, g);
485 d->table[k] = tmp;
486 }
487 }
488 }
489
490 // now the extrapolation stuff:
491 const float x[4] = { 0.7f, 0.8f, 0.9f, 1.0f };
492 const float y[4]
493 = { d->table[CLAMP((int)(x[0] * 0x10000ul), 0, 0xffff)],
494 d->table[CLAMP((int)(x[1] * 0x10000ul), 0, 0xffff)],
495 d->table[CLAMP((int)(x[2] * 0x10000ul), 0, 0xffff)],
496 d->table[CLAMP((int)(x[3] * 0x10000ul), 0, 0xffff)] };
497 dt_iop_estimate_exp(x, y, 4, d->unbounded_coeffs);
498
499 d->dynamic_range = p->dynamic_range;
500 d->grey_point = p->grey_point;
501 d->shadows_range = p->shadows_range;
502 d->security_factor = p->security_factor;
503 d->mode = p->mode;
504
505 //piece->process_cl_ready = 1;
506
507 // no OpenCL for log yet.
508 //if(d->mode == PROFILEGAMMA_LOG) piece->process_cl_ready = 0;
509}
510
516
518{
519 dt_free_align(piece->data);
520 piece->data = NULL;
521}
522
524{
526}
527
536
538{
540
541 // prepare the modes widgets stack
542 g->mode_stack = gtk_stack_new();
543 gtk_stack_set_homogeneous(GTK_STACK(g->mode_stack), FALSE);
544
545 /**** GAMMA MODE ***/
546
547 GtkWidget *vbox_gamma = self->widget = GTK_WIDGET(gtk_box_new(GTK_ORIENTATION_VERTICAL, DT_GUI_BOX_SPACING));
548
549 g->linear = dt_bauhaus_slider_from_params(self, N_("linear"));
551 gtk_widget_set_tooltip_text(g->linear, _("linear part"));
552
553 g->gamma = dt_bauhaus_slider_from_params(self, N_("gamma"));
555 gtk_widget_set_tooltip_text(g->gamma, _("gamma exponential factor"));
556
557 gtk_stack_add_named(GTK_STACK(g->mode_stack), vbox_gamma, "gamma");
558
559 /**** LOG MODE ****/
560
561 GtkWidget *vbox_log = self->widget = GTK_WIDGET(gtk_box_new(GTK_ORIENTATION_VERTICAL, DT_GUI_BOX_SPACING));
562
563 g->grey_point
565 dt_bauhaus_slider_set_format(g->grey_point, "%");
566 gtk_widget_set_tooltip_text(g->grey_point, _("adjust to match the average luma of the subject"));
567
568 g->shadows_range
570 dt_bauhaus_slider_set_soft_max(g->shadows_range, 0.0);
571 dt_bauhaus_slider_set_format(g->shadows_range, _(" EV"));
572 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"));
573
574 g->dynamic_range
576 dt_bauhaus_slider_set_soft_range(g->dynamic_range, 0.5, 16.0);
577 dt_bauhaus_slider_set_format(g->dynamic_range, _(" EV"));
578 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"));
579
580 gtk_box_pack_start(GTK_BOX(vbox_log), dt_ui_section_label_new(_("optimize automatically")), FALSE, FALSE, 0);
581
582 g->security_factor = dt_bauhaus_slider_from_params(self, "security_factor");
583 dt_bauhaus_slider_set_format(g->security_factor, "%");
584 gtk_widget_set_tooltip_text(g->security_factor, _("enlarge or shrink the computed dynamic range\nthis is useful when noise perturbates the measurements"));
585
587 dt_bauhaus_widget_set_label(g->auto_button, N_("auto tune levels"));
588 gtk_widget_set_tooltip_text(g->auto_button, _("make an optimization with some guessing"));
589 gtk_box_pack_start(GTK_BOX(vbox_log), g->auto_button, TRUE, TRUE, 0);
590
591 gtk_stack_add_named(GTK_STACK(g->mode_stack), vbox_log, "log");
592
593 // start building top level widget
594 self->widget = gtk_box_new(GTK_ORIENTATION_VERTICAL, DT_GUI_BOX_SPACING);
595
596 g->mode = dt_bauhaus_combobox_from_params(self, N_("mode"));
597 gtk_widget_set_tooltip_text(g->mode, _("tone mapping method"));
598
599 gtk_box_pack_start(GTK_BOX(self->widget), g->mode_stack, TRUE, TRUE, 0);
600}
601
602
603// clang-format off
604// modelines: These editor modelines have been set for all relevant files by tools/update_modelines.py
605// vim: shiftwidth=2 expandtab tabstop=2 cindent
606// kate: tab-indents: off; indent-width 2; replace-tabs on; indent-mode cstyle; remove-trailing-spaces modified;
607// clang-format on
#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:1650
void dt_bauhaus_slider_set_digits(GtkWidget *widget, int val)
Definition bauhaus.c:3549
void dt_bauhaus_slider_set_soft_max(GtkWidget *widget, float val)
Definition bauhaus.c:1626
void dt_bauhaus_slider_set(GtkWidget *widget, float pos)
Definition bauhaus.c:3537
void dt_bauhaus_widget_set_label(GtkWidget *widget, const char *label)
Definition bauhaus.c:1656
GtkWidget * dt_bauhaus_combobox_new(dt_bauhaus_t *bh, dt_gui_module_t *self)
Definition bauhaus.c:1845
void dt_bauhaus_slider_set_format(GtkWidget *widget, const char *format)
Definition bauhaus.c:3613
@ DEVELOP_BLEND_CS_RGB_DISPLAY
Definition blend.h:59
static const dt_aligned_pixel_simd_t const dt_adaptation_t const float p
@ IOP_CS_RGB
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)
@ DT_COLOR_PICKER_AREA
const dt_colormatrix_t dt_aligned_pixel_t out
darktable_t darktable
Definition darktable.c:183
#define dt_free_align(ptr)
Definition darktable.h:503
static void * dt_calloc_align(size_t size)
Definition darktable.h:510
#define dt_gui_freeze_begin()
Definition darktable.h:900
#define dt_gui_freeze_end()
Definition darktable.h:901
void void void gboolean dt_gui_widgets_suppressed(void)
Definition gtk.c:194
#define DT_MODULE_INTROSPECTION(MODVER, PARAMSTYPE)
Definition darktable.h:151
#define __DT_CLONE_TARGETS__
Definition darktable.h:379
#define __OMP_PARALLEL_FOR__(...)
Definition darktable.h:270
#define __OMP_FOR_SIMD__(...)
Definition darktable.h:272
#define dt_dev_add_history_item(dev, module, enable, redraw)
void dt_iop_params_t
Definition dev_history.h:42
@ DT_DEV_PIXELPIPE_DISPLAY_MASK
Definition develop.h:118
static GtkWidget * dt_ui_section_label_new(const gchar *str)
Definition gtk.h:469
#define DT_GUI_BOX_SPACING
Definition gtk.h:109
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)
#define DT_GUI_MODULE(x)
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:3220
@ IOP_FLAGS_INCLUDE_IN_STYLES
Definition imageop.h:196
@ IOP_FLAGS_SUPPORTS_BLENDING
Definition imageop.h:197
@ IOP_FLAGS_ALLOW_TILING
Definition imageop.h:199
@ IOP_FLAGS_ONE_INSTANCE
Definition imageop.h:202
@ IOP_GROUP_TECHNICAL
Definition imageop.h:173
#define IOP_GUI_ALLOC(module)
Definition imageop.h:638
GtkWidget * dt_bauhaus_slider_from_params(dt_iop_module_t *self, const char *param)
Definition imageop_gui.c:77
GtkWidget * dt_bauhaus_combobox_from_params(dt_iop_module_t *self, const char *param)
void *const ovoid
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)
static const float x
@ linear
Definition lightroom.c:368
float *const restrict const size_t k
float *const restrict const size_t const size_t ch
static float fastlog2(float x)
Definition math.h:122
static float Log2Thres(float x, float Thres)
Definition math.h:116
const char ** description(struct dt_iop_module_t *self)
int default_group()
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)
const char * name()
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)
int flags()
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
@ PROFILEGAMMA_LOG
@ PROFILEGAMMA_GAMMA
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
Definition splash.h:29
const float noise
struct dt_bauhaus_t * bauhaus
Definition darktable.h:806
struct dt_develop_t * develop
Definition darktable.h:798
dt_iop_buffer_dsc_t dsc_in
struct dt_iop_module_t *void * data
unsigned int channels
Definition format.h:54
GModule *dt_dev_operation_t op
Definition imageop.h:260
dt_iop_params_t * default_params
Definition imageop.h:344
GtkWidget * widget
Definition imageop.h:374
dt_iop_gui_data_t * gui_data
Definition imageop.h:348
dt_aligned_pixel_t picked_color_min
Definition imageop.h:309
dt_aligned_pixel_t picked_color_max
Definition imageop.h:309
dt_aligned_pixel_t picked_color
Definition imageop.h:309
dt_iop_params_t * params
Definition imageop.h:344
dt_iop_profilegamma_mode_t mode
dt_iop_profilegamma_mode_t mode
Region of interest passed through the pixelpipe.
Definition imageop.h:72