Blender V5.0
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 SeqRenderState * /*state*/,
80 Strip * /*strip*/,
81 float /*timeline_frame*/,
82 float fac,
83 ImBuf *src1,
84 ImBuf *src2)
85{
86 ImBuf *dst = prepare_effect_imbufs(context, src1, src2);
88 op.factor = fac;
89 apply_effect_op(op, src1, src2, dst);
90 return dst;
91}
92
93/* -------------------------------------------------------------------- */
94/* Alpha Under Effect */
95
96/* dst = src1 under src2 (alpha from src2) */
98 template<typename T> void apply(const T *src1, const T *src2, T *dst, int64_t size) const
99 {
100 const float fac = this->factor;
101 if (fac <= 0.0f) {
102 memcpy(dst, src2, sizeof(T) * 4 * size);
103 return;
104 }
105
106 for (int64_t idx = 0; idx < size; idx++) {
107 if (src2[3] <= 0.0f && fac >= 1.0f) {
108 memcpy(dst, src1, sizeof(T) * 4);
109 }
110 else if (alpha_opaque(src2[3])) {
111 memcpy(dst, src2, sizeof(T) * 4);
112 }
113 else {
114 float4 col2 = load_premul_pixel(src2);
115 float mfac = fac * (1.0f - col2.w);
116 float4 col1 = load_premul_pixel(src1);
117 float4 col = mfac * col1 + col2;
119 }
120 src1 += 4;
121 src2 += 4;
122 dst += 4;
123 }
124 }
125 float factor;
126};
127
128static ImBuf *do_alphaunder_effect(const RenderData *context,
129 SeqRenderState * /*state*/,
130 Strip * /*strip*/,
131 float /*timeline_frame*/,
132 float fac,
133 ImBuf *src1,
134 ImBuf *src2)
135{
136 ImBuf *dst = prepare_effect_imbufs(context, src1, src2);
138 op.factor = fac;
139 apply_effect_op(op, src1, src2, dst);
140 return dst;
141}
142
143/* -------------------------------------------------------------------- */
144/* Blend Mode Effect */
145
146/* blend_function has to be: void (T* dst, const T *src1, const T *src2) */
147template<typename T, typename Func>
149 float fac, int64_t size, const T *src1, const T *src2, T *dst, Func blend_function)
150{
151 for (int64_t i = 0; i < size; i++) {
152 T achannel = src2[3];
153 ((T *)src2)[3] = T(achannel * fac);
154 blend_function(dst, src1, src2);
155 ((T *)src2)[3] = achannel;
156 dst[3] = src1[3];
157 src1 += 4;
158 src2 += 4;
159 dst += 4;
160 }
161}
162
163static void do_blend_effect_float(float fac,
165 const float *rect1,
166 const float *rect2,
167 StripBlendMode btype,
168 float *out)
169{
170 switch (btype) {
171 case STRIP_BLEND_ADD:
173 break;
174 case STRIP_BLEND_SUB:
176 break;
177 case STRIP_BLEND_MUL:
179 break;
182 break;
185 break;
188 break;
191 break;
194 break;
197 break;
200 break;
203 break;
206 break;
209 break;
212 break;
215 break;
218 break;
219 case STRIP_BLEND_HUE:
221 break;
224 break;
227 break;
230 break;
233 break;
234 default:
235 break;
236 }
237}
238
239static void do_blend_effect_byte(float fac,
241 const uchar *rect1,
242 const uchar *rect2,
243 StripBlendMode btype,
244 uchar *out)
245{
246 switch (btype) {
247 case STRIP_BLEND_ADD:
249 break;
250 case STRIP_BLEND_SUB:
252 break;
253 case STRIP_BLEND_MUL:
255 break;
258 break;
261 break;
264 break;
267 break;
270 break;
273 break;
276 break;
279 break;
282 break;
285 break;
288 break;
291 break;
294 break;
295 case STRIP_BLEND_HUE:
297 break;
300 break;
303 break;
306 break;
309 break;
310 default:
311 break;
312 }
313}
314
316 template<typename T> void apply(const T *src1, const T *src2, T *dst, int64_t size) const
317 {
318 if constexpr (std::is_same_v<T, float>) {
319 do_blend_effect_float(this->factor, size, src1, src2, this->blend_mode, dst);
320 }
321 else {
322 do_blend_effect_byte(this->factor, size, src1, src2, this->blend_mode, dst);
323 }
324 }
326 float factor;
327};
328
329static ImBuf *do_blend_mode_effect(const RenderData *context,
330 SeqRenderState * /*state*/,
331 Strip *strip,
332 float /*timeline_frame*/,
333 float fac,
334 ImBuf *src1,
335 ImBuf *src2)
336{
337 ImBuf *dst = prepare_effect_imbufs(context, src1, src2);
339 op.factor = fac;
341 apply_effect_op(op, src1, src2, dst);
342 return dst;
343}
344
345/* -------------------------------------------------------------------- */
346/* Color Mix Effect */
347
348static void init_colormix_effect(Strip *strip)
349{
350 if (strip->effectdata) {
351 MEM_freeN(strip->effectdata);
352 }
353
355 strip->effectdata = data;
356
357 data->blend_effect = STRIP_BLEND_OVERLAY;
358 data->factor = 1.0f;
359}
360
361static ImBuf *do_colormix_effect(const RenderData *context,
362 SeqRenderState * /*state*/,
363 Strip *strip,
364 float /*timeline_frame*/,
365 float /*fac*/,
366 ImBuf *src1,
367 ImBuf *src2)
368{
369 ImBuf *dst = prepare_effect_imbufs(context, src1, src2);
370 const ColorMixVars *data = static_cast<const ColorMixVars *>(strip->effectdata);
372 op.blend_mode = StripBlendMode(data->blend_effect);
373 op.factor = data->factor;
374 apply_effect_op(op, src1, src2, dst);
375 return dst;
376}
377
378static void copy_effect_default(Strip *dst, const Strip *src, const int /*flag*/)
379{
381}
382
383static void free_effect_default(Strip *strip, const bool /*do_id_user*/)
384{
386}
387
393
402
409
415
416} // 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_BLEND_LINEAR_BURN
@ STRIP_BLEND_SUB
@ STRIP_BLEND_VIVID_LIGHT
@ STRIP_BLEND_LIGHTEN
@ STRIP_BLEND_OVERLAY
@ STRIP_BLEND_SATURATION
@ STRIP_BLEND_SOFT_LIGHT
@ STRIP_BLEND_EXCLUSION
@ STRIP_BLEND_COLOR_BURN
@ STRIP_BLEND_HUE
@ STRIP_BLEND_DODGE
@ STRIP_BLEND_LIN_LIGHT
@ STRIP_BLEND_PIN_LIGHT
@ STRIP_BLEND_ADD
@ STRIP_BLEND_DIFFERENCE
@ STRIP_BLEND_HARD_LIGHT
@ STRIP_BLEND_MUL
@ STRIP_BLEND_BLEND_COLOR
@ STRIP_BLEND_DARKEN
@ STRIP_BLEND_VALUE
@ STRIP_BLEND_SCREEN
#define MEM_SAFE_FREE(v)
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
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)
void alpha_under_effect_get_handle(EffectHandle &rval)
static ImBuf * do_alphaunder_effect(const RenderData *context, SeqRenderState *, Strip *, float, float fac, ImBuf *src1, ImBuf *src2)
StripEarlyOut early_out_mul_input2(const Strip *, float fac)
Definition effects.cc:128
static void do_blend_effect_float(float fac, int64_t size, const float *rect1, const float *rect2, StripBlendMode btype, float *out)
static bool alpha_opaque(uchar alpha)
void store_premul_pixel(const blender::float4 &pix, uchar *dst)
Definition effects.hh:60
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, SeqRenderState *, Strip *strip, float, float fac, ImBuf *src1, ImBuf *src2)
blender::float4 load_premul_pixel(const uchar *ptr)
Definition effects.hh:48
static void init_colormix_effect(Strip *strip)
static void do_blend_effect_byte(float fac, int64_t size, const uchar *rect1, const uchar *rect2, StripBlendMode btype, uchar *out)
static ImBuf * do_colormix_effect(const RenderData *context, SeqRenderState *, Strip *strip, float, float, ImBuf *src1, ImBuf *src2)
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 apply_effect_op(const OpT &op, const ImBuf *src1, const ImBuf *src2, ImBuf *dst)
Definition effects.hh:124
static ImBuf * do_alphaover_effect(const RenderData *context, SeqRenderState *, 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)
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, SeqRenderState *state, 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