Blender V4.5
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 Strip * /*seq*/,
49 float /*timeline_frame*/,
50 float fac,
51 ImBuf *src1,
52 ImBuf *src2)
53{
54 ImBuf *dst = prepare_effect_imbufs(context, src1, src2);
56 op.factor = fac;
57 apply_effect_op(op, src1, src2, dst);
58 return dst;
59}
60
61/* One could argue that gamma cross should not be hardcoded to 2.0 gamma,
62 * but instead either do proper input->linear conversion (often sRGB). Or
63 * maybe not even that, but do interpolation in some perceptual color space
64 * like OKLAB. But currently it is fixed to just 2.0 gamma. */
65
66static float gammaCorrect(float c)
67{
68 if (UNLIKELY(c < 0)) {
69 return -(c * c);
70 }
71 return c * c;
72}
73
74static float invGammaCorrect(float c)
75{
76 return sqrtf_signed(c);
77}
78
80 template<typename T> void apply(const T *src1, const T *src2, T *dst, int64_t size) const
81 {
82 const float fac = this->factor;
83 const float mfac = 1.0f - fac;
84 for (int64_t idx = 0; idx < size; idx++) {
85 float4 col1 = load_premul_pixel(src1);
86 float4 col2 = load_premul_pixel(src2);
87 float4 col;
88 for (int c = 0; c < 4; ++c) {
89 col[c] = gammaCorrect(mfac * invGammaCorrect(col1[c]) + fac * invGammaCorrect(col2[c]));
90 }
92 src1 += 4;
93 src2 += 4;
94 dst += 4;
95 }
96 }
97 float factor;
98};
99
100static ImBuf *do_gammacross_effect(const RenderData *context,
101 Strip * /*seq*/,
102 float /*timeline_frame*/,
103 float fac,
104 ImBuf *src1,
105 ImBuf *src2)
106{
107 ImBuf *dst = prepare_effect_imbufs(context, src1, src2);
109 op.factor = fac;
110 apply_effect_op(op, src1, src2, dst);
111 return dst;
112}
113
120
127
128} // 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, Strip *, float, float fac, ImBuf *src1, ImBuf *src2)
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 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:45
static float invGammaCorrect(float c)
static ImBuf * do_gammacross_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
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, 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