40#define MIN_FLOAT exp2f(-16.0f)
89 return fmaxf(fminf(
value,
top), bottom);
94static inline void interpolate_bilinear(
const float *
const restrict in,
const size_t width_in,
const size_t height_in,
95 float *
const restrict
out,
const size_t width_out,
const size_t height_out,
100 for(
size_t i = 0;
i < height_out;
i++)
102 for(
size_t j = 0; j < width_out; j++)
105 const float x_out = (float)j /(
float)width_out;
106 const float y_out = (float)
i /(
float)height_out;
109 const float x_in = x_out * (float)width_in;
110 const float y_in = y_out * (float)height_in;
113 size_t x_prev = (size_t)floorf(x_in);
114 size_t x_next = x_prev + 1;
115 size_t y_prev = (size_t)floorf(y_in);
116 size_t y_next = y_prev + 1;
118 x_prev = (x_prev < width_in) ? x_prev : width_in - 1;
119 x_next = (x_next < width_in) ? x_next : width_in - 1;
120 y_prev = (y_prev < height_in) ? y_prev : height_in - 1;
121 y_next = (y_next < height_in) ? y_next : height_in - 1;
124 const size_t Y_prev = y_prev * width_in;
125 const size_t Y_next = y_next * width_in;
126 const float *
const Q_NW = (
float *)in + (Y_prev + x_prev) *
ch;
127 const float *
const Q_NE = (
float *)in + (Y_prev + x_next) *
ch;
128 const float *
const Q_SE = (
float *)in + (Y_next + x_next) *
ch;
129 const float *
const Q_SW = (
float *)in + (Y_next + x_prev) *
ch;
132 const float Dy_next = (float)y_next - y_in;
133 const float Dy_prev = 1.f - Dy_next;
134 const float Dx_next = (float)x_next - x_in;
135 const float Dx_prev = 1.f - Dx_next;
138 float *
const pixel_out = (
float *)
out + (
i * width_out + j) *
ch;
141 for(
size_t c = 0; c <
ch; c++)
143 pixel_out[c] = Dy_prev * (Q_SW[c] * Dx_next + Q_SE[c] * Dx_prev) +
144 Dy_next * (Q_NW[c] * Dx_next + Q_NE[c] * Dx_prev);
154 const float *
const restrict mask,
155 float *
const restrict ab,
157 const int radius,
const float feathering)
165 const size_t Ndimch = Ndim * 4;
175 for(
size_t k = 0;
k < Ndim;
k++)
177 const size_t index =
k * 4;
178 input[index] = guide[
k];
179 input[index + 1] = mask[
k];
180 input[index + 2] = guide[
k] * guide[
k];
181 input[index + 3] = guide[
k] * mask[
k];
195 const float d = fmaxf((input[4*idx+2] - input[4*idx+0] * input[4*idx+0]) + feathering, 1e-15f);
196 const float a = (input[4*idx+3] - input[4*idx+0] * input[4*idx+1]) /
d;
197 const float b = input[4*idx+1] - a * input[4*idx+0];
209 const float *
const restrict ab,
210 const size_t num_elem)
213 for(
size_t k = 0;
k < num_elem;
k++)
216 image[
k] = fmaxf(image[
k] * ab[
k * 2] + ab[
k * 2 + 1],
MIN_FLOAT);
223 const float *
const restrict ab,
224 const size_t num_elem)
227 for(
size_t k = 0;
k < num_elem;
k++)
230 image[
k] = sqrtf(image[
k] * fmaxf(image[
k] * ab[
k * 2] + ab[
k * 2 + 1],
MIN_FLOAT));
236static inline void quantize(
const float *
const restrict image,
237 float *
const restrict
out,
238 const size_t num_elem,
239 const float sampling,
const float clip_min,
const float clip_max)
248 else if(sampling == 1.0f)
252 for(
size_t k = 0;
k < num_elem;
k++)
253 out[
k] =
fast_clamp(exp2f(floorf(log2f(image[
k]))), clip_min, clip_max);
260 for(
size_t k = 0;
k < num_elem;
k++)
261 out[
k] =
fast_clamp(exp2f(floorf(log2f(image[
k]) / sampling) * sampling), clip_min, clip_max);
269 const int radius,
float feathering,
const int iterations,
271 const float quantization,
const float quantize_min,
const float quantize_max)
278 const int ds_radius = (radius < 4) ? 1 : radius /
scaling;
283 const size_t num_elem_ds = ds_width * ds_height;
293 dt_control_log(_(
"fast guided filter failed to allocate memory, check your RAM settings"));
305 for(
int i = 0;
i < iterations; ++
i)
308 quantize(ds_image, ds_mask, ds_width * ds_height, quantization, quantize_min, quantize_max);
312 if(
variance_analyse(ds_mask, ds_image, ds_ab, ds_width, ds_height, ds_radius, feathering) != 0)
322 if(
dt_box_mean(ds_ab, ds_height, ds_width, 2, ds_radius, 1) != 0)
331 if(
i != iterations - 1)
int width
Definition bilateral.h:1
int height
Definition bilateral.h:1
int dt_box_mean(float *const buf, const size_t height, const size_t width, const int ch, const int radius, const unsigned iterations)
Definition box_filters.c:1047
static const float scaling
Definition chromatic_adaptation.h:293
const float i
Definition colorspaces_inline_conversions.h:440
const float d
Definition colorspaces_inline_conversions.h:680
const dt_colormatrix_t dt_aligned_pixel_t out
Definition colorspaces_inline_conversions.h:42
const float top
Definition colorspaces_inline_conversions.h:443
void dt_control_log(const char *msg,...)
Definition control.c:530
#define dt_pixelpipe_cache_alloc_align_float_cache(pixels, id)
Definition darktable.h:447
static size_t dt_round_size_sse(const size_t size)
Definition darktable.h:403
#define __OMP_DECLARE_SIMD__(...)
Definition darktable.h:263
#define dt_pixelpipe_cache_free_align(mem)
Definition darktable.h:453
#define __DT_CLONE_TARGETS__
Definition darktable.h:367
#define __OMP_PARALLEL_FOR__(...)
Definition darktable.h:258
static const dt_aligned_pixel_simd_t value
Definition darktable.h:577
#define __OMP_PARALLEL_FOR_SIMD__(...)
Definition darktable.h:259
#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
static __DT_CLONE_TARGETS__ int variance_analyse(const float *const restrict guide, const float *const restrict mask, float *const restrict ab, const size_t width, const size_t height, const int radius, const float feathering)
Definition fast_guided_filter.h:153
static __DT_CLONE_TARGETS__ int fast_surface_blur(float *const restrict image, const size_t width, const size_t height, const int radius, float feathering, const int iterations, const dt_iop_guided_filter_blending_t filter, const float scale, const float quantization, const float quantize_min, const float quantize_max)
Definition fast_guided_filter.h:267
dt_iop_guided_filter_blending_t
Definition fast_guided_filter.h:44
@ DT_GF_BLENDING_LINEAR
Definition fast_guided_filter.h:45
@ DT_GF_BLENDING_GEOMEAN
Definition fast_guided_filter.h:46
static __DT_CLONE_TARGETS__ void quantize(const float *const restrict image, float *const restrict out, const size_t num_elem, const float sampling, const float clip_min, const float clip_max)
Definition fast_guided_filter.h:236
#define MIN_FLOAT
Definition fast_guided_filter.h:40
static __DT_CLONE_TARGETS__ void apply_linear_blending_w_geomean(float *const restrict image, const float *const restrict ab, const size_t num_elem)
Definition fast_guided_filter.h:222
static __DT_CLONE_TARGETS__ void apply_linear_blending(float *const restrict image, const float *const restrict ab, const size_t num_elem)
Definition fast_guided_filter.h:208
static float fast_clamp(const float value, const float bottom, const float top)
Definition fast_guided_filter.h:86
static __DT_CLONE_TARGETS__ void interpolate_bilinear(const float *const restrict in, const size_t width_in, const size_t height_in, float *const restrict out, const size_t width_out, const size_t height_out, const size_t ch)
Definition fast_guided_filter.h:94
__DT_CLONE_TARGETS__ void dt_iop_image_copy(float *const __restrict__ out, const float *const __restrict__ in, const size_t nfloats)
Definition imagebuf.c:138
float *const restrict const size_t k
Definition luminance_mask.h:78
float *const restrict const size_t const size_t ch
Definition luminance_mask.h:78