47#define __STDC_FORMAT_MACROS
108 return _(
"surface blur");
113 return _(
"denoise (bilateral filter)");
134 _(
"corrective and creative"),
135 _(
"linear, RGB, scene-referred"),
137 _(
"linear, RGB, scene-referred"));
162 const int rad = (int)(3.0 * fmaxf(
sigma[0],
sigma[1]) + 1.0);
170 static const size_t weights_size = 2 * (6 + 1) * 2 * (6 + 1);
171 float mat[weights_size];
172 const int wd = 2 * rad + 1;
173 float *
m = mat + rad * wd + rad;
175 const float isig2col[3] = { 1.f / (2.0f *
sigma[2] *
sigma[2]), 1.f / (2.0f *
sigma[3] *
sigma[3]),
178 for(
int l = -rad; l <= rad; l++)
179 for(
int k = -rad;
k <= rad;
k++)
181 for(
int l = -rad; l <= rad; l++)
182 for(
int k = -rad;
k <= rad;
k++)
m[l * wd +
k] /=
weight;
184 size_t padded_weights_size;
187 __OMP_PARALLEL_FOR_CPP__(firstprivate(isig2col, ivoid,
ovoid, roi_in, roi_out, rad,
ch,
m, wd, weights_buf, padded_weights_size))
188 for(
int j = rad; j < roi_out->
height - rad; j++)
190 const float *in = ((
float *)ivoid) +
ch * ((size_t)j * roi_in->
width + rad);
191 float *
out = ((
float *)
ovoid) +
ch * ((size_t)j * roi_out->
width + rad);
192 float *weights = (
float*)
dt_get_perthread(weights_buf, padded_weights_size);
193 float *w = weights + rad * wd + rad;
195 for(
int i = rad;
i < roi_out->
width - rad;
i++)
198 for(
int l = -rad; l <= rad; l++)
199 for(
int k = -rad;
k <= rad;
k++)
201 const float *inp = in +
ch * (l * roi_in->
width +
k);
202 sumw += w[l * wd +
k] =
m[l * wd +
k]
203 * expf(-((in[0] - inp[0]) * (in[0] - inp[0]) * isig2col[0]
204 + (in[1] - inp[1]) * (in[1] - inp[1]) * isig2col[1]
205 + (in[2] - inp[2]) * (in[2] - inp[2]) * isig2col[2]));
207 for(
int l = -rad; l <= rad; l++)
208 for(
int k = -rad;
k <= rad;
k++) w[l * wd +
k] /= sumw;
210 for(
int l = -rad; l <= rad; l++)
211 for(
int k = -rad;
k <= rad;
k++)
213 const float *inp = in +
ch * ((size_t)l * roi_in->
width +
k);
214 float pix_weight = w[(size_t)l * wd +
k];
226 for(
int j = 0; j < rad; j++)
227 memcpy(((
float *)
ovoid) + (
size_t)
ch * j * roi_out->
width,
228 ((
float *)ivoid) + (
size_t)
ch * j * roi_in->
width, (
size_t)
ch *
sizeof(
float) * roi_out->
width);
229 for(
int j = roi_out->
height - rad; j < roi_out->
height; j++)
230 memcpy(((
float *)
ovoid) + (size_t)
ch * j * roi_out->
width,
231 ((
float *)ivoid) + (
size_t)
ch * j * roi_in->
width, (size_t)
ch *
sizeof(
float) * roi_out->
width);
232 for(
int j = rad; j < roi_out->
height - rad; j++)
234 const float *in = ((
float *)ivoid) + (size_t)
ch * roi_out->
width * j;
236 for(
int i = 0;
i < rad;
i++)
249#pragma omp parallel for
251 for(
int j = 0; j < roi_in->
height; j++)
253 const float *in = (
const float *)ivoid + (
size_t)j * roi_in->
width *
ch;
255 size_t index = (size_t)j * roi_in->
width;
256 for(
int i = 0;
i < roi_in->
width;
i++, index++)
260 lattice.
splat(pos, val, index, thread);
272#pragma omp parallel for
274 for(
int j = 0; j < roi_in->
height; j++)
277 size_t index = (size_t)j * roi_in->
width;
278 for(
int i = 0;
i < roi_in->
width;
i++, index++)
281 lattice.
slice(val, index);
283 out[(size_t)
ch*
i +
k] = val[
k] / val[3];
297 d->sigma[0] =
p->radius;
298 d->sigma[1] =
p->radius;
299 d->sigma[2] =
p->red;
300 d->sigma[3] =
p->green;
301 d->sigma[4] =
p->blue;
323 const int rad = (int)(3.0 * fmaxf(
sigma[0],
sigma[1]) + 1.0);
324 tiling->factor = 2.0 + 80.0/16 + 52.0/16;
337 gtk_widget_set_tooltip_text(
g->radius, _(
"spatial extent of the gaussian"));
341 gtk_widget_set_tooltip_text(
g->red, _(
"how much to blur red"));
346 gtk_widget_set_tooltip_text(
g->green, _(
"how much to blur green"));
351 gtk_widget_set_tooltip_text(
g->blue, _(
"how much to blur blue"));
void dt_bauhaus_slider_set_soft_range(GtkWidget *widget, float soft_min, float soft_max)
void dt_bauhaus_slider_set_digits(GtkWidget *widget, int val)
void dt_bauhaus_slider_set_soft_max(GtkWidget *widget, float val)
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_init(dt_iop_module_t *self)
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)
int default_colorspace(dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_iop_t *piece)
void cleanup_pipe(struct dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece)
void slice(float *col, size_t replay_index) const
void merge_splat_threads()
void splat(float *position, float *value, size_t replay_index, int thread_index=0) const
struct _GtkWidget GtkWidget
GtkWidget, opaque, spelled exactly as GTK spells it.
const dt_colormatrix_t dt_aligned_pixel_t out
int dt_get_num_openmp_threads(void)
Number of OpenMP threads the application decided to use.
static void weight(const float *c1, const float *c2, const float sharpen, dt_aligned_pixel_t weight)
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_SUPPORTS_BLENDING
GtkWidget * dt_bauhaus_slider_from_params(dt_iop_module_t *self, const char *param)
#define IOP_GUI_ALLOC(module)
float *const restrict const size_t k
float *const restrict const size_t const size_t ch
#define IS_NULL_PTR(p)
C is way too permissive with !=, == and if(var) checks, which can mean too many things depending on w...
#define DT_ALIGNED_PIXEL
Align a 4-float pixel on 16 bytes, enough for SSE. Same struct-member caveat as DT_ALIGNED_ARRAY,...
#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.
static int dt_get_thread_num()
Index of the calling thread within its parallel region, 0 outside one.
#define __OMP_PARALLEL_FOR_CPP__(...)
@ DT_DEV_PIXELPIPE_THUMBNAIL
#define dt_pixelpipe_cache_free_align(mem)
#define dt_get_perthread(buf, padsize)
#define dt_pixelpipe_cache_alloc_perthread_float(n, padded_size)
#define for_each_channel(_var,...)
dt_iop_buffer_dsc_t dsc_in
struct dt_iop_module_t *void * data
dt_dev_pixelpipe_type_t type
Region of interest passed through the pixelpipe.
#define __DT_CLONE_TARGETS__