Ansel 0.0
A darktable fork - bloat + design vision
Loading...
Searching...
No Matches
velvia.c
Go to the documentation of this file.
1/*
2 This file is part of darktable,
3 Copyright (C) 2010 Bernhard Schneider.
4 Copyright (C) 2010-2011 Bruce Guenter.
5 Copyright (C) 2010-2012 Henrik Andersson.
6 Copyright (C) 2010-2013, 2016 johannes hanika.
7 Copyright (C) 2010 Stuart Henderson.
8 Copyright (C) 2011 Antony Dovgal.
9 Copyright (C) 2011 Jérémy Rosen.
10 Copyright (C) 2011 Olivier Tribout.
11 Copyright (C) 2011 Robert Bieber.
12 Copyright (C) 2011 Rostyslav Pidgornyi.
13 Copyright (C) 2011-2014, 2016, 2019 Tobias Ellinghaus.
14 Copyright (C) 2012 Richard Wonka.
15 Copyright (C) 2012, 2014, 2017 Ulrich Pegelow.
16 Copyright (C) 2013 Simon Spannagel.
17 Copyright (C) 2014-2016 Roman Lebedev.
18 Copyright (C) 2015 Pedro Côrte-Real.
19 Copyright (C) 2017 Heiko Bauke.
20 Copyright (C) 2018, 2020, 2022-2023, 2025-2026 Aurélien PIERRE.
21 Copyright (C) 2018 Edgardo Hoszowski.
22 Copyright (C) 2018 Maurizio Paglia.
23 Copyright (C) 2018, 2020, 2022 Pascal Obry.
24 Copyright (C) 2018 rawfiner.
25 Copyright (C) 2019 Andreas Schneider.
26 Copyright (C) 2019 Diederik ter Rahe.
27 Copyright (C) 2020 Aldric Renaudin.
28 Copyright (C) 2020, 2022 Diederik Ter Rahe.
29 Copyright (C) 2020-2021 Hubert Kowalski.
30 Copyright (C) 2020-2021 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 <math.h>
54#include <stdlib.h>
55#include <string.h>
56
57#include "bauhaus/bauhaus.h"
58#include "common/imagebuf.h"
59#include "common/opencl.h"
60#include "control/control.h"
61#include "develop/develop.h"
62#include "develop/imageop.h"
64#include "develop/imageop_gui.h"
65
66#include "gui/gtk.h"
67#include "iop/iop_api.h"
68
69#include <gtk/gtk.h>
70#include <inttypes.h>
71
73
75{
76 float strength; // $MIN: 0.0 $MAX: 100.0 $DEFAULT: 25.0
77 float bias; // $MIN: 0.0 $MAX: 1.0 $DEFAULT: 1.0 $DESCRIPTION: "mid-tones bias"
79
80/* legacy version 1 params */
88
95
101
102const char *name()
103{
104 return _("velvia");
105}
106
107const char *aliases()
108{
109 return _("saturation");
110}
111
116
118{
119 return IOP_GROUP_COLOR;
120}
121
123{
124 return IOP_CS_RGB;
125}
126
129{
130 default_input_format(self, pipe, piece, dsc);
131 dsc->channels = 4;
132 dsc->datatype = TYPE_FLOAT;
133}
134
135const char **description(struct dt_iop_module_t *self)
136{
137 return dt_iop_set_description(self, _("resaturate giving more weight to blacks, whites and low-saturation pixels"),
138 _("creative"),
139 _("linear, RGB, scene-referred"),
140 _("linear, RGB"),
141 _("linear, RGB, scene-referred"));
142}
143
144int legacy_params(dt_iop_module_t *self, const void *const old_params, const int old_version,
145 void *new_params, const int new_version)
146{
147 if(old_version == 1 && new_version == 2)
148 {
149 const dt_iop_velvia_params1_t *old = old_params;
150 dt_iop_velvia_params_t *new = new_params;
151 new->strength = old->saturation * old->vibrance / 100.0f;
152 new->bias = old->luminance;
153 return 0;
154 }
155 return 1;
156}
157
159int process(struct dt_iop_module_t *self, const dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_iop_t *piece, const void *const ivoid,
160 void *const ovoid)
161{
162 const dt_iop_roi_t *const roi_out = &piece->roi_out;
163 const dt_iop_velvia_data_t *const data = (dt_iop_velvia_data_t *)piece->data;
164
165 const size_t ch = 4;
166 const float strength = data->strength / 100.0f;
167
168 // Apply velvia saturation
169 if(strength <= 0.0)
170 dt_iop_image_copy_by_size(ovoid, ivoid, roi_out->width, roi_out->height, ch);
171 else
172 {
174 for(size_t k = 0; k < (size_t)roi_out->width * roi_out->height; k++)
175 {
176 const float *const in = (const float *const)ivoid + ch * k;
177 float *const out = (float *const)ovoid + ch * k;
178
179 // calculate vibrance, and apply boost velvia saturation at least saturated pixels
180 float pmax = MAX(in[0], MAX(in[1], in[2])); // max value in RGB set
181 float pmin = MIN(in[0], MIN(in[1], in[2])); // min value in RGB set
182 float plum = (pmax + pmin) / 2.0f; // pixel luminocity
183 float psat = (plum <= 0.5f) ? (pmax - pmin) / (1e-5f + pmax + pmin)
184 : (pmax - pmin) / (1e-5f + MAX(0.0f, 2.0f - pmax - pmin));
185
186 float pweight
187 = CLAMPS(((1.0f - (1.5f * psat)) + ((1.0f + (fabsf(plum - 0.5f) * 2.0f)) * (1.0f - data->bias)))
188 / (1.0f + (1.0f - data->bias)),
189 0.0f, 1.0f); // The weight of pixel
190 float saturation = strength * pweight; // So lets calculate the final affection of filter on pixel
191
192 // Apply velvia saturation values
193 out[0] = CLAMPS(in[0] + saturation * (in[0] - 0.5f * (in[1] + in[2])), 0.0f, 1.0f);
194 out[1] = CLAMPS(in[1] + saturation * (in[1] - 0.5f * (in[2] + in[0])), 0.0f, 1.0f);
195 out[2] = CLAMPS(in[2] + saturation * (in[2] - 0.5f * (in[0] + in[1])), 0.0f, 1.0f);
196 }
197 }
198
199 if(pipe->mask_display & DT_DEV_PIXELPIPE_DISPLAY_MASK) dt_iop_alpha_copy(ivoid, ovoid, roi_out->width, roi_out->height);
200 return 0;
201}
202
205{
208
209 d->strength = p->strength;
210 d->bias = p->bias;
211}
212
214{
215 piece->data = dt_calloc_align(sizeof(dt_iop_velvia_data_t));
216 piece->data_size = sizeof(dt_iop_velvia_data_t);
217}
218
220{
221 dt_free_align(piece->data);
222 piece->data = NULL;
223}
224
225void gui_update(struct dt_iop_module_t *self)
226{
229 dt_bauhaus_slider_set(g->strength_scale, p->strength);
230 dt_bauhaus_slider_set(g->bias_scale, p->bias);
231}
232
233void gui_init(struct dt_iop_module_t *self)
234{
236
237 g->strength_scale = dt_bauhaus_slider_from_params(self, N_("strength"));
238 dt_bauhaus_slider_set_format(g->strength_scale, "%");
239 gtk_widget_set_tooltip_text(g->strength_scale, _("the strength of saturation boost"));
240
241 g->bias_scale = dt_bauhaus_slider_from_params(self, "bias");
242 gtk_widget_set_tooltip_text(g->bias_scale, _("how much to spare highlights and shadows"));
243}
244
245// clang-format off
246// modelines: These editor modelines have been set for all relevant files by tools/update_modelines.py
247// vim: shiftwidth=2 expandtab tabstop=2 cindent
248// kate: tab-indents: off; indent-width 2; replace-tabs on; indent-mode cstyle; remove-trailing-spaces modified;
249// clang-format on
void dt_bauhaus_slider_set(GtkWidget *widget, float pos)
Definition bauhaus.c:3506
void dt_bauhaus_slider_set_format(GtkWidget *widget, const char *format)
Definition bauhaus.c:3598
static const dt_aligned_pixel_simd_t const dt_adaptation_t const float p
@ IOP_CS_RGB
const dt_colormatrix_t dt_aligned_pixel_t out
static float strength(float value, float strength)
Definition colorzones.c:420
#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_SIMD__(...)
Definition darktable.h:259
void dt_iop_params_t
Definition dev_history.h:41
@ DT_DEV_PIXELPIPE_DISPLAY_MASK
Definition develop.h:118
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
static void dt_iop_image_copy_by_size(float *const __restrict__ out, const float *const __restrict__ in, const size_t width, const size_t height, const size_t ch)
Definition imagebuf.h:87
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_COLOR
Definition imageop.h:139
#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
float *const restrict const size_t k
float *const restrict const size_t const size_t ch
#define CLAMPS(A, L, H)
Definition math.h:76
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
dt_iop_gui_data_t * gui_data
Definition imageop.h:311
dt_iop_params_t * params
Definition imageop.h:307
Region of interest passed through the pixelpipe.
Definition imageop.h:72
GtkWidget * bias_scale
Definition velvia.c:93
GtkWidget * strength_scale
Definition velvia.c:92
#define MIN(a, b)
Definition thinplate.c:32
#define MAX(a, b)
Definition thinplate.c:29
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 velvia.c:203
const char ** description(struct dt_iop_module_t *self)
Definition velvia.c:135
int default_group()
Definition velvia.c:117
__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 velvia.c:159
const char * aliases()
Definition velvia.c:107
void init_pipe(struct dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece)
Definition velvia.c:213
const char * name()
Definition velvia.c:102
void gui_update(struct dt_iop_module_t *self)
Refresh GUI controls from current params and configuration.
Definition velvia.c:225
void gui_init(struct dt_iop_module_t *self)
Definition velvia.c:233
int default_colorspace(dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_iop_t *piece)
Definition velvia.c:122
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 velvia.c:127
int flags()
Definition velvia.c:112
void cleanup_pipe(struct dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece)
Definition velvia.c:219
int legacy_params(dt_iop_module_t *self, const void *const old_params, const int old_version, void *new_params, const int new_version)
Definition velvia.c:144