Files
test2/source/blender/sequencer/intern/effects/effects.cc
Richard Antalik 68abed543b Refactor: Remove module prefix form symbols in sequnecer namespaces
Remove
SEQ_ prefix for blender::seq namespace and
ED_sequencer for blender::ed::vse namespace

Pull Request: https://projects.blender.org/blender/blender/pulls/135560
2025-03-06 13:04:39 +01:00

298 lines
7.2 KiB
C++

/* SPDX-FileCopyrightText: 2001-2002 NaN Holding BV. All rights reserved.
* SPDX-FileCopyrightText: 2003-2024 Blender Authors
* SPDX-FileCopyrightText: 2005-2006 Peter Schlaile <peter [at] schlaile [dot] de>
*
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup sequencer
*/
#include "DNA_scene_types.h"
#include "DNA_sequence_types.h"
#include "IMB_colormanagement.hh"
#include "IMB_imbuf.hh"
#include "IMB_metadata.hh"
#include "RE_pipeline.h"
#include "SEQ_render.hh"
#include "SEQ_time.hh"
#include "effects.hh"
#include "render.hh"
namespace blender::seq {
ImBuf *prepare_effect_imbufs(const RenderData *context,
ImBuf *ibuf1,
ImBuf *ibuf2,
bool uninitialized_pixels)
{
ImBuf *out;
Scene *scene = context->scene;
int x = context->rectx;
int y = context->recty;
int base_flags = uninitialized_pixels ? IB_uninitialized_pixels : 0;
if (!ibuf1 && !ibuf2) {
/* Hmm, global float option? */
out = IMB_allocImBuf(x, y, 32, IB_byte_data | base_flags);
}
else if ((ibuf1 && ibuf1->float_buffer.data) || (ibuf2 && ibuf2->float_buffer.data)) {
/* if any inputs are float, output is float too */
out = IMB_allocImBuf(x, y, 32, IB_float_data | base_flags);
}
else {
out = IMB_allocImBuf(x, y, 32, IB_byte_data | base_flags);
}
if (out->float_buffer.data) {
if (ibuf1 && !ibuf1->float_buffer.data) {
seq_imbuf_to_sequencer_space(scene, ibuf1, true);
}
if (ibuf2 && !ibuf2->float_buffer.data) {
seq_imbuf_to_sequencer_space(scene, ibuf2, true);
}
IMB_colormanagement_assign_float_colorspace(out, scene->sequencer_colorspace_settings.name);
}
else {
if (ibuf1 && !ibuf1->byte_buffer.data) {
IMB_byte_from_float(ibuf1);
}
if (ibuf2 && !ibuf2->byte_buffer.data) {
IMB_byte_from_float(ibuf2);
}
}
/* If effect only affecting a single channel, forward input's metadata to the output. */
if (ibuf1 != nullptr && ibuf1 == ibuf2) {
IMB_metadata_copy(out, ibuf1);
}
return out;
}
Array<float> make_gaussian_blur_kernel(float rad, int size)
{
int n = 2 * size + 1;
Array<float> gaussian(n);
float sum = 0.0f;
float fac = (rad > 0.0f ? 1.0f / rad : 0.0f);
for (int i = -size; i <= size; i++) {
float val = RE_filter_value(R_FILTER_GAUSS, float(i) * fac);
sum += val;
gaussian[i + size] = val;
}
float inv_sum = 1.0f / sum;
for (int i = 0; i < n; i++) {
gaussian[i] *= inv_sum;
}
return gaussian;
}
static void init_noop(Strip * /*strip*/) {}
static void load_noop(Strip * /*strip*/) {}
static void free_noop(Strip * /*strip*/, const bool /*do_id_user*/) {}
static int num_inputs_default()
{
return 2;
}
static StripEarlyOut early_out_noop(const Strip * /*strip*/, float /*fac*/)
{
return StripEarlyOut::DoEffect;
}
StripEarlyOut early_out_fade(const Strip * /*strip*/, float fac)
{
if (fac == 0.0f) {
return StripEarlyOut::UseInput1;
}
if (fac == 1.0f) {
return StripEarlyOut::UseInput2;
}
return StripEarlyOut::DoEffect;
}
StripEarlyOut early_out_mul_input2(const Strip * /*strip*/, float fac)
{
if (fac == 0.0f) {
return StripEarlyOut::UseInput1;
}
return StripEarlyOut::DoEffect;
}
StripEarlyOut early_out_mul_input1(const Strip * /*strip*/, float fac)
{
if (fac == 0.0f) {
return StripEarlyOut::UseInput2;
}
return StripEarlyOut::DoEffect;
}
static void get_default_fac_noop(const Scene * /*scene*/,
const Strip * /*strip*/,
float /*timeline_frame*/,
float *fac)
{
*fac = 1.0f;
}
void get_default_fac_fade(const Scene *scene, const Strip *strip, float timeline_frame, float *fac)
{
*fac = float(timeline_frame - time_left_handle_frame_get(scene, strip));
*fac /= time_strip_length_get(scene, strip);
*fac = math::clamp(*fac, 0.0f, 1.0f);
}
EffectHandle get_sequence_effect_impl(int strip_type)
{
EffectHandle rval;
rval.init = init_noop;
rval.num_inputs = num_inputs_default;
rval.load = load_noop;
rval.free = free_noop;
rval.early_out = early_out_noop;
rval.get_default_fac = get_default_fac_noop;
rval.execute = nullptr;
rval.copy = nullptr;
switch (strip_type) {
case STRIP_TYPE_CROSS:
cross_effect_get_handle(rval);
break;
case STRIP_TYPE_GAMCROSS:
gamma_cross_effect_get_handle(rval);
break;
case STRIP_TYPE_ADD:
add_effect_get_handle(rval);
break;
case STRIP_TYPE_SUB:
sub_effect_get_handle(rval);
break;
case STRIP_TYPE_MUL:
mul_effect_get_handle(rval);
break;
case STRIP_TYPE_SCREEN:
case STRIP_TYPE_OVERLAY:
case STRIP_TYPE_COLOR_BURN:
case STRIP_TYPE_LINEAR_BURN:
case STRIP_TYPE_DARKEN:
case STRIP_TYPE_LIGHTEN:
case STRIP_TYPE_DODGE:
case STRIP_TYPE_SOFT_LIGHT:
case STRIP_TYPE_HARD_LIGHT:
case STRIP_TYPE_PIN_LIGHT:
case STRIP_TYPE_LIN_LIGHT:
case STRIP_TYPE_VIVID_LIGHT:
case STRIP_TYPE_BLEND_COLOR:
case STRIP_TYPE_HUE:
case STRIP_TYPE_SATURATION:
case STRIP_TYPE_VALUE:
case STRIP_TYPE_DIFFERENCE:
case STRIP_TYPE_EXCLUSION:
blend_mode_effect_get_handle(rval);
break;
case STRIP_TYPE_COLORMIX:
color_mix_effect_get_handle(rval);
break;
case STRIP_TYPE_ALPHAOVER:
alpha_over_effect_get_handle(rval);
break;
case STRIP_TYPE_ALPHAUNDER:
alpha_under_effect_get_handle(rval);
break;
case STRIP_TYPE_WIPE:
wipe_effect_get_handle(rval);
break;
case STRIP_TYPE_GLOW:
glow_effect_get_handle(rval);
break;
case STRIP_TYPE_TRANSFORM:
transform_effect_get_handle(rval);
break;
case STRIP_TYPE_SPEED:
speed_effect_get_handle(rval);
break;
case STRIP_TYPE_COLOR:
solid_color_effect_get_handle(rval);
break;
case STRIP_TYPE_MULTICAM:
multi_camera_effect_get_handle(rval);
break;
case STRIP_TYPE_ADJUSTMENT:
adjustment_effect_get_handle(rval);
break;
case STRIP_TYPE_GAUSSIAN_BLUR:
gaussian_blur_effect_get_handle(rval);
break;
case STRIP_TYPE_TEXT:
text_effect_get_handle(rval);
break;
}
return rval;
}
EffectHandle effect_handle_get(Strip *strip)
{
EffectHandle rval = {};
if (strip->type & STRIP_TYPE_EFFECT) {
rval = get_sequence_effect_impl(strip->type);
if ((strip->flag & SEQ_EFFECT_NOT_LOADED) != 0) {
rval.load(strip);
strip->flag &= ~SEQ_EFFECT_NOT_LOADED;
}
}
return rval;
}
EffectHandle strip_effect_get_sequence_blend(Strip *strip)
{
EffectHandle rval = {};
if (strip->blend_mode != 0) {
if ((strip->flag & SEQ_EFFECT_NOT_LOADED) != 0) {
/* load the effect first */
rval = get_sequence_effect_impl(strip->type);
rval.load(strip);
}
rval = get_sequence_effect_impl(strip->blend_mode);
if ((strip->flag & SEQ_EFFECT_NOT_LOADED) != 0) {
/* now load the blend and unset unloaded flag */
rval.load(strip);
strip->flag &= ~SEQ_EFFECT_NOT_LOADED;
}
}
return rval;
}
int effect_get_num_inputs(int strip_type)
{
EffectHandle rval = get_sequence_effect_impl(strip_type);
int count = rval.num_inputs();
if (rval.execute) {
return count;
}
return 0;
}
} // namespace blender::seq