Blender V4.5
vse_effect_transform.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
9#include "BLI_math_rotation.h"
10
11#include "DNA_sequence_types.h"
12#include "DNA_space_types.h"
13
14#include "IMB_imbuf.hh"
15#include "IMB_interp.hh"
16
17#include "SEQ_proxy.hh"
18#include "SEQ_render.hh"
19
20#include "effects.hh"
21
22namespace blender::seq {
23
24static void init_transform_effect(Strip *strip)
25{
26 if (strip->effectdata) {
27 MEM_freeN(strip->effectdata);
28 }
29
31 strip->effectdata = transform;
32
33 transform->ScalexIni = 1.0f;
34 transform->ScaleyIni = 1.0f;
35
36 transform->xIni = 0.0f;
37 transform->yIni = 0.0f;
38
39 transform->rotIni = 0.0f;
40
41 transform->interpolation = 1;
42 transform->percent = 1;
43 transform->uniform_scale = 0;
44}
45
47{
48 return 1;
49}
50
51static void free_transform_effect(Strip *strip, const bool /*do_id_user*/)
52{
54}
55
56static void copy_transform_effect(Strip *dst, const Strip *src, const int /*flag*/)
57{
59}
60
61static void transform_image(int x,
62 int y,
63 int start_line,
64 int total_lines,
65 const ImBuf *ibuf,
66 ImBuf *out,
67 float scale_x,
68 float scale_y,
69 float translate_x,
70 float translate_y,
71 float rotate,
72 int interpolation)
73{
74 /* Rotate */
75 float s = sinf(rotate);
76 float c = cosf(rotate);
77
78 float4 *dst_fl = reinterpret_cast<float4 *>(out->float_buffer.data);
79 uchar4 *dst_ch = reinterpret_cast<uchar4 *>(out->byte_buffer.data);
80
81 size_t offset = size_t(x) * start_line;
82 for (int yi = start_line; yi < start_line + total_lines; yi++) {
83 for (int xi = 0; xi < x; xi++) {
84 /* Translate point. */
85 float xt = xi - translate_x;
86 float yt = yi - translate_y;
87
88 /* Rotate point with center ref. */
89 float xr = c * xt + s * yt;
90 float yr = -s * xt + c * yt;
91
92 /* Scale point with center ref. */
93 xt = xr / scale_x;
94 yt = yr / scale_y;
95
96 /* Undo reference center point. */
97 xt += (x / 2.0f);
98 yt += (y / 2.0f);
99
100 /* interpolate */
101 switch (interpolation) {
102 case 0:
103 if (dst_fl) {
104 dst_fl[offset] = imbuf::interpolate_nearest_border_fl(ibuf, xt, yt);
105 }
106 else {
107 dst_ch[offset] = imbuf::interpolate_nearest_border_byte(ibuf, xt, yt);
108 }
109 break;
110 case 1:
111 if (dst_fl) {
112 dst_fl[offset] = imbuf::interpolate_bilinear_border_fl(ibuf, xt, yt);
113 }
114 else {
115 dst_ch[offset] = imbuf::interpolate_bilinear_border_byte(ibuf, xt, yt);
116 }
117 break;
118 case 2:
119 if (dst_fl) {
120 dst_fl[offset] = imbuf::interpolate_cubic_bspline_fl(ibuf, xt, yt);
121 }
122 else {
123 dst_ch[offset] = imbuf::interpolate_cubic_bspline_byte(ibuf, xt, yt);
124 }
125 break;
126 }
127 offset++;
128 }
129 }
130}
131
132static ImBuf *do_transform_effect(const RenderData *context,
133 Strip *strip,
134 float /*timeline_frame*/,
135 float /*fac*/,
136 ImBuf *src1,
137 ImBuf * /*src2*/)
138{
139 ImBuf *dst = prepare_effect_imbufs(context, src1, nullptr);
140
142
143 /* Scale */
144 float scale_x, scale_y;
145 if (transform->uniform_scale) {
146 scale_x = scale_y = transform->ScalexIni;
147 }
148 else {
149 scale_x = transform->ScalexIni;
150 scale_y = transform->ScaleyIni;
151 }
152
153 const int x = context->rectx;
154 const int y = context->recty;
155
156 /* Translate */
157 float translate_x, translate_y;
158 if (!transform->percent) {
159 /* Compensate text size for preview render size. */
160 double proxy_size_comp = context->scene->r.size / 100.0;
161 if (context->preview_render_size != SEQ_RENDER_SIZE_SCENE) {
162 proxy_size_comp = rendersize_to_scale_factor(context->preview_render_size);
163 }
164
165 translate_x = transform->xIni * proxy_size_comp + (x / 2.0f);
166 translate_y = transform->yIni * proxy_size_comp + (y / 2.0f);
167 }
168 else {
169 translate_x = x * (transform->xIni / 100.0f) + (x / 2.0f);
170 translate_y = y * (transform->yIni / 100.0f) + (y / 2.0f);
171 }
172
173 /* Rotate */
174 float rotate_radians = DEG2RADF(transform->rotIni);
175
177 blender::IndexRange(dst->y), 32, [&](blender::IndexRange y_range) {
178 transform_image(x,
179 y,
180 y_range.first(),
181 y_range.size(),
182 src1,
183 dst,
184 scale_x,
185 scale_y,
186 translate_x,
187 translate_y,
188 rotate_radians,
189 transform->interpolation);
190 });
191 return dst;
192}
193
202
203} // namespace blender::seq
#define DEG2RADF(_deg)
@ SEQ_RENDER_SIZE_SCENE
SIMD_FORCE_INLINE btVector3 transform(const btVector3 &point) const
#define sinf(x)
#define cosf(x)
#define out
#define MEM_SAFE_FREE(v)
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
float4 interpolate_nearest_border_fl(const ImBuf *in, float u, float v)
Definition IMB_interp.hh:27
uchar4 interpolate_nearest_border_byte(const ImBuf *in, float u, float v)
Definition IMB_interp.hh:23
uchar4 interpolate_cubic_bspline_byte(const ImBuf *in, float u, float v)
float4 interpolate_cubic_bspline_fl(const ImBuf *in, float u, float v)
uchar4 interpolate_bilinear_border_byte(const ImBuf *in, float u, float v)
Definition IMB_interp.hh:74
float4 interpolate_bilinear_border_fl(const ImBuf *in, float u, float v)
Definition IMB_interp.hh:78
static void copy_transform_effect(Strip *dst, const Strip *src, const int)
double rendersize_to_scale_factor(int render_size)
Definition proxy.cc:87
static void free_transform_effect(Strip *strip, const bool)
static ImBuf * do_transform_effect(const RenderData *context, Strip *strip, float, float, ImBuf *src1, ImBuf *)
ImBuf * prepare_effect_imbufs(const RenderData *context, ImBuf *ibuf1, ImBuf *ibuf2, bool uninitialized_pixels)
Definition effects.cc:28
static void init_transform_effect(Strip *strip)
void transform_effect_get_handle(EffectHandle &rval)
static int num_inputs_transform()
static void transform_image(int x, int y, int start_line, int total_lines, const ImBuf *ibuf, ImBuf *out, float scale_x, float scale_y, float translate_x, float translate_y, float rotate, int interpolation)
void parallel_for(const IndexRange range, const int64_t grain_size, const Function &function, const TaskSizeHints &size_hints=detail::TaskSizeHints_Static(1))
Definition BLI_task.hh:93
blender::VecBase< uint8_t, 4 > uchar4
VecBase< float, 4 > float4
static void rotate(float new_co[3], float a, const float ax[3], const float co[3])
void * effectdata
void(* copy)(Strip *dst, const Strip *src, int flag)
ImBuf *(* execute)(const RenderData *context, Strip *strip, float timeline_frame, float fac, ImBuf *ibuf1, ImBuf *ibuf2)
void(* free)(Strip *strip, bool do_id_user)
void(* init)(Strip *strip)