Ansel 0.0
A darktable fork - bloat + design vision
Loading...
Searching...
No Matches
colisa.c
Go to the documentation of this file.
1/*
2 This file is part of darktable,
3 Copyright (C) 2013-2016 Roman Lebedev.
4 Copyright (C) 2013-2014, 2016, 2019 Tobias Ellinghaus.
5 Copyright (C) 2013-2014, 2016 Ulrich Pegelow.
6 Copyright (C) 2015 Pedro Côrte-Real.
7 Copyright (C) 2016 johannes hanika.
8 Copyright (C) 2017 Heiko Bauke.
9 Copyright (C) 2018, 2020, 2022-2023, 2025-2026 Aurélien PIERRE.
10 Copyright (C) 2018 Edgardo Hoszowski.
11 Copyright (C) 2018 Maurizio Paglia.
12 Copyright (C) 2018, 2020, 2022 Pascal Obry.
13 Copyright (C) 2018 rawfiner.
14 Copyright (C) 2019 Andreas Schneider.
15 Copyright (C) 2020 Aldric Renaudin.
16 Copyright (C) 2020, 2022 Diederik Ter Rahe.
17 Copyright (C) 2020 Ralf Brown.
18 Copyright (C) 2022 Hanno Schwalm.
19 Copyright (C) 2022 Martin Bařinka.
20 Copyright (C) 2022 Philipp Lutz.
21
22 darktable is free software: you can redistribute it and/or modify
23 it under the terms of the GNU General Public License as published by
24 the Free Software Foundation, either version 3 of the License, or
25 (at your option) any later version.
26
27 darktable is distributed in the hope that it will be useful,
28 but WITHOUT ANY WARRANTY; without even the implied warranty of
29 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30 GNU General Public License for more details.
31
32 You should have received a copy of the GNU General Public License
33 along with darktable. If not, see <http://www.gnu.org/licenses/>.
34*/
35
36#ifdef HAVE_CONFIG_H
37#include "config.h"
38#endif
39#include "bauhaus/bauhaus.h"
40#include "common/debug.h"
41#include "common/opencl.h"
42#include "control/control.h"
43#include "develop/develop.h"
44#include "develop/imageop.h"
46#include "develop/imageop_gui.h"
47#include "develop/tiling.h"
48
49#include "gui/gtk.h"
50#include "gui/presets.h"
51#include "iop/iop_api.h"
52
53#include <assert.h>
54#include <math.h>
55#include <stdlib.h>
56#include <string.h>
57
58#include <gtk/gtk.h>
59#include <inttypes.h>
60
62
64{
65 float contrast; // $MIN: -1.0 $MAX: 1.0 $DEFAULT: 0.0
66 float brightness; // $MIN: -1.0 $MAX: 1.0 $DEFAULT: 0.0
67 float saturation; // $MIN: -1.0 $MAX: 1.0 $DEFAULT: 0.0
69
76
78{
79 float contrast;
82 float ctable[0x10000]; // precomputed look-up table for contrast curve
83 float cunbounded_coeffs[3]; // approximation for extrapolation of contrast curve
84 float ltable[0x10000]; // precomputed look-up table for brightness curve
85 float lunbounded_coeffs[3]; // approximation for extrapolation of brightness curve
87
88const char *name()
89{
90 return _("contrast brightness saturation");
91}
92
93const char **description(struct dt_iop_module_t *self)
94{
95 return dt_iop_set_description(self, _("adjust the look of the image"),
96 _("creative"),
97 _("non-linear, Lab, display-referred"),
98 _("non-linear, Lab"),
99 _("non-linear, Lab, display-referred"));
100}
101
106
108{
109 return IOP_GROUP_EFFECTS;
110}
111
113{
114 return IOP_CS_LAB;
115}
116
119{
120 default_input_format(self, pipe, piece, dsc);
121 dsc->channels = 4;
122 dsc->datatype = TYPE_FLOAT;
123}
124
126int process(struct dt_iop_module_t *self, const dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_iop_t *piece, const void *const ivoid,
127 void *const ovoid)
128{
129 (void)self;
130 (void)pipe;
131 const dt_iop_roi_t *const roi_in = &piece->roi_in;
133 float *in = (float *)ivoid;
134 float *out = (float *)ovoid;
135
136 const int width = roi_in->width;
137 const int height = roi_in->height;
138 const int ch = 4;
140 for(size_t k = 0; k < (size_t)width * height; k++)
141 {
142 float L = (in[k * ch + 0] < 100.0f)
143 ? data->ctable[CLAMP((int)(in[k * ch + 0] / 100.0f * 0x10000ul), 0, 0xffff)]
144 : dt_iop_eval_exp(data->cunbounded_coeffs, in[k * ch + 0] / 100.0f);
145 out[k * ch + 0] = (L < 100.0f) ? data->ltable[CLAMP((int)(L / 100.0f * 0x10000ul), 0, 0xffff)]
146 : dt_iop_eval_exp(data->lunbounded_coeffs, L / 100.0f);
147 out[k * ch + 1] = in[k * ch + 1] * data->saturation;
148 out[k * ch + 2] = in[k * ch + 2] * data->saturation;
149 out[k * ch + 3] = in[k * ch + 3];
150 }
151 return 0;
152}
153
154
157{
160
161 d->contrast = p->contrast + 1.0f; // rescale from [-1;+1] to [0;+2] (zero meaning no contrast -> gray plane)
162 d->brightness = p->brightness * 2.0f; // rescale from [-1;+1] to [-2;+2]
163 d->saturation = p->saturation + 1.0f; // rescale from [-1;+1] to [0;+2] (zero meaning no saturation -> b&w)
164
165 // generate precomputed contrast curve
166 if(d->contrast <= 1.0f)
167 {
168// linear curve for d->contrast below 1
170 for(int k = 0; k < 0x10000; k++) d->ctable[k] = d->contrast * (100.0f * k / 0x10000 - 50.0f) + 50.0f;
171 }
172 else
173 {
174 // sigmoidal curve for d->contrast above 1
175 const float boost = 20.0f;
176 const float contrastm1sq = boost * (d->contrast - 1.0f) * (d->contrast - 1.0f);
177 const float contrastscale = sqrtf(1.0f + contrastm1sq);
179 for(int k = 0; k < 0x10000; k++)
180 {
181 float kx2m1 = 2.0f * (float)k / 0x10000 - 1.0f;
182 d->ctable[k] = 50.0f * (contrastscale * kx2m1 / sqrtf(1.0f + contrastm1sq * kx2m1 * kx2m1) + 1.0f);
183 }
184 }
185
186 // now the extrapolation stuff for the contrast curve:
187 const float xc[4] = { 0.7f, 0.8f, 0.9f, 1.0f };
188 const float yc[4] = { d->ctable[CLAMP((int)(xc[0] * 0x10000ul), 0, 0xffff)],
189 d->ctable[CLAMP((int)(xc[1] * 0x10000ul), 0, 0xffff)],
190 d->ctable[CLAMP((int)(xc[2] * 0x10000ul), 0, 0xffff)],
191 d->ctable[CLAMP((int)(xc[3] * 0x10000ul), 0, 0xffff)] };
192 dt_iop_estimate_exp(xc, yc, 4, d->cunbounded_coeffs);
193
194
195 // generate precomputed brightness curve
196 const float gamma = (d->brightness >= 0.0f) ? 1.0f / (1.0f + d->brightness) : (1.0f - d->brightness);
198 for(int k = 0; k < 0x10000; k++)
199 {
200 d->ltable[k] = 100.0f * powf((float)k / 0x10000, gamma);
201 }
202
203 // now the extrapolation stuff for the brightness curve:
204 const float xl[4] = { 0.7f, 0.8f, 0.9f, 1.0f };
205 const float yl[4] = { d->ltable[CLAMP((int)(xl[0] * 0x10000ul), 0, 0xffff)],
206 d->ltable[CLAMP((int)(xl[1] * 0x10000ul), 0, 0xffff)],
207 d->ltable[CLAMP((int)(xl[2] * 0x10000ul), 0, 0xffff)],
208 d->ltable[CLAMP((int)(xl[3] * 0x10000ul), 0, 0xffff)] };
209 dt_iop_estimate_exp(xl, yl, 4, d->lunbounded_coeffs);
210}
211
213{
215 piece->data = (void *)d;
216 piece->data_size = sizeof(dt_iop_colisa_data_t);
217 for(int k = 0; k < 0x10000; k++) d->ctable[k] = d->ltable[k] = 100.0f * k / 0x10000; // identity
218}
219
221{
222 dt_free_align(piece->data);
223 piece->data = NULL;
224}
225
226void gui_init(struct dt_iop_module_t *self)
227{
229
230 g->contrast = dt_bauhaus_slider_from_params(self, N_("contrast"));
231 g->brightness = dt_bauhaus_slider_from_params(self, N_("brightness"));
232 g->saturation = dt_bauhaus_slider_from_params(self, N_("saturation"));
233
234 gtk_widget_set_tooltip_text(g->contrast, _("contrast adjustment"));
235 gtk_widget_set_tooltip_text(g->brightness, _("brightness adjustment"));
236 gtk_widget_set_tooltip_text(g->saturation, _("color saturation adjustment"));
237}
238
239// clang-format off
240// modelines: These editor modelines have been set for all relevant files by tools/update_modelines.py
241// vim: shiftwidth=2 expandtab tabstop=2 cindent
242// kate: tab-indents: off; indent-width 2; replace-tabs on; indent-mode cstyle; remove-trailing-spaces modified;
243// clang-format on
int width
Definition bilateral.h:1
int height
Definition bilateral.h:1
static const dt_aligned_pixel_simd_t const dt_adaptation_t const float p
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 colisa.c:155
const char ** description(struct dt_iop_module_t *self)
Definition colisa.c:93
int default_group()
Definition colisa.c:107
__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 colisa.c:126
void init_pipe(struct dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece)
Definition colisa.c:212
const char * name()
Definition colisa.c:88
void gui_init(struct dt_iop_module_t *self)
Definition colisa.c:226
int default_colorspace(dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_iop_t *piece)
Definition colisa.c:112
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 colisa.c:117
int flags()
Definition colisa.c:102
void cleanup_pipe(struct dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece)
Definition colisa.c:220
@ IOP_CS_LAB
const dt_colormatrix_t dt_aligned_pixel_t out
typedef void((*dt_cache_allocate_t)(void *userdata, dt_cache_entry_t *entry))
#define dt_free_align(ptr)
Definition darktable.h:481
static void * dt_calloc_align(size_t size)
Definition darktable.h:488
#define DT_MODULE_INTROSPECTION(MODVER, PARAMSTYPE)
Definition darktable.h:151
#define __DT_CLONE_TARGETS__
Definition darktable.h:367
#define __OMP_PARALLEL_FOR__(...)
Definition darktable.h:258
void dt_iop_params_t
Definition dev_history.h:41
void default_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 format.c:57
@ TYPE_FLOAT
Definition format.h:46
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:3141
@ IOP_FLAGS_INCLUDE_IN_STYLES
Definition imageop.h:166
@ IOP_FLAGS_DEPRECATED
Definition imageop.h:168
@ IOP_FLAGS_SUPPORTS_BLENDING
Definition imageop.h:167
@ IOP_FLAGS_ALLOW_TILING
Definition imageop.h:169
@ IOP_GROUP_EFFECTS
Definition imageop.h:142
#define IOP_GUI_ALLOC(module)
Definition imageop.h:599
GtkWidget * dt_bauhaus_slider_from_params(dt_iop_module_t *self, const char *param)
Definition imageop_gui.c:77
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)
float *const restrict const size_t k
float *const restrict const size_t const size_t ch
struct _GtkWidget GtkWidget
Definition splash.h:29
struct dt_iop_module_t *void * data
unsigned int channels
Definition format.h:54
dt_iop_buffer_type_t datatype
Definition format.h:56
float lunbounded_coeffs[3]
Definition colisa.c:85
float ctable[0x10000]
Definition colisa.c:82
float ltable[0x10000]
Definition colisa.c:84
float cunbounded_coeffs[3]
Definition colisa.c:83
GtkWidget * saturation
Definition colisa.c:74
GtkWidget * contrast
Definition colisa.c:72
GtkWidget * brightness
Definition colisa.c:73
Region of interest passed through the pixelpipe.
Definition imageop.h:72