Ansel 0.0
A darktable fork - bloat + design vision
Loading...
Searching...
No Matches
relight.c
Go to the documentation of this file.
1/*
2 This file is part of darktable,
3 Copyright (C) 2010-2011 Bruce Guenter.
4 Copyright (C) 2010-2012 Henrik Andersson.
5 Copyright (C) 2010-2013, 2016 johannes hanika.
6 Copyright (C) 2010 Milan Knížek.
7 Copyright (C) 2010, 2012 Pascal de Bruijn.
8 Copyright (C) 2011 Antony Dovgal.
9 Copyright (C) 2011 Brian Teague.
10 Copyright (C) 2011 Jérémy Rosen.
11 Copyright (C) 2011 Olivier Tribout.
12 Copyright (C) 2011 Robert Bieber.
13 Copyright (C) 2011-2014, 2016, 2018-2019 Tobias Ellinghaus.
14 Copyright (C) 2012 Richard Wonka.
15 Copyright (C) 2012-2014 Ulrich Pegelow.
16 Copyright (C) 2013 Dennis Gnad.
17 Copyright (C) 2013 Simon Spannagel.
18 Copyright (C) 2014-2016, 2019 Roman Lebedev.
19 Copyright (C) 2015 Pedro Côrte-Real.
20 Copyright (C) 2017 Heiko Bauke.
21 Copyright (C) 2018-2020, 2022-2023, 2025-2026 Aurélien PIERRE.
22 Copyright (C) 2018-2019 Edgardo Hoszowski.
23 Copyright (C) 2018 Maurizio Paglia.
24 Copyright (C) 2018-2022 Pascal Obry.
25 Copyright (C) 2018 rawfiner.
26 Copyright (C) 2019 Andreas Schneider.
27 Copyright (C) 2019-2020, 2022 Diederik Ter Rahe.
28 Copyright (C) 2020 Aldric Renaudin.
29 Copyright (C) 2020 Marco.
30 Copyright (C) 2020 Ralf Brown.
31 Copyright (C) 2021 Chris Elston.
32 Copyright (C) 2022 Hanno Schwalm.
33 Copyright (C) 2022 Martin Bařinka.
34 Copyright (C) 2022 Philipp Lutz.
35
36 darktable is free software: you can redistribute it and/or modify
37 it under the terms of the GNU General Public License as published by
38 the Free Software Foundation, either version 3 of the License, or
39 (at your option) any later version.
40
41 darktable is distributed in the hope that it will be useful,
42 but WITHOUT ANY WARRANTY; without even the implied warranty of
43 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
44 GNU General Public License for more details.
45
46 You should have received a copy of the GNU General Public License
47 along with darktable. If not, see <http://www.gnu.org/licenses/>.
48*/
49#ifdef HAVE_CONFIG_H
50#include "config.h"
51#endif
52#include <assert.h>
53#include <stdlib.h>
54#include <string.h>
55
56#include "widgets/bauhaus.h"
57#include "math/math.h"
58#include "develop/develop.h"
59#include "system/openmp.h"
61#include "system/mem_alloc.h"
63#include "database/database.h"
64#include "develop/imageop.h"
65#include "develop/imageop_gui.h"
68
69#include "gui/presets.h"
70#include "iop/iop_api.h"
71
73
75{
76 float ev; // $MIN: -2.0 $MAX: 2.0 $DEFAULT: 0.33 $DESCRIPTION: "exposure"
77 float center; // $DEFAULT: 0.0
78 float width; // $MIN: 2.0 $MAX: 10.0 $DEFAULT: 4.0
80
82{
84
85 dt_gui_presets_add_generic(_("fill-light 0.25EV with 4 zones"), self->op, self->version(),
86 &(dt_iop_relight_params_t){ 0.25, 0.25, 4.0 }, sizeof(dt_iop_relight_params_t), 1);
87
88 dt_gui_presets_add_generic(_("fill-shadow -0.25EV with 4 zones"), self->op, self->version(),
89 &(dt_iop_relight_params_t){ -0.25, 0.25, 4.0 }, sizeof(dt_iop_relight_params_t), 1);
90
92}
93
100
102{
103 float ev; // The ev of relight -4 - +4 EV
104 float center; // the center light value for relight
105 float width; // the width expressed in zones
107
108const char *name()
109{
110 return _("fill light");
111}
112
117
118const char *deprecated_msg()
119{
120 return _("this module is deprecated. please use the tone equalizer module instead.");
121}
122
124{
125 return IOP_GROUP_EFFECTS;
126}
127
129{
130 return IOP_CS_LAB;
131}
132
133#define GAUSS(a, b, c, x) (a * powf(2.718281828f, (-powf((x - b), 2) / (powf(c, 2)))))
134
136int process(struct dt_iop_module_t *self, const dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_iop_t *piece, const void *const ivoid,
137 void *const ovoid)
138{
139 const dt_iop_roi_t *const roi_out = &piece->roi_out;
141 const int ch = piece->dsc_in.channels;
142
143 // Precalculate parameters for gauss function
144 const float a = 1.0; // Height of top
145 const float b = -1.0 + (data->center * 2); // Center of top
146 const float c = (data->width / 10.0) / 2.0; // Width
148 for(int k = 0; k < roi_out->height; k++)
149 {
150 float *in = ((float *)ivoid) + (size_t)ch * k * roi_out->width;
151 float *out = ((float *)ovoid) + (size_t)ch * k * roi_out->width;
152 for(int j = 0; j < roi_out->width; j++, in += ch, out += ch)
153 {
154 const float lightness = in[0] / 100.0;
155 const float x = -1.0 + (lightness * 2.0);
156 float gauss = GAUSS(a, b, c, x);
157
158 if(isnan(gauss) || !isfinite(gauss)) gauss = 0.0;
159
160 float relight = 1.0 / exp2f(-data->ev * CLIP(gauss));
161
162 if(isnan(relight) || !isfinite(relight)) relight = 1.0;
163
164 out[0] = 100.0 * CLIP(lightness * relight);
165 out[1] = in[1];
166 out[2] = in[2];
167 out[3] = in[3];
168 }
169 }
170 return 0;
171}
172
173static void center_callback(GtkDarktableGradientSlider *slider, gpointer user_data)
174{
175 dt_iop_module_t *self = (dt_iop_module_t *)user_data;
176 if(dt_gui_widgets_suppressed()) return;
179 p->center = dtgtk_gradient_slider_get_value(slider);
180 dt_dev_add_history_item(self->dev, self, TRUE, TRUE);
181}
182
185{
188
189 d->ev = p->ev;
190 d->width = p->width;
191 d->center = p->center;
192}
193
195{
197 piece->data_size = sizeof(dt_iop_relight_data_t);
198}
199
201{
202 dt_free_align(piece->data);
203 piece->data = NULL;
204}
205
212
214{
216 float mean, min, max;
217
218 if(self->picked_color_max[0] >= 0.0f)
219 {
220 mean = fmin(fmax(self->picked_color[0] / 100.0f, 0.0f), 1.0f);
221 min = fmin(fmax(self->picked_color_min[0] / 100.0f, 0.0f), 1.0f);
222 max = fmin(fmax(self->picked_color_max[0] / 100.0f, 0.0f), 1.0f);
223 }
224 else
225 {
226 mean = min = max = NAN;
227 }
228
230}
231
232void gui_init(struct dt_iop_module_t *self)
233{
235
236 g->exposure = dt_bauhaus_slider_from_params(self, "ev");
237 dt_bauhaus_slider_set_format(g->exposure, _(" EV"));
238 gtk_widget_set_tooltip_text(g->exposure, _("the fill-light in EV"));
239
240 /* lightnessslider */
241 GtkBox *sliderbox = GTK_BOX(gtk_box_new(GTK_ORIENTATION_HORIZONTAL, DT_GUI_BOX_SPACING));
242#define NEUTRAL_GRAY 0.5
243 static const GdkRGBA _gradient_L[]
244 = { { 0, 0, 0, 1.0 }, { NEUTRAL_GRAY, NEUTRAL_GRAY, NEUTRAL_GRAY, 1.0 } };
245
247 gtk_widget_set_tooltip_text(GTK_WIDGET(g->center), _("select the center of fill-light\nctrl+click to select an area"));
248 g_signal_connect(G_OBJECT(g->center), "value-changed", G_CALLBACK(center_callback), self);
249 gtk_box_pack_start(sliderbox, GTK_WIDGET(g->center), TRUE, TRUE, 0);
250 g->colorpicker = dt_color_picker_new(self, DT_COLOR_PICKER_POINT_AREA, GTK_WIDGET(sliderbox));
251 gtk_widget_set_tooltip_text(GTK_WIDGET(g->colorpicker), _("toggle tool for picking median lightness in image"));
252 gtk_box_pack_start(GTK_BOX(self->gui->widget), GTK_WIDGET(sliderbox), TRUE, FALSE, 0);
253
254 g->width = dt_bauhaus_slider_from_params(self, N_("width"));
255 gtk_widget_set_tooltip_text(g->width, _("width of fill-light area defined in zones"));
256}
257
258// clang-format off
259// modelines: These editor modelines have been set for all relevant files by tools/update_modelines.py
260// vim: shiftwidth=2 expandtab tabstop=2 cindent
261// kate: tab-indents: off; indent-width 2; replace-tabs on; indent-mode cstyle; remove-trailing-spaces modified;
262// clang-format on
#define TRUE
Definition ashift_lsd.c:162
#define FALSE
Definition ashift_lsd.c:158
void dt_bauhaus_slider_set_format(GtkWidget *widget, const char *format)
Definition bauhaus.c:3407
const dt_iop_gui_blendif_colorstop_t _gradient_L[]
Definition blend_gui.c:95
@ IOP_CS_LAB
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_POINT_AREA
static const float x
struct _GtkWidget GtkWidget
GtkWidget, opaque, spelled exactly as GTK spells it.
Definition colorspaces.h:98
static const float const float const float min
const float max
const dt_colormatrix_t dt_aligned_pixel_t out
#define dt_database_start_transaction()
Definition database.h:290
#define dt_database_release_transaction()
Definition database.h:291
#define dt_dev_add_history_item(dev, module, enable, redraw)
void dt_iop_params_t
Definition dev_history.h:43
GtkWidget * dtgtk_gradient_slider_new_with_color_and_name(GdkRGBA start, GdkRGBA end, gchar *name)
void dtgtk_gradient_slider_set_value(GtkDarktableGradientSlider *gslider, gdouble value)
gdouble dtgtk_gradient_slider_get_value(GtkDarktableGradientSlider *gslider)
void dtgtk_gradient_slider_set_picker_meanminmax(GtkDarktableGradientSlider *gslider, gdouble mean, gdouble min, gdouble max)
#define DTGTK_GRADIENT_SLIDER(obj)
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
Definition imageop.h:185
@ IOP_FLAGS_DEPRECATED
Definition imageop.h:187
@ IOP_FLAGS_SUPPORTS_BLENDING
Definition imageop.h:186
@ IOP_FLAGS_ALLOW_TILING
Definition imageop.h:188
@ IOP_GROUP_EFFECTS
Definition imageop.h:161
GtkWidget * dt_bauhaus_slider_from_params(dt_iop_module_t *self, const char *param)
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...
Definition imageop_gui.h:81
#define IOP_GUI_ALLOC(module)
Definition imageop_gui.h:93
void *const ovoid
float *const restrict const size_t k
float *const restrict const size_t const size_t ch
#define CLIP(x)
Definition math.h:83
#define dt_free_align(ptr)
Release memory from dt_alloc_align() and set ptr to NULL.
Definition mem_alloc.h:214
static void * dt_calloc_align(size_t size)
dt_alloc_align() followed by a zero fill.
Definition mem_alloc.h:225
#define DT_MODULE_INTROSPECTION(MODVER, PARAMSTYPE)
DT_MODULE() for a module whose params struct is introspected.
#define __OMP_PARALLEL_FOR__(...)
Definition openmp.h:95
static void center_callback(GtkDarktableGradientSlider *slider, gpointer user_data)
Definition relight.c:173
void commit_params(struct dt_iop_module_t *self, dt_iop_params_t *p1, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece)
Definition relight.c:183
int default_group()
Definition relight.c:123
__DT_CLONE_TARGETS__ int process(struct 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)
Definition relight.c:136
void init_pipe(struct dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece)
Definition relight.c:194
const char * name()
Definition relight.c:108
void gui_update(struct dt_iop_module_t *self)
Refresh GUI controls from current params and configuration.
Definition relight.c:206
void gui_init(struct dt_iop_module_t *self)
Definition relight.c:232
int default_colorspace(dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_iop_t *piece)
Definition relight.c:128
int flags()
Definition relight.c:113
void init_presets(dt_iop_module_so_t *self)
Definition relight.c:81
#define GAUSS(a, b, c, x)
Definition relight.c:133
void cleanup_pipe(struct dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece)
Definition relight.c:200
const char * deprecated_msg()
Definition relight.c:118
void color_picker_apply(dt_iop_module_t *self, GtkWidget *picker, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece)
Definition relight.c:213
#define NEUTRAL_GRAY
dt_iop_buffer_dsc_t dsc_in
struct dt_iop_module_t *void * data
unsigned int channels
Definition format.h:83
GtkWidget * widget
Definition imageop_gui.h:47
dt_dev_operation_t op
Definition imageop.h:235
struct dt_iop_module_gui_t * gui
Definition imageop.h:346
struct dt_develop_t * dev
Definition imageop.h:311
dt_aligned_pixel_t picked_color_min
Definition imageop.h:287
dt_aligned_pixel_t picked_color_max
Definition imageop.h:287
dt_aligned_pixel_t picked_color
Definition imageop.h:287
dt_iop_params_t * params
Definition imageop.h:333
GtkWidget * colorpicker
Definition relight.c:98
GtkDarktableGradientSlider * center
Definition relight.c:97
Region of interest passed through the pixelpipe.
Definition format.h:49
int width
Definition format.h:50
int height
Definition format.h:50
#define __DT_CLONE_TARGETS__
gboolean dt_gui_widgets_suppressed(void)
#define DT_GUI_BOX_SPACING