37 float vmax[4] = { 1e9f, 1e9f, 1e9f, 1e9f };
38 float vmin[4] = { -1e9f, -1e9f, -1e9f, -1e9f };
69 const float vmax[4] = { 1e9f, 1e9f, 1e9f, 1e9f };
70 const float vmin[4] = { -1e9f, -1e9f, -1e9f, -1e9f };
74cl_int
_region_blur_cl(
const int devid, cl_mem in, cl_mem
out,
const int region_w,
const int region_h,
104 const float *
const restrict guide,
float *
const restrict step_x,
105 float *
const restrict step_y,
const int region_w,
const int region_h,
108 const size_t region_pixels = (size_t)region_w * region_h;
109 memcpy(
out, in, region_pixels * 4 *
sizeof(
float));
115 for(
int y = 0; y < region_h; y++)
116 for(
int x = 0;
x < region_w;
x++)
118 const size_t i = (size_t)y * region_w +
x;
119 const float dx = (
x > 0) ? fabsf(guide[
i] - guide[
i - 1]) : 0.f;
120 const float dy = (y > 0) ? fabsf(guide[
i] - guide[
i - region_w]) : 0.f;
121 step_x[
i] = 1.f + range_scale * dx;
122 step_y[
i] = 1.f + range_scale * dy;
125 const int n_iterations = 3;
126 for(
int iteration = 0; iteration < n_iterations; iteration++)
129 const float sigma_i =
sigma_s * sqrtf(3.f) * (float)(1 << (n_iterations - 1 - iteration))
130 / sqrtf((
float)((1 << (2 * n_iterations)) - 1));
131 const float feedback = expf(-sqrtf(2.f) / fmaxf(sigma_i, 1e-6f));
134 for(
int y = 0; y < region_h; y++)
136 float *
const restrict
row =
out + (size_t)y * region_w * 4;
137 const float *
const restrict step = step_x + (size_t)y * region_w;
138 for(
int x = 1;
x < region_w;
x++)
140 const float a = powf(feedback, step[
x]);
141 for(
int c = 0; c < 4; c++)
row[
x * 4 + c] += a * (
row[(
x - 1) * 4 + c] -
row[
x * 4 + c]);
143 for(
int x = region_w - 2;
x >= 0;
x--)
145 const float a = powf(feedback, step[
x + 1]);
146 for(
int c = 0; c < 4; c++)
row[
x * 4 + c] += a * (
row[(
x + 1) * 4 + c] -
row[
x * 4 + c]);
151 for(
int x = 0;
x < region_w;
x++)
153 for(
int y = 1; y < region_h; y++)
155 const size_t i = (size_t)y * region_w +
x;
156 const float a = powf(feedback, step_y[
i]);
157 for(
int c = 0; c < 4; c++)
158 out[
i * 4 + c] += a * (
out[(
i - region_w) * 4 + c] -
out[
i * 4 + c]);
160 for(
int y = region_h - 2; y >= 0; y--)
162 const size_t i = (size_t)y * region_w +
x;
163 const float a = powf(feedback, step_y[
i + region_w]);
164 for(
int c = 0; c < 4; c++)
165 out[
i * 4 + c] += a * (
out[(
i + region_w) * 4 + c] -
out[
i * 4 + c]);
178 cl_mem guide, cl_mem data, cl_mem step_x, cl_mem step_y,
const int region_w,
182 const size_t origin[] = { 0, 0, 0 };
183 const size_t region[] = { (size_t)region_w, (
size_t)region_h, 1 };
187 (
size_t *)region, 0);
188 if(cl_err != CL_SUCCESS)
return cl_err;
203 if(cl_err != CL_SUCCESS)
return cl_err;
206 const int n_iterations = 3;
207 for(
int iteration = 0; iteration < n_iterations && cl_err == CL_SUCCESS; iteration++)
209 const float sigma_i =
sigma_s * sqrtf(3.f) * (float)(1 << (n_iterations - 1 - iteration))
210 / sqrtf((
float)((1 << (2 * n_iterations)) - 1));
211 const float feedback = expf(-sqrtf(2.f) / fmaxf(sigma_i, 1e-6f));
215 size_t size_rows[3] = {
ROUNDUP(region_h, 64), 1, 1 };
223 if(cl_err != CL_SUCCESS)
break;
226 size_t size_cols[3] = {
ROUNDUP(region_w, 64), 1, 1 };
235 if(cl_err != CL_SUCCESS)
return cl_err;
void _region_edge_blur(const float *const restrict in, float *const restrict out, const float *const restrict guide, float *const restrict step_x, float *const restrict step_y, const int region_w, const int region_h, const float sigma_s, const float sigma_r)
static __thread _hl_gauss_slot_t _hl_gauss_cache[HL_GAUSS_SLOTS]
cl_int _region_edge_blur_cl(const int devid, void *gd_void, cl_mem in_image, cl_mem out_image, cl_mem guide, cl_mem data, cl_mem step_x, cl_mem step_y, const int region_w, const int region_h, const float sigma_s, const float sigma_r)
dt_gaussian_t * _hl_gauss_get(const int width, const int height, const int channels, const float sigma)
static __thread int _hl_gauss_rr
void _hl_gauss_cache_flush(void)
cl_int _region_blur_cl(const int devid, cl_mem in, cl_mem out, const int region_w, const int region_h, const float sigma)
dt_gaussian_cl_t * _region_blur_handle(const int devid, const int region_w, const int region_h, const float sigma)
const dt_colormatrix_t dt_aligned_pixel_t out
static float gaussian(float x, float std)
void dt_gaussian_free(dt_gaussian_t *g)
void dt_gaussian_free_cl(dt_gaussian_cl_t *g)
cl_int dt_gaussian_blur_cl(dt_gaussian_cl_t *g, cl_mem dev_in, cl_mem dev_out)
dt_gaussian_cl_t * dt_gaussian_init_cl(const int devid, const int width, const int height, const int channels, const float *max, const float *min, const float sigma, const int order)
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)
static float kernel(const float *x, const float *y)
int dt_opencl_enqueue_kernel_2d(const int dev, const int kernel, const size_t *sizes)
int dt_opencl_enqueue_copy_buffer_to_image(const int devid, cl_mem src_buffer, cl_mem dst_image, size_t offset, size_t *origin, size_t *region)
int dt_opencl_set_kernel_arg(const int dev, const int kernel, const int num, const size_t size, const void *arg)
int dt_opencl_enqueue_copy_image_to_buffer(const int devid, cl_mem src_image, cl_mem dst_buffer, size_t *origin, size_t *region, size_t offset)
#define DT_OPENCL_DEFAULT_ERROR