33 float *
const restrict
out,
const float *
const restrict mask,
const size_t stride);
37 const float *
const restrict b,
float *
const restrict mask)
44 const int owidth = roi_out->
width;
45 const int oheight = roi_out->
height;
46 const size_t buffsize = (size_t)owidth * oheight;
49 const float global_opacity = fminf(fmaxf(0.0f, (
d->opacity / 100.0f)), 1.0f);
55 for(
size_t x = 0;
x < buffsize;
x++) mask[
x] = global_opacity * (1.0f - mask[
x]);
66static
void _blend_normal_bounded(const float *const restrict a, const float *const restrict b,
67 float *const restrict
out, const float *const restrict mask, const size_t stride)
69 for(
size_t j = 0; j < stride; j++)
71 const float local_opacity = mask[j];
72 out[j] =
clamp_simd(a[j] * (1.0f - local_opacity) + b[j] * local_opacity);
78static
void _blend_normal_unbounded(const float *const restrict a, const float *const restrict
b,
79 float *const restrict
out, const float *const restrict
mask,
82 for(
size_t j = 0; j < stride; j++)
84 const float local_opacity =
mask[j];
85 out[j] = a[j] * (1.0f - local_opacity) + b[j] * local_opacity;
91static
void _blend_lighten(const float *const restrict a, const float *const restrict
b,
92 float *const restrict
out, const float *const restrict
mask, const size_t stride)
94 for(
size_t j = 0; j < stride; j++)
96 const float local_opacity =
mask[j];
97 out[j] =
clamp_simd(a[j] * (1.0f - local_opacity) + fmaxf(a[j], b[j]) * local_opacity);
103static
void _blend_darken(const float *const restrict a, const float *const restrict
b,
104 float *const restrict
out, const float *const restrict
mask, const size_t stride)
106 for(
size_t j = 0; j < stride; j++)
108 const float local_opacity =
mask[j];
109 out[j] =
clamp_simd(a[j] * (1.0f - local_opacity) + fminf(a[j], b[j]) * local_opacity);
115static
void _blend_multiply(const float *const restrict a, const float *const restrict
b,
116 float *const restrict
out, const float *const restrict
mask, const size_t stride)
118 for(
size_t j = 0; j < stride; j++)
120 const float local_opacity =
mask[j];
121 out[j] =
clamp_simd(a[j] * (1.0f - local_opacity) + (a[j] * b[j]) * local_opacity);
127static
void _blend_average(const float *const restrict a, const float *const restrict
b,
128 float *const restrict
out, const float *const restrict
mask, const size_t stride)
130 for(
size_t j = 0; j < stride; j++)
132 const float local_opacity =
mask[j];
133 out[j] =
clamp_simd(a[j] * (1.0f - local_opacity) + (a[j] + b[j]) / 2.0f * local_opacity);
139static
void _blend_add(const float *const restrict a, const float *const restrict
b,
140 float *const restrict
out, const float *const restrict
mask, const size_t stride)
142 for(
size_t j = 0; j < stride; j++)
144 const float local_opacity =
mask[j];
145 out[j] =
clamp_simd(a[j] * (1.0f - local_opacity) + (a[j] + b[j]) * local_opacity);
151static
void _blend_subtract(const float *const restrict a, const float *const restrict
b,
152 float *const restrict
out, const float *const restrict
mask, const size_t stride)
154 for(
size_t j = 0; j < stride; j++)
156 const float local_opacity =
mask[j];
157 out[j] =
clamp_simd(a[j] * (1.0f - local_opacity) + ((b[j] + a[j]) - 1.0f) * local_opacity);
163static
void _blend_difference(const float *const restrict a, const float *const restrict
b,
164 float *const restrict
out, const float *const restrict
mask, const size_t stride)
166 for(
size_t j = 0; j < stride; j++)
168 const float local_opacity =
mask[j];
169 out[j] =
clamp_simd(a[j] * (1.0f - local_opacity) + fabsf(a[j] - b[j]) * local_opacity);
175static
void _blend_screen(const float *const restrict a, const float *const restrict
b,
176 float *const restrict
out, const float *const restrict
mask, const size_t stride)
178 for(
size_t j = 0; j < stride; j++)
180 const float local_opacity =
mask[j];
183 out[j] =
clamp_simd(la * (1.0f - local_opacity) + (1.0f - (1.0f - la) * (1.0f - lb)) * local_opacity);
189static
void _blend_overlay(const float *const restrict a, const float *const restrict
b,
190 float *const restrict
out, const float *const restrict
mask, const size_t stride)
192 for(
size_t j = 0; j < stride; j++)
194 const float local_opacity =
mask[j];
195 const float local_opacity2 = local_opacity * local_opacity;
199 la * (1.0f - local_opacity2)
200 + (la > 0.5f ? 1.0f - (1.0f - 2.0f * (la - 0.5f)) * (1.0f - lb) : 2.0f * la * lb) * local_opacity2);
206static
void _blend_softlight(const float *const restrict a, const float *const restrict
b,
207 float *const restrict
out, const float *const restrict
mask, const size_t stride)
209 for(
size_t j = 0; j < stride; j++)
211 const float local_opacity =
mask[j];
212 const float local_opacity2 = local_opacity * local_opacity;
216 la * (1.0f - local_opacity2)
217 + (lb > 0.5f ? 1.0f - (1.0f - la) * (1.0f - (lb - 0.5f)) : la * (lb + 0.5f)) * local_opacity2);
223static
void _blend_hardlight(const float *const restrict a, const float *const restrict
b,
224 float *const restrict
out, const float *const restrict
mask, const size_t stride)
226 for(
size_t j = 0; j < stride; j++)
228 const float local_opacity =
mask[j];
229 const float local_opacity2 = local_opacity * local_opacity;
233 la * (1.0f - local_opacity2)
234 + (lb > 0.5f ? 1.0f - (1.0f - 2.0f * (la - 0.5f)) * (1.0f - lb) : 2.0f * la * lb) * local_opacity2);
240static
void _blend_vividlight(const float *const restrict a, const float *const restrict
b,
241 float *const restrict
out, const float *const restrict
mask, const size_t stride)
243 for(
size_t j = 0; j < stride; j++)
245 const float local_opacity =
mask[j];
246 const float local_opacity2 = local_opacity * local_opacity;
250 la * (1.0f - local_opacity2)
251 + (lb > 0.5f ? (lb >= 1.0f ? 1.0f : la / (2.0f * (1.0f - lb)))
252 : (lb <= 0.0f ? 0.0f : 1.0f - (1.0f - la) / (2.0f * lb)))
259static
void _blend_linearlight(const float *const restrict a, const float *const restrict
b,
260 float *const restrict
out, const float *const restrict
mask, const size_t stride)
262 for(
size_t j = 0; j < stride; j++)
264 const float local_opacity =
mask[j];
265 const float local_opacity2 = local_opacity * local_opacity;
268 out[j] =
clamp_simd(la * (1.0f - local_opacity2) + (la + 2.0f * lb - 1.0f) * local_opacity2);
274static
void _blend_pinlight(const float *const restrict a, const float *const restrict
b,
275 float *const restrict
out, const float *const restrict
mask, const size_t stride)
277 for(
size_t j = 0; j < stride; j++)
279 const float local_opacity =
mask[j];
280 const float local_opacity2 = local_opacity * local_opacity;
284 la * (1.0f - local_opacity2)
285 + (lb > 0.5f ? fmaxf(la, 2.0f * (lb - 0.5f)) : fminf(la, 2.0f * lb)) * local_opacity2);
298 blend = _blend_lighten;
301 blend = _blend_darken;
304 blend = _blend_multiply;
307 blend = _blend_average;
313 blend = _blend_subtract;
317 blend = _blend_difference;
320 blend = _blend_screen;
323 blend = _blend_overlay;
326 blend = _blend_softlight;
329 blend = _blend_hardlight;
332 blend = _blend_vividlight;
335 blend = _blend_linearlight;
338 blend = _blend_pinlight;
341 blend = _blend_normal_bounded;
347 blend = _blend_normal_unbounded;
357 const float *
const restrict a,
float *
const restrict b,
358 const float *
const restrict mask,
368 const int xoffs = roi_out->
x - roi_in->
x;
369 const int yoffs = roi_out->
y - roi_in->
y;
370 const int iwidth = roi_in->
width;
371 const int owidth = roi_out->
width;
372 const int oheight = roi_out->
height;
389 for(
size_t y = 0; y < oheight; y++)
391 const size_t a_start = (y + yoffs) * iwidth + xoffs;
392 const size_t bm_start = y * owidth;
393 blend(tmp_buffer + bm_start, a + a_start, b + bm_start, mask + bm_start, owidth);
399 for(
size_t y = 0; y < oheight; y++)
401 const size_t a_start = (y + yoffs) * iwidth + xoffs;
402 const size_t bm_start = y * owidth;
403 blend(a + a_start, tmp_buffer + bm_start, b + bm_start, mask + bm_start, owidth);
@ DEVELOP_BLEND_DIFFERENCE
@ DEVELOP_BLEND_MODE_MASK
@ DEVELOP_BLEND_HARDLIGHT
@ DEVELOP_BLEND_LINEARLIGHT
@ DEVELOP_BLEND_VIVIDLIGHT
@ DEVELOP_BLEND_SOFTLIGHT
@ DEVELOP_BLEND_DIFFERENCE2
static _blend_row_func * _choose_blend_func(const unsigned int blend_mode)
void dt_develop_blendif_raw_blend(const struct dt_dev_pixelpipe_t *pipe, const struct dt_dev_pixelpipe_iop_t *piece, const float *const restrict a, float *const restrict b, const float *const restrict mask, const dt_dev_pixelpipe_display_mask_t request_mask_display)
void() _blend_row_func(const float *const restrict a, const float *const restrict b, float *const restrict out, const float *const restrict mask, const size_t stride)
void dt_develop_blendif_raw_make_mask(const struct dt_dev_pixelpipe_iop_t *piece, const float *const restrict a, const float *const restrict b, float *const restrict mask)
const dt_colormatrix_t dt_aligned_pixel_t out
typedef void((*dt_cache_allocate_t)(void *userdata, dt_cache_entry_t *entry))
#define dt_pixelpipe_cache_alloc_align_float_cache(pixels, id)
#define __OMP_DECLARE_SIMD__(...)
#define dt_pixelpipe_cache_free_align(mem)
#define __OMP_PARALLEL_FOR__(...)
#define __OMP_FOR_SIMD__(...)
#define IS_NULL_PTR(p)
C is way too permissive with !=, == and if(var) checks, which can mean too many things depending on w...
dt_dev_pixelpipe_display_mask_t
@ DT_DEV_PIXELPIPE_DISPLAY_ANY
__DT_CLONE_TARGETS__ void dt_iop_image_mul_const(float *const buf, const float mul_value, const size_t width, const size_t height, const size_t ch)
__DT_CLONE_TARGETS__ void dt_iop_image_copy(float *const __restrict__ out, const float *const __restrict__ in, const size_t nfloats)
__DT_CLONE_TARGETS__ void dt_iop_image_fill(float *const buf, const float fill_value, const size_t width, const size_t height, const size_t ch)
static float clamp_simd(const float x)
dt_iop_buffer_dsc_t dsc_in
Region of interest passed through the pixelpipe.