Ansel 0.0
A darktable fork - bloat + design vision
Loading...
Searching...
No Matches
shadhi.c
Go to the documentation of this file.
1/*
2 This file is part of darktable,
3 Copyright (C) 2011 Brian Teague.
4 Copyright (C) 2011 Henrik Andersson.
5 Copyright (C) 2011-2013, 2016-2017 johannes hanika.
6 Copyright (C) 2011 Jérémy Rosen.
7 Copyright (C) 2011 Robert Bieber.
8 Copyright (C) 2011-2014, 2016, 2019 Tobias Ellinghaus.
9 Copyright (C) 2011-2012, 2014-2017 Ulrich Pegelow.
10 Copyright (C) 2012 Pascal de Bruijn.
11 Copyright (C) 2012 Richard Wonka.
12 Copyright (C) 2013-2016 Roman Lebedev.
13 Copyright (C) 2015 Pedro Côrte-Real.
14 Copyright (C) 2017 Heiko Bauke.
15 Copyright (C) 2018, 2020, 2022-2023, 2025-2026 Aurélien PIERRE.
16 Copyright (C) 2018 Edgardo Hoszowski.
17 Copyright (C) 2018 Maurizio Paglia.
18 Copyright (C) 2018, 2020, 2022 Pascal Obry.
19 Copyright (C) 2018 rawfiner.
20 Copyright (C) 2019 Andreas Schneider.
21 Copyright (C) 2020 Aldric Renaudin.
22 Copyright (C) 2020-2021 Chris Elston.
23 Copyright (C) 2020, 2022 Diederik Ter Rahe.
24 Copyright (C) 2020-2021 Hubert Kowalski.
25 Copyright (C) 2020-2021 Ralf Brown.
26 Copyright (C) 2022 Hanno Schwalm.
27 Copyright (C) 2022 Martin Bařinka.
28 Copyright (C) 2022 Philipp Lutz.
29
30 darktable is free software: you can redistribute it and/or modify
31 it under the terms of the GNU General Public License as published by
32 the Free Software Foundation, either version 3 of the License, or
33 (at your option) any later version.
34
35 darktable is distributed in the hope that it will be useful,
36 but WITHOUT ANY WARRANTY; without even the implied warranty of
37 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
38 GNU General Public License for more details.
39
40 You should have received a copy of the GNU General Public License
41 along with darktable. If not, see <http://www.gnu.org/licenses/>.
42*/
43#ifdef HAVE_CONFIG_H
44#include "config.h"
45#endif
46#include "bauhaus/bauhaus.h"
47#include "common/bilateral.h"
48#include "common/bilateralcl.h"
49#include "common/debug.h"
50#include "common/gaussian.h"
51#include "common/opencl.h"
52#include "control/control.h"
53#include "develop/develop.h"
54#include "develop/imageop.h"
56#include "develop/imageop_gui.h"
57#include "develop/tiling.h"
58#include "dtgtk/togglebutton.h"
59
60#include "gui/gtk.h"
61#include "gui/presets.h"
62#include "iop/iop_api.h"
63#include <assert.h>
64#include <math.h>
65#include <stdlib.h>
66#include <string.h>
67
68#include <gtk/gtk.h>
69#include <inttypes.h>
70
71#define UNBOUND_L 1
72#define UNBOUND_A 2
73#define UNBOUND_B 4
74#define UNBOUND_SHADOWS_L UNBOUND_L
75#define UNBOUND_SHADOWS_A UNBOUND_A
76#define UNBOUND_SHADOWS_B UNBOUND_B
77#define UNBOUND_HIGHLIGHTS_L (UNBOUND_L << 3) /* 8 */
78#define UNBOUND_HIGHLIGHTS_A (UNBOUND_A << 3) /* 16 */
79#define UNBOUND_HIGHLIGHTS_B (UNBOUND_B << 3) /* 32 */
80#define UNBOUND_GAUSSIAN 64
81#define UNBOUND_BILATERAL 128 /* not implemented yet */
82#define UNBOUND_DEFAULT \
83 (UNBOUND_SHADOWS_L | UNBOUND_SHADOWS_A | UNBOUND_SHADOWS_B | UNBOUND_HIGHLIGHTS_L | UNBOUND_HIGHLIGHTS_A \
84 | UNBOUND_HIGHLIGHTS_B | UNBOUND_GAUSSIAN)
85
87
89{
90 SHADHI_ALGO_GAUSSIAN, // $DESCRIPTION: "gaussian"
91 SHADHI_ALGO_BILATERAL // $DESCRIPTION: "bilateral filter"
93
94/* legacy version 1 params */
105
106/* legacy version 2 params */
119
133
148
150{
151 dt_gaussian_order_t order; // $DEFAULT: DT_IOP_GAUSSIAN_ZERO
152 float radius; // $MIN: 0.1 $MAX: 500.0 $DEFAULT: 100.0
153 float shadows; // $MIN: -100.0 $MAX: 100.0 $DEFAULT: 50.0
154 float whitepoint; // $MIN: -10.0 $MAX: 10.0 $DEFAULT: 0.0 $DESCRIPTION: "white point adjustment"
155 float highlights; // $MIN: -100.0 $MAX: 100.0 $DEFAULT: -50.0
157 float compress; // $MIN: 0.0 $MAX: 100.0 $DEFAULT: 50.0
158 float shadows_ccorrect; // $MIN: 0.0 $MAX: 100.0 $DEFAULT: 100.0 $DESCRIPTION: "shadows color adjustment"
159 float highlights_ccorrect; // $MIN: 0.0 $MAX: 100.0 $DEFAULT: 50.0 $DESCRIPTION: "highlights color adjustment"
160 unsigned int flags; // $DEFAULT: UNBOUND_DEFAULT
161 float low_approximation; // $DEFAULT: 0.000001
162 dt_iop_shadhi_algo_t shadhi_algo; // $DEFAULT: SHADHI_ALGO_GAUSSIAN $DESCRIPTION: "soften with" $DEFAULT: 0
164
176
191
192const char *name()
193{
194 return _("shadows and highlights");
195}
196
201
203{
204 return IOP_GROUP_TONES;
205}
206
208{
209 return IOP_CS_LAB;
210}
211
212const char **description(struct dt_iop_module_t *self)
213{
214 return dt_iop_set_description(self, _("modify the tonal range of the shadows and highlights\n"
215 "of an image by enhancing local contrast."),
216 _("corrective and creative"),
217 _("linear or non-linear, Lab, display-referred"),
218 _("non-linear, Lab"),
219 _("non-linear, Lab, display-referred"));
220}
221
222int legacy_params(dt_iop_module_t *self, const void *const old_params, const int old_version,
223 void *new_params, const int new_version)
224{
225 if(old_version == 1 && new_version == 5)
226 {
227 const dt_iop_shadhi_params1_t *old = old_params;
228 dt_iop_shadhi_params_t *new = new_params;
229 new->order = old->order;
230 new->radius = fabs(old->radius);
231 new->shadows = 0.5f * old->shadows;
232 new->whitepoint = old->reserved1;
233 new->reserved2 = old->reserved2;
234 new->highlights = -0.5f * old->highlights;
235 new->flags = 0;
236 new->compress = old->compress;
237 new->shadows_ccorrect = 100.0f;
238 new->highlights_ccorrect = 0.0f;
239 new->low_approximation = 0.01f;
240 new->shadhi_algo = old->radius < 0.0f ? SHADHI_ALGO_BILATERAL : SHADHI_ALGO_GAUSSIAN;
241 return 0;
242 }
243 else if(old_version == 2 && new_version == 5)
244 {
245 const dt_iop_shadhi_params2_t *old = old_params;
246 dt_iop_shadhi_params_t *new = new_params;
247 new->order = old->order;
248 new->radius = fabs(old->radius);
249 new->shadows = old->shadows;
250 new->whitepoint = old->reserved1;
251 new->reserved2 = old->reserved2;
252 new->highlights = old->highlights;
253 new->compress = old->compress;
254 new->shadows_ccorrect = old->shadows_ccorrect;
255 new->highlights_ccorrect = old->highlights_ccorrect;
256 new->flags = 0;
257 new->low_approximation = 0.01f;
258 new->shadhi_algo = old->radius < 0.0f ? SHADHI_ALGO_BILATERAL : SHADHI_ALGO_GAUSSIAN;
259 return 0;
260 }
261 else if(old_version == 3 && new_version == 5)
262 {
263 const dt_iop_shadhi_params3_t *old = old_params;
264 dt_iop_shadhi_params_t *new = new_params;
265 new->order = old->order;
266 new->radius = fabs(old->radius);
267 new->shadows = old->shadows;
268 new->whitepoint = old->reserved1;
269 new->reserved2 = old->reserved2;
270 new->highlights = old->highlights;
271 new->compress = old->compress;
272 new->shadows_ccorrect = old->shadows_ccorrect;
273 new->highlights_ccorrect = old->highlights_ccorrect;
274 new->flags = old->flags;
275 new->low_approximation = 0.01f;
276 new->shadhi_algo = old->radius < 0.0f ? SHADHI_ALGO_BILATERAL : SHADHI_ALGO_GAUSSIAN;
277 return 0;
278 }
279 else if(old_version == 4 && new_version == 5)
280 {
281 const dt_iop_shadhi_params4_t *old = old_params;
282 dt_iop_shadhi_params_t *new = new_params;
283 new->order = old->order;
284 new->radius = fabs(old->radius);
285 new->shadows = old->shadows;
286 new->whitepoint = old->whitepoint;
287 new->reserved2 = old->reserved2;
288 new->highlights = old->highlights;
289 new->compress = old->compress;
290 new->shadows_ccorrect = old->shadows_ccorrect;
291 new->highlights_ccorrect = old->highlights_ccorrect;
292 new->flags = old->flags;
293 new->low_approximation = old->low_approximation;
294 new->shadhi_algo = old->radius < 0.0f ? SHADHI_ALGO_BILATERAL : SHADHI_ALGO_GAUSSIAN;
295 return 0;
296 }
297 return 1;
298}
299
300
301static inline void _Lab_scale(const float *i, float *o)
302{
303 o[0] = i[0] / 100.0f;
304 o[1] = i[1] / 128.0f;
305 o[2] = i[2] / 128.0f;
306}
307
308
309static inline void _Lab_rescale(const float *i, float *o)
310{
311 o[0] = i[0] * 100.0f;
312 o[1] = i[1] * 128.0f;
313 o[2] = i[2] * 128.0f;
314}
315
316static inline float sign(float x)
317{
318 return (x < 0 ? -1.0f : 1.0f);
319}
321int process(struct dt_iop_module_t *self, const dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_iop_t *piece, const void *const ivoid,
322 void *const ovoid)
323{
324 const dt_iop_roi_t *const roi_in = &piece->roi_in;
325 const dt_iop_roi_t *const roi_out = &piece->roi_out;
326 const dt_iop_shadhi_data_t *const restrict data = (dt_iop_shadhi_data_t *)piece->data;
327 const float *const restrict in = (float *)ivoid;
328 float *const restrict out = (float *)ovoid;
329 const int width = roi_out->width;
330 const int height = roi_out->height;
331 const int ch = piece->dsc_in.channels;
332
333 const int order = data->order;
334 const float radius = fmaxf(0.1f, data->radius);
335 const float sigma = radius * roi_in->scale;
336 const float shadows = 2.0f * fmin(fmax(-1.0, (data->shadows / 100.0f)), 1.0f);
337 const float highlights = 2.0f * fmin(fmax(-1.0, (data->highlights / 100.0f)), 1.0f);
338 const float whitepoint = fmax(1.0f - data->whitepoint / 100.0f, 0.01f);
339 const float compress
340 = fmin(fmax(0, (data->compress / 100.0f)), 0.99f); // upper limit 0.99f to avoid division by zero later
341 const float shadows_ccorrect = (fmin(fmax(0.0f, (data->shadows_ccorrect / 100.0f)), 1.0f) - 0.5f)
342 * sign(shadows) + 0.5f;
343 const float highlights_ccorrect = (fmin(fmax(0.0f, (data->highlights_ccorrect / 100.0f)), 1.0f) - 0.5f)
344 * sign(-highlights) + 0.5f;
345 const unsigned int flags = data->flags;
346 const int unbound_mask = ((data->shadhi_algo == SHADHI_ALGO_BILATERAL) && (flags & UNBOUND_BILATERAL))
347 || ((data->shadhi_algo == SHADHI_ALGO_GAUSSIAN) && (flags & UNBOUND_GAUSSIAN));
348 const float low_approximation = data->low_approximation;
349
350 if(data->shadhi_algo == SHADHI_ALGO_GAUSSIAN)
351 {
352 dt_aligned_pixel_t Labmax = { 100.0f, 128.0f, 128.0f, 1.0f };
353 dt_aligned_pixel_t Labmin = { 0.0f, -128.0f, -128.0f, 0.0f };
354
355 if(unbound_mask)
356 {
357 for(int k = 0; k < 4; k++) Labmax[k] = INFINITY;
358 for(int k = 0; k < 4; k++) Labmin[k] = -INFINITY;
359 }
360
361 dt_gaussian_t *g = dt_gaussian_init(width, height, ch, Labmax, Labmin, sigma, order);
362 if(IS_NULL_PTR(g)) return 1;
365 }
366 else
367 {
368 const float sigma_r = 100.0f; // d->sigma_r; // does not depend on scale
369 const float sigma_s = sigma;
370 const float detail = -1.0f; // we want the bilateral base layer
371
373 if(IS_NULL_PTR(b)) return 1;
374 dt_bilateral_splat(b, in);
376 dt_bilateral_slice(b, in, out, detail);
378 }
379
380 const dt_aligned_pixel_t max = { 1.0f, 1.0f, 1.0f, 1.0f };
381 const dt_aligned_pixel_t min = { 0.0f, -1.0f, -1.0f, 0.0f };
382 const float lmin = 0.0f;
383 const float lmax = max[0] + fabsf(min[0]);
384 const float halfmax = lmax / 2.0;
385 const float doublemax = lmax * 2.0;
387 for(size_t j = 0; j < (size_t)width * height * ch; j += ch)
388 {
389 dt_aligned_pixel_t ta, tb;
390 _Lab_scale(&in[j], ta);
391 // invert and desaturate the blurred output pixel
392 out[j + 0] = 100.0f - out[j + 0];
393 out[j + 1] = 0.0f;
394 out[j + 2] = 0.0f;
395 _Lab_scale(&out[j], tb);
396
397 ta[0] = ta[0] > 0.0f ? ta[0] / whitepoint : ta[0];
398 tb[0] = tb[0] > 0.0f ? tb[0] / whitepoint : tb[0];
399
400 // overlay highlights
401 float highlights2 = highlights * highlights;
402 const float highlights_xform = CLAMP(1.0f - tb[0] / (1.0f - compress), 0.0f, 1.0f);
403
404 while(highlights2 > 0.0f)
405 {
406 const float la = (flags & UNBOUND_HIGHLIGHTS_L) ? ta[0] : CLAMP(ta[0], lmin, lmax);
407 float lb = (tb[0] - halfmax) * sign(-highlights) * sign(lmax - la) + halfmax;
408 lb = unbound_mask ? lb : CLAMP(lb, lmin, lmax);
409 const float lref = copysignf(fabsf(la) > low_approximation ? 1.0f / fabsf(la) : 1.0f / low_approximation, la);
410 const float href = copysignf(
411 fabsf(1.0f - la) > low_approximation ? 1.0f / fabsf(1.0f - la) : 1.0f / low_approximation, 1.0f - la);
412
413 const float chunk = highlights2 > 1.0f ? 1.0f : highlights2;
414 const float optrans = chunk * highlights_xform;
415 highlights2 -= 1.0f;
416
417 ta[0] = la * (1.0 - optrans)
418 + (la > halfmax ? lmax - (lmax - doublemax * (la - halfmax)) * (lmax - lb) : doublemax * la
419 * lb) * optrans;
420
421 ta[0] = (flags & UNBOUND_HIGHLIGHTS_L) ? ta[0] : CLAMP(ta[0], lmin, lmax);
422
423 const float chroma_factor = (ta[0] * lref * (1.0f - highlights_ccorrect)
424 + (1.0f - ta[0]) * href * highlights_ccorrect);
425 ta[1] = ta[1] * (1.0f - optrans) + (ta[1] + tb[1]) * chroma_factor * optrans;
426 ta[1] = (flags & UNBOUND_HIGHLIGHTS_A) ? ta[1] : CLAMP(ta[1], min[1], max[1]);
427
428 ta[2] = ta[2] * (1.0f - optrans) + (ta[2] + tb[2]) * chroma_factor * optrans;
429 ta[2] = (flags & UNBOUND_HIGHLIGHTS_B) ? ta[2] : CLAMP(ta[2], min[2], max[2]);
430 }
431
432 // overlay shadows
433 float shadows2 = shadows * shadows;
434 const float shadows_xform = CLAMP(tb[0] / (1.0f - compress) - compress / (1.0f - compress), 0.0f, 1.0f);
435
436 while(shadows2 > 0.0f)
437 {
438 const float la = (flags & UNBOUND_HIGHLIGHTS_L) ? ta[0] : CLAMP(ta[0], lmin, lmax);
439 float lb = (tb[0] - halfmax) * sign(shadows) * sign(lmax - la) + halfmax;
440 lb = unbound_mask ? lb : CLAMP(lb, lmin, lmax);
441 const float lref = copysignf(fabsf(la) > low_approximation ? 1.0f / fabsf(la) : 1.0f / low_approximation, la);
442 const float href = copysignf(
443 fabsf(1.0f - la) > low_approximation ? 1.0f / fabsf(1.0f - la) : 1.0f / low_approximation, 1.0f - la);
444
445
446 const float chunk = shadows2 > 1.0f ? 1.0f : shadows2;
447 const float optrans = chunk * shadows_xform;
448 shadows2 -= 1.0f;
449
450 ta[0] = la * (1.0 - optrans)
451 + (la > halfmax ? lmax - (lmax - doublemax * (la - halfmax)) * (lmax - lb) : doublemax * la
452 * lb) * optrans;
453
454 ta[0] = (flags & UNBOUND_SHADOWS_L) ? ta[0] : CLAMP(ta[0], lmin, lmax);
455
456 const float chroma_factor = (ta[0] * lref * shadows_ccorrect
457 + (1.0f - ta[0]) * href * (1.0f - shadows_ccorrect));
458 ta[1] = ta[1] * (1.0f - optrans) + (ta[1] + tb[1]) * chroma_factor * optrans;
459 ta[1] = (flags & UNBOUND_SHADOWS_A) ? ta[1] : CLAMP(ta[1], min[1], max[1]);
460
461 ta[2] = ta[2] * (1.0f - optrans) + (ta[2] + tb[2]) * chroma_factor * optrans;
462 ta[2] = (flags & UNBOUND_SHADOWS_B) ? ta[2] : CLAMP(ta[2], min[2], max[2]);
463 }
464
465 _Lab_rescale(ta, &out[j]);
466 }
467
468 if(pipe->mask_display & DT_DEV_PIXELPIPE_DISPLAY_MASK) dt_iop_alpha_copy(ivoid, ovoid, roi_out->width, roi_out->height);
469 return 0;
470}
471
472
473void tiling_callback(struct dt_iop_module_t *self, const struct dt_dev_pixelpipe_t *pipe, const struct dt_dev_pixelpipe_iop_t *piece, struct dt_develop_tiling_t *tiling)
474{
475 (void)self;
476 (void)pipe;
477 const dt_iop_roi_t *const roi_in = &piece->roi_in;
479
480 const int width = roi_in->width;
481 const int height = roi_in->height;
482 const int channels = piece->dsc_in.channels;
483
484 const float radius = fmax(0.1f, d->radius);
485 const float sigma = radius * roi_in->scale;
486 const float sigma_r = 100.0f; // does not depend on scale
487 const float sigma_s = sigma;
488
489 const size_t basebuffer = sizeof(float) * channels * width * height;
490
491 if(d->shadhi_algo == SHADHI_ALGO_BILATERAL)
492 {
493 // bilateral filter
494 tiling->factor = 2.0f + fmax(1.0f, (float)dt_bilateral_memory_use(width, height, sigma_s, sigma_r) / basebuffer);
495 tiling->maxbuf
496 = fmax(1.0f, (float)dt_bilateral_singlebuffer_size(width, height, sigma_s, sigma_r) / basebuffer);
497 }
498 else
499 {
500 // gaussian blur
501 tiling->factor = 2.0f + fmax(1.0f, (float)dt_gaussian_memory_use(width, height, channels) / basebuffer);
502 tiling->maxbuf = fmax(1.0f, (float)dt_gaussian_singlebuffer_size(width, height, channels) / basebuffer);
503 }
504
505 tiling->overhead = 0;
506 tiling->overlap = ceilf(4 * sigma);
507 tiling->xalign = 1;
508 tiling->yalign = 1;
509 return;
510}
511
514{
517
518 d->order = p->order;
519 d->radius = p->radius;
520 d->shadows = p->shadows;
521 d->highlights = p->highlights;
522 d->whitepoint = p->whitepoint;
523 d->compress = p->compress;
524 d->shadows_ccorrect = p->shadows_ccorrect;
525 d->highlights_ccorrect = p->highlights_ccorrect;
526 d->flags = p->flags;
527 d->low_approximation = p->low_approximation;
528 d->shadhi_algo = p->shadhi_algo;
529}
530
532{
533 piece->data = dt_calloc_align(sizeof(dt_iop_shadhi_data_t));
534 piece->data_size = sizeof(dt_iop_shadhi_data_t);
535}
536
538{
539 dt_free_align(piece->data);
540 piece->data = NULL;
541}
542
543void gui_init(struct dt_iop_module_t *self)
544{
546
547 g->shadows = dt_bauhaus_slider_from_params(self, N_("shadows"));
548 g->highlights = dt_bauhaus_slider_from_params(self, N_("highlights"));
549 g->whitepoint = dt_bauhaus_slider_from_params(self, "whitepoint");
550 g->shadhi_algo = dt_bauhaus_combobox_from_params(self, "shadhi_algo");
551 g->radius = dt_bauhaus_slider_from_params(self, N_("radius"));
552 g->compress = dt_bauhaus_slider_from_params(self, N_("compress"));
553 dt_bauhaus_slider_set_format(g->compress, "%");
554 g->shadows_ccorrect = dt_bauhaus_slider_from_params(self, "shadows_ccorrect");
555 dt_bauhaus_slider_set_format(g->shadows_ccorrect, "%");
556 g->highlights_ccorrect = dt_bauhaus_slider_from_params(self, "highlights_ccorrect");
557 dt_bauhaus_slider_set_format(g->highlights_ccorrect, "%");
558
559 gtk_widget_set_tooltip_text(g->shadows, _("correct shadows"));
560 gtk_widget_set_tooltip_text(g->highlights, _("correct highlights"));
561 gtk_widget_set_tooltip_text(g->whitepoint, _("shift white point"));
562 gtk_widget_set_tooltip_text(g->radius, _("spatial extent"));
563 gtk_widget_set_tooltip_text(g->shadhi_algo, _("filter to use for softening. bilateral avoids halos"));
564 gtk_widget_set_tooltip_text(g->compress, _("compress the effect on shadows/highlights and\npreserve mid-tones"));
565 gtk_widget_set_tooltip_text(g->shadows_ccorrect, _("adjust saturation of shadows"));
566 gtk_widget_set_tooltip_text(g->highlights_ccorrect, _("adjust saturation of highlights"));
567}
568
569// clang-format off
570// modelines: These editor modelines have been set for all relevant files by tools/update_modelines.py
571// vim: shiftwidth=2 expandtab tabstop=2 cindent
572// kate: tab-indents: off; indent-width 2; replace-tabs on; indent-mode cstyle; remove-trailing-spaces modified;
573// clang-format on
void dt_bauhaus_slider_set_format(GtkWidget *widget, const char *format)
Definition bauhaus.c:3598
void dt_bilateral_free(dt_bilateral_t *b)
Definition bilateral.c:426
__DT_CLONE_TARGETS__ void dt_bilateral_splat(const dt_bilateral_t *b, const float *const in)
Definition bilateral.c:177
size_t dt_bilateral_memory_use(const int width, const int height, const float sigma_s, const float sigma_r)
Definition bilateral.c:74
dt_bilateral_t * dt_bilateral_init(const int width, const int height, const float sigma_s, const float sigma_r)
Definition bilateral.c:151
size_t dt_bilateral_singlebuffer_size(const int width, const int height, const float sigma_s, const float sigma_r)
Definition bilateral.c:102
__DT_CLONE_TARGETS__ void dt_bilateral_slice(const dt_bilateral_t *const b, const float *const in, float *out, const float detail)
Definition bilateral.c:350
void dt_bilateral_blur(const dt_bilateral_t *b)
Definition bilateral.c:335
int width
Definition bilateral.h:1
float sigma_s
Definition bilateral.h:3
int height
Definition bilateral.h:1
float sigma_r
Definition bilateral.h:3
static const dt_aligned_pixel_simd_t const dt_adaptation_t const float p
@ IOP_CS_LAB
static const float const float const float min
const float max
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
static const dt_aligned_pixel_simd_t sign
Definition darktable.h:551
#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
#define IS_NULL_PTR(p)
C is way too permissive with !=, == and if(var) checks, which can mean too many things depending on w...
Definition darktable.h:281
void dt_iop_params_t
Definition dev_history.h:41
@ DT_DEV_PIXELPIPE_DISPLAY_MASK
Definition develop.h:118
void dt_gaussian_free(dt_gaussian_t *g)
Definition gaussian.c:330
size_t dt_gaussian_singlebuffer_size(const int width, const int height, const int channels)
Definition gaussian.c:108
void dt_gaussian_blur_4c(dt_gaussian_t *g, const float *const in, float *const out)
Definition gaussian.c:325
dt_gaussian_t * dt_gaussian_init(const int width, const int height, const int channels, const float *max, const float *min, const float sigma, const int order)
Definition gaussian.c:122
size_t dt_gaussian_memory_use(const int width, const int height, const int channels)
Definition gaussian.c:92
dt_gaussian_order_t
Definition gaussian.h:32
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_TONES
Definition imageop.h:137
#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
GtkWidget * dt_bauhaus_combobox_from_params(dt_iop_module_t *self, const char *param)
void *const ovoid
static const float x
float *const restrict const size_t k
float *const restrict const size_t const size_t ch
float dt_aligned_pixel_t[4]
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 shadhi.c:512
#define UNBOUND_SHADOWS_L
Definition shadhi.c:74
const char ** description(struct dt_iop_module_t *self)
Definition shadhi.c:212
int default_group()
Definition shadhi.c:202
__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 shadhi.c:321
#define UNBOUND_GAUSSIAN
Definition shadhi.c:80
#define UNBOUND_HIGHLIGHTS_L
Definition shadhi.c:77
#define UNBOUND_HIGHLIGHTS_A
Definition shadhi.c:78
#define UNBOUND_SHADOWS_A
Definition shadhi.c:75
#define UNBOUND_SHADOWS_B
Definition shadhi.c:76
void init_pipe(struct dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece)
Definition shadhi.c:531
const char * name()
Definition shadhi.c:192
void gui_init(struct dt_iop_module_t *self)
Definition shadhi.c:543
static void _Lab_rescale(const float *i, float *o)
Definition shadhi.c:309
void tiling_callback(struct dt_iop_module_t *self, const struct dt_dev_pixelpipe_t *pipe, const struct dt_dev_pixelpipe_iop_t *piece, struct dt_develop_tiling_t *tiling)
Definition shadhi.c:473
int default_colorspace(dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_iop_t *piece)
Definition shadhi.c:207
int flags()
Definition shadhi.c:197
#define UNBOUND_BILATERAL
Definition shadhi.c:81
#define UNBOUND_HIGHLIGHTS_B
Definition shadhi.c:79
void cleanup_pipe(struct dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece)
Definition shadhi.c:537
dt_iop_shadhi_algo_t
Definition shadhi.c:89
@ SHADHI_ALGO_BILATERAL
Definition shadhi.c:91
@ SHADHI_ALGO_GAUSSIAN
Definition shadhi.c:90
static void _Lab_scale(const float *i, float *o)
Definition shadhi.c:301
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 shadhi.c:222
struct _GtkWidget GtkWidget
Definition splash.h:29
const float sigma
dt_iop_buffer_dsc_t dsc_in
struct dt_iop_module_t *void * data
unsigned int channels
Definition format.h:54
Region of interest passed through the pixelpipe.
Definition imageop.h:72
double scale
Definition imageop.h:74
dt_gaussian_order_t order
Definition shadhi.c:179
float highlights_ccorrect
Definition shadhi.c:186
float low_approximation
Definition shadhi.c:188
dt_iop_shadhi_algo_t shadhi_algo
Definition shadhi.c:189
unsigned int flags
Definition shadhi.c:187
GtkWidget * highlights_ccorrect
Definition shadhi.c:173
GtkWidget * whitepoint
Definition shadhi.c:169
GtkWidget * compress
Definition shadhi.c:171
GtkWidget * shadows_ccorrect
Definition shadhi.c:172
GtkWidget * shadhi_algo
Definition shadhi.c:174
GtkWidget * highlights
Definition shadhi.c:168
GtkWidget * shadows
Definition shadhi.c:167
dt_gaussian_order_t order
Definition shadhi.c:97
dt_gaussian_order_t order
Definition shadhi.c:109
unsigned int flags
Definition shadhi.c:131
dt_gaussian_order_t order
Definition shadhi.c:122
unsigned int flags
Definition shadhi.c:145
dt_gaussian_order_t order
Definition shadhi.c:136
dt_gaussian_order_t order
Definition shadhi.c:151
unsigned int flags
Definition shadhi.c:160
dt_iop_shadhi_algo_t shadhi_algo
Definition shadhi.c:162