Blender V5.0
vse_effect_cross.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
20 template<typename T> void apply(const T *src1, const T *src2, T *dst, int64_t size) const
21 {
22 const float fac = this->factor;
23 const float mfac = 1.0f - fac;
24 const int ifac = int(256.0f * fac);
25 const int imfac = 256 - ifac;
26 for (int64_t idx = 0; idx < size; idx++) {
27 if constexpr (std::is_same_v<T, uchar>) {
28 dst[0] = (imfac * src1[0] + ifac * src2[0]) >> 8;
29 dst[1] = (imfac * src1[1] + ifac * src2[1]) >> 8;
30 dst[2] = (imfac * src1[2] + ifac * src2[2]) >> 8;
31 dst[3] = (imfac * src1[3] + ifac * src2[3]) >> 8;
32 }
33 else {
34 dst[0] = mfac * src1[0] + fac * src2[0];
35 dst[1] = mfac * src1[1] + fac * src2[1];
36 dst[2] = mfac * src1[2] + fac * src2[2];
37 dst[3] = mfac * src1[3] + fac * src2[3];
38 }
39 src1 += 4;
40 src2 += 4;
41 dst += 4;
42 }
43 }
44 float factor;
45};
46
47static ImBuf *do_cross_effect(const RenderData *context,
48 SeqRenderState * /*state*/,
49 Strip * /*seq*/,
50 float /*timeline_frame*/,
51 float fac,
52 ImBuf *src1,
53 ImBuf *src2)
54{
55 ImBuf *dst = prepare_effect_imbufs(context, src1, src2);
57 op.factor = fac;
58 apply_effect_op(op, src1, src2, dst);
59 return dst;
60}
61
62/* One could argue that gamma cross should not be hardcoded to 2.0 gamma,
63 * but instead either do proper input->linear conversion (often sRGB). Or
64 * maybe not even that, but do interpolation in some perceptual color space
65 * like OKLAB. But currently it is fixed to just 2.0 gamma. */
66
67static float gammaCorrect(float c)
68{
69 if (UNLIKELY(c < 0)) {
70 return -(c * c);
71 }
72 return c * c;
73}
74
75static float invGammaCorrect(float c)
76{
77 return sqrtf_signed(c);
78}
79
81 template<typename T> void apply(const T *src1, const T *src2, T *dst, int64_t size) const
82 {
83 const float fac = this->factor;
84 const float mfac = 1.0f - fac;
85 for (int64_t idx = 0; idx < size; idx++) {
86 float4 col1 = load_premul_pixel(src1);
87 float4 col2 = load_premul_pixel(src2);
88 float4 col;
89 for (int c = 0; c < 4; ++c) {
90 col[c] = gammaCorrect(mfac * invGammaCorrect(col1[c]) + fac * invGammaCorrect(col2[c]));
91 }
93 src1 += 4;
94 src2 += 4;
95 dst += 4;
96 }
97 }
98 float factor;
99};
100
101static ImBuf *do_gammacross_effect(const RenderData *context,
102 SeqRenderState * /*state*/,
103 Strip * /*seq*/,
104 float /*timeline_frame*/,
105 float fac,
106 ImBuf *src1,
107 ImBuf *src2)
108{
109 ImBuf *dst = prepare_effect_imbufs(context, src1, src2);
111 op.factor = fac;
112 apply_effect_op(op, src1, src2, dst);
113 return dst;
114}
115
122
129
130} // namespace blender::seq
MINLINE float sqrtf_signed(float f)
#define UNLIKELY(x)
long long int int64_t
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition btDbvt.cpp:52
uint col
#define T
static ImBuf * do_cross_effect(const RenderData *context, SeqRenderState *, Strip *, float, float fac, ImBuf *src1, ImBuf *src2)
static ImBuf * do_gammacross_effect(const RenderData *context, SeqRenderState *, Strip *, float, float fac, ImBuf *src1, ImBuf *src2)
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 gamma_cross_effect_get_handle(EffectHandle &rval)
void get_default_fac_fade(const Scene *scene, const Strip *strip, float timeline_frame, float *fac)
Definition effects.cc:152
void cross_effect_get_handle(EffectHandle &rval)
blender::float4 load_premul_pixel(const uchar *ptr)
Definition effects.hh:48
static float invGammaCorrect(float c)
static void apply_effect_op(const OpT &op, const ImBuf *src1, const ImBuf *src2, ImBuf *dst)
Definition effects.hh:124
static float gammaCorrect(float c)
StripEarlyOut early_out_fade(const Strip *, float fac)
Definition effects.cc:117
VecBase< float, 4 > float4
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)
void(* get_default_fac)(const Scene *scene, const Strip *strip, float timeline_frame, float *fac)
StripEarlyOut(* early_out)(const Strip *strip, float fac)
void apply(const T *src1, const T *src2, T *dst, int64_t size) const