108 return _(
"saturation");
136 return dt_iop_set_description(self, _(
"resaturate giving more weight to blacks, whites and low-saturation pixels"),
138 _(
"linear, RGB, scene-referred"),
140 _(
"linear, RGB, scene-referred"));
144 void *new_params,
const int new_version)
146 if(old_version == 1 && new_version == 2)
173 for(
size_t k = 0;
k < (size_t)roi_out->
width * roi_out->
height;
k++)
175 const float *
const in = (
const float *
const)ivoid +
ch *
k;
179 float pmax =
MAX(in[0],
MAX(in[1], in[2]));
180 float pmin =
MIN(in[0],
MIN(in[1], in[2]));
181 float plum = (pmax + pmin) / 2.0f;
182 float psat = (plum <= 0.5f) ? (pmax - pmin) / (1e-5f + pmax + pmin)
183 : (pmax - pmin) / (1e-5f +
MAX(0.0f, 2.0f - pmax - pmin));
186 =
CLAMPS(((1.0f - (1.5f * psat)) + ((1.0f + (fabsf(plum - 0.5f) * 2.0f)) * (1.0f - data->
bias)))
187 / (1.0f + (1.0f - data->
bias)),
189 float saturation =
strength * pweight;
192 out[0] =
CLAMPS(in[0] + saturation * (in[0] - 0.5f * (in[1] + in[2])), 0.0f, 1.0f);
193 out[1] =
CLAMPS(in[1] + saturation * (in[1] - 0.5f * (in[2] + in[0])), 0.0f, 1.0f);
194 out[2] =
CLAMPS(in[2] + saturation * (in[2] - 0.5f * (in[0] + in[1])), 0.0f, 1.0f);
208 d->strength =
p->strength;
238 gtk_widget_set_tooltip_text(
g->strength_scale, _(
"the strength of saturation boost"));
241 gtk_widget_set_tooltip_text(
g->bias_scale, _(
"how much to spare highlights and shadows"));
void dt_bauhaus_slider_set(GtkWidget *widget, float pos)
void dt_bauhaus_slider_set_format(GtkWidget *widget, const char *format)
struct _GtkWidget GtkWidget
GtkWidget, opaque, spelled exactly as GTK spells it.
const dt_colormatrix_t dt_aligned_pixel_t out
static float strength(float value, float strength)
@ DT_DEV_PIXELPIPE_DISPLAY_MASK
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)
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
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...
#define IOP_GUI_ALLOC(module)
float *const restrict const size_t k
float *const restrict const size_t const size_t ch
#define dt_free_align(ptr)
Release memory from dt_alloc_align() and set ptr to NULL.
static void * dt_calloc_align(size_t size)
dt_alloc_align() followed by a zero fill.
#define DT_MODULE_INTROSPECTION(MODVER, PARAMSTYPE)
DT_MODULE() for a module whose params struct is introspected.
#define __OMP_PARALLEL_FOR_SIMD__(...)
struct dt_iop_module_t *void * data
dt_iop_buffer_type_t datatype
Region of interest passed through the pixelpipe.
GtkWidget * strength_scale
#define __DT_CLONE_TARGETS__
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)
const char ** description(struct dt_iop_module_t *self)
__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)
void init_pipe(struct dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece)
void gui_update(struct dt_iop_module_t *self)
Refresh GUI controls from current params and configuration.
void gui_init(struct dt_iop_module_t *self)
int default_colorspace(dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_iop_t *piece)
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)
void cleanup_pipe(struct dt_iop_module_t *self, 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)