Blender V5.0
vse_effect_add_sub_mul.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 "IMB_imbuf.hh"
12
13#include "SEQ_render.hh"
14
15#include "effects.hh"
16
17namespace blender::seq {
18
19/* -------------------------------------------------------------------- */
20/* Color Add Effect */
21
23 template<typename T> void apply(const T *src1, const T *src2, T *dst, int64_t size) const
24 {
25 const float fac = this->factor;
26 int ifac = int(256.0f * fac);
27 for (int64_t idx = 0; idx < size; idx++) {
28 if constexpr (std::is_same_v<T, uchar>) {
29 const int f = ifac * int(src2[3]);
30 dst[0] = min_ii(src1[0] + ((f * src2[0]) >> 16), 255);
31 dst[1] = min_ii(src1[1] + ((f * src2[1]) >> 16), 255);
32 dst[2] = min_ii(src1[2] + ((f * src2[2]) >> 16), 255);
33 }
34 else {
35 const float f = (1.0f - (src1[3] * (1.0f - fac))) * src2[3];
36 dst[0] = src1[0] + f * src2[0];
37 dst[1] = src1[1] + f * src2[1];
38 dst[2] = src1[2] + f * src2[2];
39 }
40 dst[3] = src1[3];
41 src1 += 4;
42 src2 += 4;
43 dst += 4;
44 }
45 }
46 float factor;
47};
48
49static ImBuf *do_add_effect(const RenderData *context,
50 SeqRenderState * /*state*/,
51 Strip * /*seq*/,
52 float /*timeline_frame*/,
53 float fac,
54 ImBuf *src1,
55 ImBuf *src2)
56{
57 ImBuf *dst = prepare_effect_imbufs(context, src1, src2);
58 AddEffectOp op;
59 op.factor = fac;
60 apply_effect_op(op, src1, src2, dst);
61 return dst;
62}
63
64/* -------------------------------------------------------------------- */
65/* Color Subtract Effect */
66
68 template<typename T> void apply(const T *src1, const T *src2, T *dst, int64_t size) const
69 {
70 const float fac = this->factor;
71 int ifac = int(256.0f * fac);
72 for (int64_t idx = 0; idx < size; idx++) {
73 if constexpr (std::is_same_v<T, uchar>) {
74 const int f = ifac * int(src2[3]);
75 dst[0] = max_ii(src1[0] - ((f * src2[0]) >> 16), 0);
76 dst[1] = max_ii(src1[1] - ((f * src2[1]) >> 16), 0);
77 dst[2] = max_ii(src1[2] - ((f * src2[2]) >> 16), 0);
78 }
79 else {
80 const float f = (1.0f - (src1[3] * (1.0f - fac))) * src2[3];
81 dst[0] = max_ff(src1[0] - f * src2[0], 0.0f);
82 dst[1] = max_ff(src1[1] - f * src2[1], 0.0f);
83 dst[2] = max_ff(src1[2] - f * src2[2], 0.0f);
84 }
85 dst[3] = src1[3];
86 src1 += 4;
87 src2 += 4;
88 dst += 4;
89 }
90 }
91 float factor;
92};
93
94static ImBuf *do_sub_effect(const RenderData *context,
95 SeqRenderState * /*state*/,
96 Strip * /*seq*/,
97 float /*timeline_frame*/,
98 float fac,
99 ImBuf *src1,
100 ImBuf *src2)
101{
102 ImBuf *dst = prepare_effect_imbufs(context, src1, src2);
103 SubEffectOp op;
104 op.factor = fac;
105 apply_effect_op(op, src1, src2, dst);
106 return dst;
107}
108
109/* -------------------------------------------------------------------- */
110/* Multiply Effect */
111
113 template<typename T> void apply(const T *src1, const T *src2, T *dst, int64_t size) const
114 {
115 const float fac = this->factor;
116 int ifac = int(256.0f * fac);
117 for (int64_t idx = 0; idx < size; idx++) {
118 /* Formula: `fac * (a * b) + (1-fac) * a => fac * a * (b - 1) + a` */
119 if constexpr (std::is_same_v<T, uchar>) {
120 dst[0] = src1[0] + ((ifac * src1[0] * (src2[0] - 255)) >> 16);
121 dst[1] = src1[1] + ((ifac * src1[1] * (src2[1] - 255)) >> 16);
122 dst[2] = src1[2] + ((ifac * src1[2] * (src2[2] - 255)) >> 16);
123 dst[3] = src1[3] + ((ifac * src1[3] * (src2[3] - 255)) >> 16);
124 }
125 else {
126 dst[0] = src1[0] + fac * src1[0] * (src2[0] - 1.0f);
127 dst[1] = src1[1] + fac * src1[1] * (src2[1] - 1.0f);
128 dst[2] = src1[2] + fac * src1[2] * (src2[2] - 1.0f);
129 dst[3] = src1[3] + fac * src1[3] * (src2[3] - 1.0f);
130 }
131 src1 += 4;
132 src2 += 4;
133 dst += 4;
134 }
135 }
136 float factor;
137};
138
139static ImBuf *do_mul_effect(const RenderData *context,
140 SeqRenderState * /*state*/,
141 Strip * /*seq*/,
142 float /*timeline_frame*/,
143 float fac,
144 ImBuf *src1,
145 ImBuf *src2)
146{
147 ImBuf *dst = prepare_effect_imbufs(context, src1, src2);
148 MulEffectOp op;
149 op.factor = fac;
150 apply_effect_op(op, src1, src2, dst);
151 return dst;
152}
153
159
165
171
172} // namespace blender::seq
MINLINE float max_ff(float a, float b)
MINLINE int min_ii(int a, int b)
MINLINE int max_ii(int a, int b)
long long int int64_t
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition btDbvt.cpp:52
#define T
void mul_effect_get_handle(EffectHandle &rval)
StripEarlyOut early_out_mul_input2(const Strip *, float fac)
Definition effects.cc:128
ImBuf * prepare_effect_imbufs(const RenderData *context, ImBuf *ibuf1, ImBuf *ibuf2, bool uninitialized_pixels)
Definition effects.cc:28
void add_effect_get_handle(EffectHandle &rval)
static ImBuf * do_mul_effect(const RenderData *context, SeqRenderState *, Strip *, float, float fac, ImBuf *src1, ImBuf *src2)
void sub_effect_get_handle(EffectHandle &rval)
static ImBuf * do_sub_effect(const RenderData *context, SeqRenderState *, Strip *, float, float fac, ImBuf *src1, ImBuf *src2)
static void apply_effect_op(const OpT &op, const ImBuf *src1, const ImBuf *src2, ImBuf *dst)
Definition effects.hh:124
static ImBuf * do_add_effect(const RenderData *context, SeqRenderState *, Strip *, float, float fac, ImBuf *src1, ImBuf *src2)
void apply(const T *src1, const T *src2, T *dst, int64_t size) const
ImBuf *(* execute)(const RenderData *context, SeqRenderState *state, Strip *strip, float timeline_frame, float fac, ImBuf *ibuf1, ImBuf *ibuf2)
StripEarlyOut(* early_out)(const Strip *strip, float fac)
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