Blender V4.5
vse_effect_blend.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2024 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
8
10
11#include "DNA_sequence_types.h"
12
13#include "IMB_imbuf.hh"
14
15#include "SEQ_render.hh"
16
17#include "effects.hh"
18
19namespace blender::seq {
20
21/* -------------------------------------------------------------------- */
22/* Alpha Over Effect */
23
25{
26 Strip *input1 = strip->input1;
27 Strip *input2 = strip->input2;
28
29 strip->input2 = input1;
30 strip->input1 = input2;
31}
32
33static bool alpha_opaque(uchar alpha)
34{
35 return alpha == 255;
36}
37
38static bool alpha_opaque(float alpha)
39{
40 return alpha >= 1.0f;
41}
42
43/* dst = src1 over src2 (alpha from src1) */
45 template<typename T> void apply(const T *src1, const T *src2, T *dst, int64_t size) const
46 {
47 const float fac = this->factor;
48 if (fac <= 0.0f) {
49 memcpy(dst, src2, sizeof(T) * 4 * size);
50 return;
51 }
52
53 for (int64_t idx = 0; idx < size; idx++) {
54 if (src1[3] <= 0.0f) {
55 /* Alpha of zero. No color addition will happen as the colors are pre-multiplied. */
56 memcpy(dst, src2, sizeof(T) * 4);
57 }
58 else if (fac == 1.0f && alpha_opaque(src1[3])) {
59 /* No change to `src1` as `fac == 1` and fully opaque. */
60 memcpy(dst, src1, sizeof(T) * 4);
61 }
62 else {
63 float4 col1 = load_premul_pixel(src1);
64 float mfac = 1.0f - fac * col1.w;
65 float4 col2 = load_premul_pixel(src2);
66 float4 col = fac * col1 + mfac * col2;
68 }
69 src1 += 4;
70 src2 += 4;
71 dst += 4;
72 }
73 }
74
75 float factor;
76};
77
78static ImBuf *do_alphaover_effect(const RenderData *context,
79 Strip * /*strip*/,
80 float /*timeline_frame*/,
81 float fac,
82 ImBuf *src1,
83 ImBuf *src2)
84{
85 ImBuf *dst = prepare_effect_imbufs(context, src1, src2);
87 op.factor = fac;
88 apply_effect_op(op, src1, src2, dst);
89 return dst;
90}
91
92/* -------------------------------------------------------------------- */
93/* Alpha Under Effect */
94
95/* dst = src1 under src2 (alpha from src2) */
97 template<typename T> void apply(const T *src1, const T *src2, T *dst, int64_t size) const
98 {
99 const float fac = this->factor;
100 if (fac <= 0.0f) {
101 memcpy(dst, src2, sizeof(T) * 4 * size);
102 return;
103 }
104
105 for (int64_t idx = 0; idx < size; idx++) {
106 if (src2[3] <= 0.0f && fac >= 1.0f) {
107 memcpy(dst, src1, sizeof(T) * 4);
108 }
109 else if (alpha_opaque(src2[3])) {
110 memcpy(dst, src2, sizeof(T) * 4);
111 }
112 else {
113 float4 col2 = load_premul_pixel(src2);
114 float mfac = fac * (1.0f - col2.w);
115 float4 col1 = load_premul_pixel(src1);
116 float4 col = mfac * col1 + col2;
118 }
119 src1 += 4;
120 src2 += 4;
121 dst += 4;
122 }
123 }
124 float factor;
125};
126
127static ImBuf *do_alphaunder_effect(const RenderData *context,
128 Strip * /*strip*/,
129 float /*timeline_frame*/,
130 float fac,
131 ImBuf *src1,
132 ImBuf *src2)
133{
134 ImBuf *dst = prepare_effect_imbufs(context, src1, src2);
136 op.factor = fac;
137 apply_effect_op(op, src1, src2, dst);
138 return dst;
139}
140
141/* -------------------------------------------------------------------- */
142/* Blend Mode Effect */
143
144/* blend_function has to be: void (T* dst, const T *src1, const T *src2) */
145template<typename T, typename Func>
147 float fac, int64_t size, const T *src1, const T *src2, T *dst, Func blend_function)
148{
149 for (int64_t i = 0; i < size; i++) {
150 T achannel = src2[3];
151 ((T *)src2)[3] = T(achannel * fac);
152 blend_function(dst, src1, src2);
153 ((T *)src2)[3] = achannel;
154 dst[3] = src1[3];
155 src1 += 4;
156 src2 += 4;
157 dst += 4;
158 }
159}
160
162 float fac, int64_t size, const float *rect1, const float *rect2, int btype, float *out)
163{
164 switch (btype) {
165 case STRIP_TYPE_ADD:
167 break;
168 case STRIP_TYPE_SUB:
170 break;
171 case STRIP_TYPE_MUL:
173 break;
176 break;
179 break;
182 break;
185 break;
188 break;
189 case STRIP_TYPE_DODGE:
191 break;
194 break;
197 break;
200 break;
203 break;
206 break;
209 break;
212 break;
213 case STRIP_TYPE_HUE:
215 break;
218 break;
219 case STRIP_TYPE_VALUE:
221 break;
224 break;
227 break;
228 default:
229 break;
230 }
231}
232
234 float fac, int64_t size, const uchar *rect1, const uchar *rect2, int btype, uchar *out)
235{
236 switch (btype) {
237 case STRIP_TYPE_ADD:
239 break;
240 case STRIP_TYPE_SUB:
242 break;
243 case STRIP_TYPE_MUL:
245 break;
248 break;
251 break;
254 break;
257 break;
260 break;
261 case STRIP_TYPE_DODGE:
263 break;
266 break;
269 break;
272 break;
275 break;
278 break;
281 break;
284 break;
285 case STRIP_TYPE_HUE:
287 break;
290 break;
291 case STRIP_TYPE_VALUE:
293 break;
296 break;
299 break;
300 default:
301 break;
302 }
303}
304
306 template<typename T> void apply(const T *src1, const T *src2, T *dst, int64_t size) const
307 {
308 if constexpr (std::is_same_v<T, float>) {
309 do_blend_effect_float(this->factor, size, src1, src2, this->blend_mode, dst);
310 }
311 else {
312 do_blend_effect_byte(this->factor, size, src1, src2, this->blend_mode, dst);
313 }
314 }
315 int blend_mode; /* STRIP_TYPE_ */
316 float factor;
317};
318
319static ImBuf *do_blend_mode_effect(const RenderData *context,
320 Strip *strip,
321 float /*timeline_frame*/,
322 float fac,
323 ImBuf *src1,
324 ImBuf *src2)
325{
326 ImBuf *dst = prepare_effect_imbufs(context, src1, src2);
328 op.factor = fac;
329 op.blend_mode = strip->blend_mode;
330 apply_effect_op(op, src1, src2, dst);
331 return dst;
332}
333
334/* -------------------------------------------------------------------- */
335/* Color Mix Effect */
336
337static void init_colormix_effect(Strip *strip)
338{
339 if (strip->effectdata) {
340 MEM_freeN(strip->effectdata);
341 }
342
344 strip->effectdata = data;
345
346 data->blend_effect = STRIP_TYPE_OVERLAY;
347 data->factor = 1.0f;
348}
349
350static ImBuf *do_colormix_effect(const RenderData *context,
351 Strip *strip,
352 float /*timeline_frame*/,
353 float /*fac*/,
354 ImBuf *src1,
355 ImBuf *src2)
356{
357 ImBuf *dst = prepare_effect_imbufs(context, src1, src2);
358 const ColorMixVars *data = static_cast<const ColorMixVars *>(strip->effectdata);
360 op.blend_mode = data->blend_effect;
361 op.factor = data->factor;
362 apply_effect_op(op, src1, src2, dst);
363 return dst;
364}
365
366static void copy_effect_default(Strip *dst, const Strip *src, const int /*flag*/)
367{
369}
370
371static void free_effect_default(Strip *strip, const bool /*do_id_user*/)
372{
374}
375
381
390
397
403
404} // namespace blender::seq
MINLINE void blend_color_add_float(float dst[4], const float src1[4], const float src2[4])
MINLINE void blend_color_exclusion_float(float dst[4], const float src1[4], const float src2[4])
MINLINE void blend_color_linearburn_byte(unsigned char dst[4], const uchar src1[4], const uchar src2[4])
MINLINE void blend_color_overlay_float(float dst[4], const float src1[4], const float src2[4])
MINLINE void blend_color_saturation_byte(unsigned char dst[4], const uchar src1[4], const uchar src2[4])
MINLINE void blend_color_burn_float(float dst[4], const float src1[4], const float src2[4])
MINLINE void blend_color_color_float(float dst[4], const float src1[4], const float src2[4])
MINLINE void blend_color_linearlight_float(float dst[4], const float src1[4], const float src2[4])
MINLINE void blend_color_sub_byte(unsigned char dst[4], const unsigned char src1[4], const unsigned char src2[4])
MINLINE void blend_color_saturation_float(float dst[4], const float src1[4], const float src2[4])
MINLINE void blend_color_hue_float(float dst[4], const float src1[4], const float src2[4])
MINLINE void blend_color_difference_float(float dst[4], const float src1[4], const float src2[4])
MINLINE void blend_color_dodge_float(float dst[4], const float src1[4], const float src2[4])
MINLINE void blend_color_luminosity_byte(unsigned char dst[4], const uchar src1[4], const uchar src2[4])
MINLINE void blend_color_pinlight_float(float dst[4], const float src1[4], const float src2[4])
MINLINE void blend_color_mul_float(float dst[4], const float src1[4], const float src2[4])
MINLINE void blend_color_pinlight_byte(unsigned char dst[4], const uchar src1[4], const uchar src2[4])
MINLINE void blend_color_screen_float(float dst[4], const float src1[4], const float src2[4])
MINLINE void blend_color_screen_byte(unsigned char dst[4], const uchar src1[4], const uchar src2[4])
MINLINE void blend_color_vividlight_byte(unsigned char dst[4], const uchar src1[4], const uchar src2[4])
MINLINE void blend_color_linearburn_float(float dst[4], const float src1[4], const float src2[4])
MINLINE void blend_color_mul_byte(unsigned char dst[4], const unsigned char src1[4], const unsigned char src2[4])
MINLINE void blend_color_vividlight_float(float dst[4], const float src1[4], const float src2[4])
MINLINE void blend_color_darken_byte(unsigned char dst[4], const unsigned char src1[4], const unsigned char src2[4])
MINLINE void blend_color_luminosity_float(float dst[4], const float src1[4], const float src2[4])
MINLINE void blend_color_difference_byte(unsigned char dst[4], const uchar src1[4], const uchar src2[4])
MINLINE void blend_color_burn_byte(unsigned char dst[4], const uchar src1[4], const uchar src2[4])
MINLINE void blend_color_color_byte(unsigned char dst[4], const uchar src1[4], const uchar src2[4])
MINLINE void blend_color_overlay_byte(unsigned char dst[4], const uchar src1[4], const uchar src2[4])
MINLINE void blend_color_dodge_byte(unsigned char dst[4], const uchar src1[4], const uchar src2[4])
MINLINE void blend_color_hardlight_byte(unsigned char dst[4], const uchar src1[4], const uchar src2[4])
MINLINE void blend_color_sub_float(float dst[4], const float src1[4], const float src2[4])
MINLINE void blend_color_darken_float(float dst[4], const float src1[4], const float src2[4])
MINLINE void blend_color_softlight_byte(unsigned char dst[4], const uchar src1[4], const uchar src2[4])
MINLINE void blend_color_add_byte(unsigned char dst[4], const unsigned char src1[4], const unsigned char src2[4])
MINLINE void blend_color_hue_byte(unsigned char dst[4], const uchar src1[4], const uchar src2[4])
MINLINE void blend_color_lighten_byte(unsigned char dst[4], const unsigned char src1[4], const unsigned char src2[4])
MINLINE void blend_color_exclusion_byte(unsigned char dst[4], const uchar src1[4], const uchar src2[4])
MINLINE void blend_color_hardlight_float(float dst[4], const float src1[4], const float src2[4])
MINLINE void blend_color_linearlight_byte(unsigned char dst[4], const uchar src1[4], const uchar src2[4])
MINLINE void blend_color_lighten_float(float dst[4], const float src1[4], const float src2[4])
MINLINE void blend_color_softlight_float(float dst[4], const float src1[4], const float src2[4])
unsigned char uchar
@ STRIP_TYPE_SCREEN
@ STRIP_TYPE_EXCLUSION
@ STRIP_TYPE_LIN_LIGHT
@ STRIP_TYPE_OVERLAY
@ STRIP_TYPE_DARKEN
@ STRIP_TYPE_HARD_LIGHT
@ STRIP_TYPE_ADD
@ STRIP_TYPE_COLOR_BURN
@ STRIP_TYPE_HUE
@ STRIP_TYPE_LIGHTEN
@ STRIP_TYPE_BLEND_COLOR
@ STRIP_TYPE_DODGE
@ STRIP_TYPE_SUB
@ STRIP_TYPE_MUL
@ STRIP_TYPE_VALUE
@ STRIP_TYPE_SOFT_LIGHT
@ STRIP_TYPE_LINEAR_BURN
@ STRIP_TYPE_SATURATION
@ STRIP_TYPE_PIN_LIGHT
@ STRIP_TYPE_DIFFERENCE
@ STRIP_TYPE_VIVID_LIGHT
BMesh const char void * data
long long int int64_t
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition btDbvt.cpp:52
uint col
#define out
#define MEM_SAFE_FREE(v)
void * MEM_callocN(size_t len, const char *str)
Definition mallocn.cc:118
void * MEM_dupallocN(const void *vmemh)
Definition mallocn.cc:143
void MEM_freeN(void *vmemh)
Definition mallocn.cc:113
#define T
static void copy_effect_default(Strip *dst, const Strip *src, const int)
static ImBuf * do_colormix_effect(const RenderData *context, Strip *strip, float, float, ImBuf *src1, ImBuf *src2)
void alpha_under_effect_get_handle(EffectHandle &rval)
StripEarlyOut early_out_mul_input2(const Strip *, float fac)
Definition effects.cc:128
static bool alpha_opaque(uchar alpha)
void store_premul_pixel(const blender::float4 &pix, uchar *dst)
Definition effects.hh:57
ImBuf * prepare_effect_imbufs(const RenderData *context, ImBuf *ibuf1, ImBuf *ibuf2, bool uninitialized_pixels)
Definition effects.cc:28
void blend_mode_effect_get_handle(EffectHandle &rval)
static ImBuf * do_blend_mode_effect(const RenderData *context, Strip *strip, float, float fac, ImBuf *src1, ImBuf *src2)
static ImBuf * do_alphaunder_effect(const RenderData *context, Strip *, float, float fac, ImBuf *src1, ImBuf *src2)
blender::float4 load_premul_pixel(const uchar *ptr)
Definition effects.hh:45
static void init_colormix_effect(Strip *strip)
StripEarlyOut early_out_mul_input1(const Strip *, float fac)
Definition effects.cc:136
static void init_alpha_over_or_under(Strip *strip)
static void free_effect_default(Strip *strip, const bool)
static void do_blend_effect_float(float fac, int64_t size, const float *rect1, const float *rect2, int btype, float *out)
static void apply_effect_op(const OpT &op, const ImBuf *src1, const ImBuf *src2, ImBuf *dst)
Definition effects.hh:121
static ImBuf * do_alphaover_effect(const RenderData *context, Strip *, float, float fac, ImBuf *src1, ImBuf *src2)
void color_mix_effect_get_handle(EffectHandle &rval)
static void apply_blend_function(float fac, int64_t size, const T *src1, const T *src2, T *dst, Func blend_function)
void alpha_over_effect_get_handle(EffectHandle &rval)
static void do_blend_effect_byte(float fac, int64_t size, const uchar *rect1, const uchar *rect2, int btype, uchar *out)
VecBase< float, 4 > float4
struct Strip * input1
void * effectdata
struct Strip * input2
void apply(const T *src1, const T *src2, T *dst, int64_t size) const
void apply(const T *src1, const T *src2, T *dst, int64_t size) const
void apply(const T *src1, const T *src2, T *dst, int64_t size) const
void(* copy)(Strip *dst, const Strip *src, int flag)
ImBuf *(* execute)(const RenderData *context, Strip *strip, float timeline_frame, float fac, ImBuf *ibuf1, ImBuf *ibuf2)
void(* free)(Strip *strip, bool do_id_user)
StripEarlyOut(* early_out)(const Strip *strip, float fac)
void(* init)(Strip *strip)
i
Definition text_draw.cc:230