Blender V4.5
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 Strip * /*seq*/,
51 float /*timeline_frame*/,
52 float fac,
53 ImBuf *src1,
54 ImBuf *src2)
55{
56 ImBuf *dst = prepare_effect_imbufs(context, src1, src2);
57 AddEffectOp op;
58 op.factor = fac;
59 apply_effect_op(op, src1, src2, dst);
60 return dst;
61}
62
63/* -------------------------------------------------------------------- */
64/* Color Subtract Effect */
65
67 template<typename T> void apply(const T *src1, const T *src2, T *dst, int64_t size) const
68 {
69 const float fac = this->factor;
70 int ifac = int(256.0f * fac);
71 for (int64_t idx = 0; idx < size; idx++) {
72 if constexpr (std::is_same_v<T, uchar>) {
73 const int f = ifac * int(src2[3]);
74 dst[0] = max_ii(src1[0] - ((f * src2[0]) >> 16), 0);
75 dst[1] = max_ii(src1[1] - ((f * src2[1]) >> 16), 0);
76 dst[2] = max_ii(src1[2] - ((f * src2[2]) >> 16), 0);
77 }
78 else {
79 const float f = (1.0f - (src1[3] * (1.0f - fac))) * src2[3];
80 dst[0] = max_ff(src1[0] - f * src2[0], 0.0f);
81 dst[1] = max_ff(src1[1] - f * src2[1], 0.0f);
82 dst[2] = max_ff(src1[2] - f * src2[2], 0.0f);
83 }
84 dst[3] = src1[3];
85 src1 += 4;
86 src2 += 4;
87 dst += 4;
88 }
89 }
90 float factor;
91};
92
93static ImBuf *do_sub_effect(const RenderData *context,
94 Strip * /*seq*/,
95 float /*timeline_frame*/,
96 float fac,
97 ImBuf *src1,
98 ImBuf *src2)
99{
100 ImBuf *dst = prepare_effect_imbufs(context, src1, src2);
101 SubEffectOp op;
102 op.factor = fac;
103 apply_effect_op(op, src1, src2, dst);
104 return dst;
105}
106
107/* -------------------------------------------------------------------- */
108/* Multiply Effect */
109
111 template<typename T> void apply(const T *src1, const T *src2, T *dst, int64_t size) const
112 {
113 const float fac = this->factor;
114 int ifac = int(256.0f * fac);
115 for (int64_t idx = 0; idx < size; idx++) {
116 /* Formula: `fac * (a * b) + (1-fac) * a => fac * a * (b - 1) + a` */
117 if constexpr (std::is_same_v<T, uchar>) {
118 dst[0] = src1[0] + ((ifac * src1[0] * (src2[0] - 255)) >> 16);
119 dst[1] = src1[1] + ((ifac * src1[1] * (src2[1] - 255)) >> 16);
120 dst[2] = src1[2] + ((ifac * src1[2] * (src2[2] - 255)) >> 16);
121 dst[3] = src1[3] + ((ifac * src1[3] * (src2[3] - 255)) >> 16);
122 }
123 else {
124 dst[0] = src1[0] + fac * src1[0] * (src2[0] - 1.0f);
125 dst[1] = src1[1] + fac * src1[1] * (src2[1] - 1.0f);
126 dst[2] = src1[2] + fac * src1[2] * (src2[2] - 1.0f);
127 dst[3] = src1[3] + fac * src1[3] * (src2[3] - 1.0f);
128 }
129 src1 += 4;
130 src2 += 4;
131 dst += 4;
132 }
133 }
134 float factor;
135};
136
137static ImBuf *do_mul_effect(const RenderData *context,
138 Strip * /*seq*/,
139 float /*timeline_frame*/,
140 float fac,
141 ImBuf *src1,
142 ImBuf *src2)
143{
144 ImBuf *dst = prepare_effect_imbufs(context, src1, src2);
145 MulEffectOp op;
146 op.factor = fac;
147 apply_effect_op(op, src1, src2, dst);
148 return dst;
149}
150
156
162
168
169} // 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
static ImBuf * do_add_effect(const RenderData *context, Strip *, float, float fac, ImBuf *src1, ImBuf *src2)
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
static ImBuf * do_mul_effect(const RenderData *context, Strip *, float, float fac, ImBuf *src1, ImBuf *src2)
void add_effect_get_handle(EffectHandle &rval)
void sub_effect_get_handle(EffectHandle &rval)
static ImBuf * do_sub_effect(const RenderData *context, 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:121
void apply(const T *src1, const T *src2, T *dst, int64_t size) const
ImBuf *(* execute)(const RenderData *context, 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