diff options
author | Campbell Barton <ideasman42@gmail.com> | 2019-04-17 07:17:24 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2019-04-17 07:21:24 +0300 |
commit | e12c08e8d170b7ca40f204a5b0423c23a9fbc2c1 (patch) | |
tree | 8cf3453d12edb177a218ef8009357518ec6cab6a /source/blender/blenkernel/intern/seqeffects.c | |
parent | b3dabc200a4b0399ec6b81f2ff2730d07b44fcaa (diff) |
ClangFormat: apply to source, most of intern
Apply clang format as proposed in T53211.
For details on usage and instructions for migrating branches
without conflicts, see:
https://wiki.blender.org/wiki/Tools/ClangFormat
Diffstat (limited to 'source/blender/blenkernel/intern/seqeffects.c')
-rw-r--r-- | source/blender/blenkernel/intern/seqeffects.c | 6704 |
1 files changed, 3517 insertions, 3187 deletions
diff --git a/source/blender/blenkernel/intern/seqeffects.c b/source/blender/blenkernel/intern/seqeffects.c index 6ef3f980c85..fa596c875a8 100644 --- a/source/blender/blenkernel/intern/seqeffects.c +++ b/source/blender/blenkernel/intern/seqeffects.c @@ -24,7 +24,6 @@ * \ingroup bke */ - #include <string.h> #include <math.h> #include <stdlib.h> @@ -61,557 +60,641 @@ #include "BLF_api.h" -static void slice_get_byte_buffers( - const SeqRenderData *context, const ImBuf *ibuf1, const ImBuf *ibuf2, - const ImBuf *ibuf3, const ImBuf *out, int start_line, unsigned char **rect1, - unsigned char **rect2, unsigned char **rect3, unsigned char **rect_out) +static void slice_get_byte_buffers(const SeqRenderData *context, + const ImBuf *ibuf1, + const ImBuf *ibuf2, + const ImBuf *ibuf3, + const ImBuf *out, + int start_line, + unsigned char **rect1, + unsigned char **rect2, + unsigned char **rect3, + unsigned char **rect_out) { - int offset = 4 * start_line * context->rectx; + int offset = 4 * start_line * context->rectx; - *rect1 = (unsigned char *)ibuf1->rect + offset; - *rect_out = (unsigned char *)out->rect + offset; + *rect1 = (unsigned char *)ibuf1->rect + offset; + *rect_out = (unsigned char *)out->rect + offset; - if (ibuf2) - *rect2 = (unsigned char *)ibuf2->rect + offset; + if (ibuf2) + *rect2 = (unsigned char *)ibuf2->rect + offset; - if (ibuf3) - *rect3 = (unsigned char *)ibuf3->rect + offset; + if (ibuf3) + *rect3 = (unsigned char *)ibuf3->rect + offset; } -static void slice_get_float_buffers( - const SeqRenderData *context, const ImBuf *ibuf1, const ImBuf *ibuf2, - const ImBuf *ibuf3, const ImBuf *out, int start_line, - float **rect1, float **rect2, float **rect3, float **rect_out) +static void slice_get_float_buffers(const SeqRenderData *context, + const ImBuf *ibuf1, + const ImBuf *ibuf2, + const ImBuf *ibuf3, + const ImBuf *out, + int start_line, + float **rect1, + float **rect2, + float **rect3, + float **rect_out) { - int offset = 4 * start_line * context->rectx; + int offset = 4 * start_line * context->rectx; - *rect1 = ibuf1->rect_float + offset; - *rect_out = out->rect_float + offset; + *rect1 = ibuf1->rect_float + offset; + *rect_out = out->rect_float + offset; - if (ibuf2) - *rect2 = ibuf2->rect_float + offset; + if (ibuf2) + *rect2 = ibuf2->rect_float + offset; - if (ibuf3) - *rect3 = ibuf3->rect_float + offset; + if (ibuf3) + *rect3 = ibuf3->rect_float + offset; } /*********************** Glow effect *************************/ enum { - GlowR = 0, - GlowG = 1, - GlowB = 2, - GlowA = 3, + GlowR = 0, + GlowG = 1, + GlowB = 2, + GlowA = 3, }; -static ImBuf *prepare_effect_imbufs(const SeqRenderData *context, ImBuf *ibuf1, ImBuf *ibuf2, ImBuf *ibuf3) -{ - ImBuf *out; - Scene *scene = context->scene; - int x = context->rectx; - int y = context->recty; - - if (!ibuf1 && !ibuf2 && !ibuf3) { - /* hmmm, global float option ? */ - out = IMB_allocImBuf(x, y, 32, IB_rect); - } - else if ((ibuf1 && ibuf1->rect_float) || - (ibuf2 && ibuf2->rect_float) || - (ibuf3 && ibuf3->rect_float)) - { - /* if any inputs are rectfloat, output is float too */ - - out = IMB_allocImBuf(x, y, 32, IB_rectfloat); - } - else { - out = IMB_allocImBuf(x, y, 32, IB_rect); - } - - if (out->rect_float) { - if (ibuf1 && !ibuf1->rect_float) { - BKE_sequencer_imbuf_to_sequencer_space(scene, ibuf1, true); - } - - if (ibuf2 && !ibuf2->rect_float) { - BKE_sequencer_imbuf_to_sequencer_space(scene, ibuf2, true); - } - - if (ibuf3 && !ibuf3->rect_float) { - BKE_sequencer_imbuf_to_sequencer_space(scene, ibuf3, true); - } - - IMB_colormanagement_assign_float_colorspace(out, scene->sequencer_colorspace_settings.name); - } - else { - if (ibuf1 && !ibuf1->rect) { - IMB_rect_from_float(ibuf1); - } - - if (ibuf2 && !ibuf2->rect) { - IMB_rect_from_float(ibuf2); - } - - if (ibuf3 && !ibuf3->rect) { - IMB_rect_from_float(ibuf3); - } - } - - /* If effect only affecting a single channel, forward input's metadata to the output. */ - if (ibuf1 != NULL && ibuf1 == ibuf2 && ibuf2 == ibuf3) { - IMB_metadata_copy(out, ibuf1); - } - - return out; +static ImBuf *prepare_effect_imbufs(const SeqRenderData *context, + ImBuf *ibuf1, + ImBuf *ibuf2, + ImBuf *ibuf3) +{ + ImBuf *out; + Scene *scene = context->scene; + int x = context->rectx; + int y = context->recty; + + if (!ibuf1 && !ibuf2 && !ibuf3) { + /* hmmm, global float option ? */ + out = IMB_allocImBuf(x, y, 32, IB_rect); + } + else if ((ibuf1 && ibuf1->rect_float) || (ibuf2 && ibuf2->rect_float) || + (ibuf3 && ibuf3->rect_float)) { + /* if any inputs are rectfloat, output is float too */ + + out = IMB_allocImBuf(x, y, 32, IB_rectfloat); + } + else { + out = IMB_allocImBuf(x, y, 32, IB_rect); + } + + if (out->rect_float) { + if (ibuf1 && !ibuf1->rect_float) { + BKE_sequencer_imbuf_to_sequencer_space(scene, ibuf1, true); + } + + if (ibuf2 && !ibuf2->rect_float) { + BKE_sequencer_imbuf_to_sequencer_space(scene, ibuf2, true); + } + + if (ibuf3 && !ibuf3->rect_float) { + BKE_sequencer_imbuf_to_sequencer_space(scene, ibuf3, true); + } + + IMB_colormanagement_assign_float_colorspace(out, scene->sequencer_colorspace_settings.name); + } + else { + if (ibuf1 && !ibuf1->rect) { + IMB_rect_from_float(ibuf1); + } + + if (ibuf2 && !ibuf2->rect) { + IMB_rect_from_float(ibuf2); + } + + if (ibuf3 && !ibuf3->rect) { + IMB_rect_from_float(ibuf3); + } + } + + /* If effect only affecting a single channel, forward input's metadata to the output. */ + if (ibuf1 != NULL && ibuf1 == ibuf2 && ibuf2 == ibuf3) { + IMB_metadata_copy(out, ibuf1); + } + + return out; } /*********************** Alpha Over *************************/ static void init_alpha_over_or_under(Sequence *seq) { - Sequence *seq1 = seq->seq1; - Sequence *seq2 = seq->seq2; - - seq->seq2 = seq1; - seq->seq1 = seq2; -} - -static void do_alphaover_effect_byte( - float facf0, float facf1, int x, int y, - unsigned char *rect1, unsigned char *rect2, unsigned char *out) -{ - float fac2, mfac, fac, fac4; - int xo; - unsigned char *cp1, *cp2, *rt; - float tempc[4], rt1[4], rt2[4]; - - xo = x; - cp1 = rect1; - cp2 = rect2; - rt = out; - - fac2 = facf0; - fac4 = facf1; - - while (y--) { - x = xo; - while (x--) { - /* rt = rt1 over rt2 (alpha from rt1) */ - - straight_uchar_to_premul_float(rt1, cp1); - straight_uchar_to_premul_float(rt2, cp2); - - fac = fac2; - mfac = 1.0f - fac2 * rt1[3]; - - if (fac <= 0.0f) *((unsigned int *) rt) = *((unsigned int *) cp2); - else if (mfac <= 0.0f) *((unsigned int *) rt) = *((unsigned int *) cp1); - else { - tempc[0] = fac * rt1[0] + mfac * rt2[0]; - tempc[1] = fac * rt1[1] + mfac * rt2[1]; - tempc[2] = fac * rt1[2] + mfac * rt2[2]; - tempc[3] = fac * rt1[3] + mfac * rt2[3]; - - premul_float_to_straight_uchar(rt, tempc); - } - cp1 += 4; cp2 += 4; rt += 4; - } - - if (y == 0) break; - y--; - - x = xo; - while (x--) { - straight_uchar_to_premul_float(rt1, cp1); - straight_uchar_to_premul_float(rt2, cp2); - - fac = fac4; - mfac = 1.0f - (fac4 * rt1[3]); - - if (fac <= 0.0f) *((unsigned int *) rt) = *((unsigned int *) cp2); - else if (mfac <= 0.0f) *((unsigned int *) rt) = *((unsigned int *) cp1); - else { - tempc[0] = fac * rt1[0] + mfac * rt2[0]; - tempc[1] = fac * rt1[1] + mfac * rt2[1]; - tempc[2] = fac * rt1[2] + mfac * rt2[2]; - tempc[3] = fac * rt1[3] + mfac * rt2[3]; - - premul_float_to_straight_uchar(rt, tempc); - } - cp1 += 4; cp2 += 4; rt += 4; - } - } + Sequence *seq1 = seq->seq1; + Sequence *seq2 = seq->seq2; + + seq->seq2 = seq1; + seq->seq1 = seq2; +} + +static void do_alphaover_effect_byte(float facf0, + float facf1, + int x, + int y, + unsigned char *rect1, + unsigned char *rect2, + unsigned char *out) +{ + float fac2, mfac, fac, fac4; + int xo; + unsigned char *cp1, *cp2, *rt; + float tempc[4], rt1[4], rt2[4]; + + xo = x; + cp1 = rect1; + cp2 = rect2; + rt = out; + + fac2 = facf0; + fac4 = facf1; + + while (y--) { + x = xo; + while (x--) { + /* rt = rt1 over rt2 (alpha from rt1) */ + + straight_uchar_to_premul_float(rt1, cp1); + straight_uchar_to_premul_float(rt2, cp2); + + fac = fac2; + mfac = 1.0f - fac2 * rt1[3]; + + if (fac <= 0.0f) + *((unsigned int *)rt) = *((unsigned int *)cp2); + else if (mfac <= 0.0f) + *((unsigned int *)rt) = *((unsigned int *)cp1); + else { + tempc[0] = fac * rt1[0] + mfac * rt2[0]; + tempc[1] = fac * rt1[1] + mfac * rt2[1]; + tempc[2] = fac * rt1[2] + mfac * rt2[2]; + tempc[3] = fac * rt1[3] + mfac * rt2[3]; + + premul_float_to_straight_uchar(rt, tempc); + } + cp1 += 4; + cp2 += 4; + rt += 4; + } + + if (y == 0) + break; + y--; + + x = xo; + while (x--) { + straight_uchar_to_premul_float(rt1, cp1); + straight_uchar_to_premul_float(rt2, cp2); + + fac = fac4; + mfac = 1.0f - (fac4 * rt1[3]); + + if (fac <= 0.0f) + *((unsigned int *)rt) = *((unsigned int *)cp2); + else if (mfac <= 0.0f) + *((unsigned int *)rt) = *((unsigned int *)cp1); + else { + tempc[0] = fac * rt1[0] + mfac * rt2[0]; + tempc[1] = fac * rt1[1] + mfac * rt2[1]; + tempc[2] = fac * rt1[2] + mfac * rt2[2]; + tempc[3] = fac * rt1[3] + mfac * rt2[3]; + + premul_float_to_straight_uchar(rt, tempc); + } + cp1 += 4; + cp2 += 4; + rt += 4; + } + } } static void do_alphaover_effect_float( - float facf0, float facf1, int x, int y, - float *rect1, float *rect2, float *out) -{ - float fac2, mfac, fac, fac4; - int xo; - float *rt1, *rt2, *rt; - - xo = x; - rt1 = rect1; - rt2 = rect2; - rt = out; - - fac2 = facf0; - fac4 = facf1; - - while (y--) { - x = xo; - while (x--) { - /* rt = rt1 over rt2 (alpha from rt1) */ - - fac = fac2; - mfac = 1.0f - (fac2 * rt1[3]); - - if (fac <= 0.0f) { - memcpy(rt, rt2, 4 * sizeof(float)); - } - else if (mfac <= 0) { - memcpy(rt, rt1, 4 * sizeof(float)); - } - else { - rt[0] = fac * rt1[0] + mfac * rt2[0]; - rt[1] = fac * rt1[1] + mfac * rt2[1]; - rt[2] = fac * rt1[2] + mfac * rt2[2]; - rt[3] = fac * rt1[3] + mfac * rt2[3]; - } - rt1 += 4; rt2 += 4; rt += 4; - } - - if (y == 0) - break; - y--; - - x = xo; - while (x--) { - fac = fac4; - mfac = 1.0f - (fac4 * rt1[3]); - - if (fac <= 0.0f) { - memcpy(rt, rt2, 4 * sizeof(float)); - } - else if (mfac <= 0.0f) { - memcpy(rt, rt1, 4 * sizeof(float)); - } - else { - rt[0] = fac * rt1[0] + mfac * rt2[0]; - rt[1] = fac * rt1[1] + mfac * rt2[1]; - rt[2] = fac * rt1[2] + mfac * rt2[2]; - rt[3] = fac * rt1[3] + mfac * rt2[3]; - } - rt1 += 4; rt2 += 4; rt += 4; - } - } -} - -static void do_alphaover_effect( - const SeqRenderData *context, Sequence *UNUSED(seq), float UNUSED(cfra), float facf0, - float facf1, ImBuf *ibuf1, ImBuf *ibuf2, ImBuf *UNUSED(ibuf3), - int start_line, int total_lines, ImBuf *out) -{ - if (out->rect_float) { - float *rect1 = NULL, *rect2 = NULL, *rect_out = NULL; - - slice_get_float_buffers(context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out); - - do_alphaover_effect_float(facf0, facf1, context->rectx, total_lines, rect1, rect2, rect_out); - } - else { - unsigned char *rect1 = NULL, *rect2 = NULL, *rect_out = NULL; - - slice_get_byte_buffers(context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out); - - do_alphaover_effect_byte(facf0, facf1, context->rectx, total_lines, rect1, rect2, rect_out); - } + float facf0, float facf1, int x, int y, float *rect1, float *rect2, float *out) +{ + float fac2, mfac, fac, fac4; + int xo; + float *rt1, *rt2, *rt; + + xo = x; + rt1 = rect1; + rt2 = rect2; + rt = out; + + fac2 = facf0; + fac4 = facf1; + + while (y--) { + x = xo; + while (x--) { + /* rt = rt1 over rt2 (alpha from rt1) */ + + fac = fac2; + mfac = 1.0f - (fac2 * rt1[3]); + + if (fac <= 0.0f) { + memcpy(rt, rt2, 4 * sizeof(float)); + } + else if (mfac <= 0) { + memcpy(rt, rt1, 4 * sizeof(float)); + } + else { + rt[0] = fac * rt1[0] + mfac * rt2[0]; + rt[1] = fac * rt1[1] + mfac * rt2[1]; + rt[2] = fac * rt1[2] + mfac * rt2[2]; + rt[3] = fac * rt1[3] + mfac * rt2[3]; + } + rt1 += 4; + rt2 += 4; + rt += 4; + } + + if (y == 0) + break; + y--; + + x = xo; + while (x--) { + fac = fac4; + mfac = 1.0f - (fac4 * rt1[3]); + + if (fac <= 0.0f) { + memcpy(rt, rt2, 4 * sizeof(float)); + } + else if (mfac <= 0.0f) { + memcpy(rt, rt1, 4 * sizeof(float)); + } + else { + rt[0] = fac * rt1[0] + mfac * rt2[0]; + rt[1] = fac * rt1[1] + mfac * rt2[1]; + rt[2] = fac * rt1[2] + mfac * rt2[2]; + rt[3] = fac * rt1[3] + mfac * rt2[3]; + } + rt1 += 4; + rt2 += 4; + rt += 4; + } + } +} + +static void do_alphaover_effect(const SeqRenderData *context, + Sequence *UNUSED(seq), + float UNUSED(cfra), + float facf0, + float facf1, + ImBuf *ibuf1, + ImBuf *ibuf2, + ImBuf *UNUSED(ibuf3), + int start_line, + int total_lines, + ImBuf *out) +{ + if (out->rect_float) { + float *rect1 = NULL, *rect2 = NULL, *rect_out = NULL; + + slice_get_float_buffers( + context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out); + + do_alphaover_effect_float(facf0, facf1, context->rectx, total_lines, rect1, rect2, rect_out); + } + else { + unsigned char *rect1 = NULL, *rect2 = NULL, *rect_out = NULL; + + slice_get_byte_buffers( + context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out); + + do_alphaover_effect_byte(facf0, facf1, context->rectx, total_lines, rect1, rect2, rect_out); + } } /*********************** Alpha Under *************************/ -static void do_alphaunder_effect_byte( - float facf0, float facf1, int x, int y, - unsigned char *rect1, unsigned char *rect2, unsigned char *out) -{ - float fac2, fac, fac4; - int xo; - unsigned char *cp1, *cp2, *rt; - float tempc[4], rt1[4], rt2[4]; - - xo = x; - cp1 = rect1; - cp2 = rect2; - rt = out; - - fac2 = facf0; - fac4 = facf1; - - while (y--) { - x = xo; - while (x--) { - /* rt = rt1 under rt2 (alpha from rt2) */ - straight_uchar_to_premul_float(rt1, cp1); - straight_uchar_to_premul_float(rt2, cp2); - - /* this complex optimization is because the - * 'skybuf' can be crossed in - */ - if (rt2[3] <= 0.0f && fac2 >= 1.0f) *((unsigned int *) rt) = *((unsigned int *) cp1); - else if (rt2[3] >= 1.0f) *((unsigned int *) rt) = *((unsigned int *) cp2); - else { - fac = (fac2 * (1.0f - rt2[3])); - - if (fac <= 0) *((unsigned int *) rt) = *((unsigned int *) cp2); - else { - tempc[0] = (fac * rt1[0] + rt2[0]); - tempc[1] = (fac * rt1[1] + rt2[1]); - tempc[2] = (fac * rt1[2] + rt2[2]); - tempc[3] = (fac * rt1[3] + rt2[3]); - - premul_float_to_straight_uchar(rt, tempc); - } - } - cp1 += 4; cp2 += 4; rt += 4; - } - - if (y == 0) - break; - y--; - - x = xo; - while (x--) { - straight_uchar_to_premul_float(rt1, cp1); - straight_uchar_to_premul_float(rt2, cp2); - - if (rt2[3] <= 0.0f && fac4 >= 1.0f) *((unsigned int *) rt) = *((unsigned int *) cp1); - else if (rt2[3] >= 1.0f) *((unsigned int *) rt) = *((unsigned int *) cp2); - else { - fac = (fac4 * (1.0f - rt2[3])); - - if (fac <= 0) *((unsigned int *)rt) = *((unsigned int *)cp2); - else { - tempc[0] = (fac * rt1[0] + rt2[0]); - tempc[1] = (fac * rt1[1] + rt2[1]); - tempc[2] = (fac * rt1[2] + rt2[2]); - tempc[3] = (fac * rt1[3] + rt2[3]); - - premul_float_to_straight_uchar(rt, tempc); - } - } - cp1 += 4; cp2 += 4; rt += 4; - } - } +static void do_alphaunder_effect_byte(float facf0, + float facf1, + int x, + int y, + unsigned char *rect1, + unsigned char *rect2, + unsigned char *out) +{ + float fac2, fac, fac4; + int xo; + unsigned char *cp1, *cp2, *rt; + float tempc[4], rt1[4], rt2[4]; + + xo = x; + cp1 = rect1; + cp2 = rect2; + rt = out; + + fac2 = facf0; + fac4 = facf1; + + while (y--) { + x = xo; + while (x--) { + /* rt = rt1 under rt2 (alpha from rt2) */ + straight_uchar_to_premul_float(rt1, cp1); + straight_uchar_to_premul_float(rt2, cp2); + + /* this complex optimization is because the + * 'skybuf' can be crossed in + */ + if (rt2[3] <= 0.0f && fac2 >= 1.0f) + *((unsigned int *)rt) = *((unsigned int *)cp1); + else if (rt2[3] >= 1.0f) + *((unsigned int *)rt) = *((unsigned int *)cp2); + else { + fac = (fac2 * (1.0f - rt2[3])); + + if (fac <= 0) + *((unsigned int *)rt) = *((unsigned int *)cp2); + else { + tempc[0] = (fac * rt1[0] + rt2[0]); + tempc[1] = (fac * rt1[1] + rt2[1]); + tempc[2] = (fac * rt1[2] + rt2[2]); + tempc[3] = (fac * rt1[3] + rt2[3]); + + premul_float_to_straight_uchar(rt, tempc); + } + } + cp1 += 4; + cp2 += 4; + rt += 4; + } + + if (y == 0) + break; + y--; + + x = xo; + while (x--) { + straight_uchar_to_premul_float(rt1, cp1); + straight_uchar_to_premul_float(rt2, cp2); + + if (rt2[3] <= 0.0f && fac4 >= 1.0f) + *((unsigned int *)rt) = *((unsigned int *)cp1); + else if (rt2[3] >= 1.0f) + *((unsigned int *)rt) = *((unsigned int *)cp2); + else { + fac = (fac4 * (1.0f - rt2[3])); + + if (fac <= 0) + *((unsigned int *)rt) = *((unsigned int *)cp2); + else { + tempc[0] = (fac * rt1[0] + rt2[0]); + tempc[1] = (fac * rt1[1] + rt2[1]); + tempc[2] = (fac * rt1[2] + rt2[2]); + tempc[3] = (fac * rt1[3] + rt2[3]); + + premul_float_to_straight_uchar(rt, tempc); + } + } + cp1 += 4; + cp2 += 4; + rt += 4; + } + } } static void do_alphaunder_effect_float( - float facf0, float facf1, int x, int y, - float *rect1, float *rect2, float *out) -{ - float fac2, fac, fac4; - int xo; - float *rt1, *rt2, *rt; - - xo = x; - rt1 = rect1; - rt2 = rect2; - rt = out; - - fac2 = facf0; - fac4 = facf1; - - while (y--) { - x = xo; - while (x--) { - /* rt = rt1 under rt2 (alpha from rt2) */ - - /* this complex optimization is because the - * 'skybuf' can be crossed in - */ - if (rt2[3] <= 0 && fac2 >= 1.0f) { - memcpy(rt, rt1, 4 * sizeof(float)); - } - else if (rt2[3] >= 1.0f) { - memcpy(rt, rt2, 4 * sizeof(float)); - } - else { - fac = fac2 * (1.0f - rt2[3]); - - if (fac == 0) { - memcpy(rt, rt2, 4 * sizeof(float)); - } - else { - rt[0] = fac * rt1[0] + rt2[0]; - rt[1] = fac * rt1[1] + rt2[1]; - rt[2] = fac * rt1[2] + rt2[2]; - rt[3] = fac * rt1[3] + rt2[3]; - } - } - rt1 += 4; rt2 += 4; rt += 4; - } - - if (y == 0) - break; - y--; - - x = xo; - while (x--) { - if (rt2[3] <= 0 && fac4 >= 1.0f) { - memcpy(rt, rt1, 4 * sizeof(float)); - } - else if (rt2[3] >= 1.0f) { - memcpy(rt, rt2, 4 * sizeof(float)); - } - else { - fac = fac4 * (1.0f - rt2[3]); - - if (fac == 0) { - memcpy(rt, rt2, 4 * sizeof(float)); - } - else { - rt[0] = fac * rt1[0] + rt2[0]; - rt[1] = fac * rt1[1] + rt2[1]; - rt[2] = fac * rt1[2] + rt2[2]; - rt[3] = fac * rt1[3] + rt2[3]; - } - } - rt1 += 4; rt2 += 4; rt += 4; - } - } -} - -static void do_alphaunder_effect( - const SeqRenderData *context, Sequence *UNUSED(seq), float UNUSED(cfra), - float facf0, float facf1, ImBuf *ibuf1, ImBuf *ibuf2, ImBuf *UNUSED(ibuf3), - int start_line, int total_lines, ImBuf *out) -{ - if (out->rect_float) { - float *rect1 = NULL, *rect2 = NULL, *rect_out = NULL; - - slice_get_float_buffers(context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out); - - do_alphaunder_effect_float(facf0, facf1, context->rectx, total_lines, rect1, rect2, rect_out); - } - else { - unsigned char *rect1 = NULL, *rect2 = NULL, *rect_out = NULL; - - slice_get_byte_buffers(context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out); - - do_alphaunder_effect_byte(facf0, facf1, context->rectx, total_lines, rect1, rect2, rect_out); - } + float facf0, float facf1, int x, int y, float *rect1, float *rect2, float *out) +{ + float fac2, fac, fac4; + int xo; + float *rt1, *rt2, *rt; + + xo = x; + rt1 = rect1; + rt2 = rect2; + rt = out; + + fac2 = facf0; + fac4 = facf1; + + while (y--) { + x = xo; + while (x--) { + /* rt = rt1 under rt2 (alpha from rt2) */ + + /* this complex optimization is because the + * 'skybuf' can be crossed in + */ + if (rt2[3] <= 0 && fac2 >= 1.0f) { + memcpy(rt, rt1, 4 * sizeof(float)); + } + else if (rt2[3] >= 1.0f) { + memcpy(rt, rt2, 4 * sizeof(float)); + } + else { + fac = fac2 * (1.0f - rt2[3]); + + if (fac == 0) { + memcpy(rt, rt2, 4 * sizeof(float)); + } + else { + rt[0] = fac * rt1[0] + rt2[0]; + rt[1] = fac * rt1[1] + rt2[1]; + rt[2] = fac * rt1[2] + rt2[2]; + rt[3] = fac * rt1[3] + rt2[3]; + } + } + rt1 += 4; + rt2 += 4; + rt += 4; + } + + if (y == 0) + break; + y--; + + x = xo; + while (x--) { + if (rt2[3] <= 0 && fac4 >= 1.0f) { + memcpy(rt, rt1, 4 * sizeof(float)); + } + else if (rt2[3] >= 1.0f) { + memcpy(rt, rt2, 4 * sizeof(float)); + } + else { + fac = fac4 * (1.0f - rt2[3]); + + if (fac == 0) { + memcpy(rt, rt2, 4 * sizeof(float)); + } + else { + rt[0] = fac * rt1[0] + rt2[0]; + rt[1] = fac * rt1[1] + rt2[1]; + rt[2] = fac * rt1[2] + rt2[2]; + rt[3] = fac * rt1[3] + rt2[3]; + } + } + rt1 += 4; + rt2 += 4; + rt += 4; + } + } +} + +static void do_alphaunder_effect(const SeqRenderData *context, + Sequence *UNUSED(seq), + float UNUSED(cfra), + float facf0, + float facf1, + ImBuf *ibuf1, + ImBuf *ibuf2, + ImBuf *UNUSED(ibuf3), + int start_line, + int total_lines, + ImBuf *out) +{ + if (out->rect_float) { + float *rect1 = NULL, *rect2 = NULL, *rect_out = NULL; + + slice_get_float_buffers( + context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out); + + do_alphaunder_effect_float(facf0, facf1, context->rectx, total_lines, rect1, rect2, rect_out); + } + else { + unsigned char *rect1 = NULL, *rect2 = NULL, *rect_out = NULL; + + slice_get_byte_buffers( + context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out); + + do_alphaunder_effect_byte(facf0, facf1, context->rectx, total_lines, rect1, rect2, rect_out); + } } /*********************** Cross *************************/ -static void do_cross_effect_byte( - float facf0, float facf1, int x, int y, - unsigned char *rect1, unsigned char *rect2, unsigned char *out) -{ - int fac1, fac2, fac3, fac4; - int xo; - unsigned char *rt1, *rt2, *rt; - - xo = x; - rt1 = rect1; - rt2 = rect2; - rt = out; - - fac2 = (int) (256.0f * facf0); - fac1 = 256 - fac2; - fac4 = (int) (256.0f * facf1); - fac3 = 256 - fac4; - - while (y--) { - x = xo; - while (x--) { - rt[0] = (fac1 * rt1[0] + fac2 * rt2[0]) >> 8; - rt[1] = (fac1 * rt1[1] + fac2 * rt2[1]) >> 8; - rt[2] = (fac1 * rt1[2] + fac2 * rt2[2]) >> 8; - rt[3] = (fac1 * rt1[3] + fac2 * rt2[3]) >> 8; - - rt1 += 4; rt2 += 4; rt += 4; - } - - if (y == 0) - break; - y--; - - x = xo; - while (x--) { - rt[0] = (fac3 * rt1[0] + fac4 * rt2[0]) >> 8; - rt[1] = (fac3 * rt1[1] + fac4 * rt2[1]) >> 8; - rt[2] = (fac3 * rt1[2] + fac4 * rt2[2]) >> 8; - rt[3] = (fac3 * rt1[3] + fac4 * rt2[3]) >> 8; - - rt1 += 4; rt2 += 4; rt += 4; - } - - } -} - -static void do_cross_effect_float(float facf0, float facf1, int x, int y, float *rect1, float *rect2, float *out) -{ - float fac1, fac2, fac3, fac4; - int xo; - float *rt1, *rt2, *rt; - - xo = x; - rt1 = rect1; - rt2 = rect2; - rt = out; - - fac2 = facf0; - fac1 = 1.0f - fac2; - fac4 = facf1; - fac3 = 1.0f - fac4; - - while (y--) { - x = xo; - while (x--) { - rt[0] = fac1 * rt1[0] + fac2 * rt2[0]; - rt[1] = fac1 * rt1[1] + fac2 * rt2[1]; - rt[2] = fac1 * rt1[2] + fac2 * rt2[2]; - rt[3] = fac1 * rt1[3] + fac2 * rt2[3]; - - rt1 += 4; rt2 += 4; rt += 4; - } - - if (y == 0) - break; - y--; - - x = xo; - while (x--) { - rt[0] = fac3 * rt1[0] + fac4 * rt2[0]; - rt[1] = fac3 * rt1[1] + fac4 * rt2[1]; - rt[2] = fac3 * rt1[2] + fac4 * rt2[2]; - rt[3] = fac3 * rt1[3] + fac4 * rt2[3]; - - rt1 += 4; rt2 += 4; rt += 4; - } - - } -} - -static void do_cross_effect( - const SeqRenderData *context, Sequence *UNUSED(seq), float UNUSED(cfra), - float facf0, float facf1, ImBuf *ibuf1, ImBuf *ibuf2, ImBuf *UNUSED(ibuf3), - int start_line, int total_lines, ImBuf *out) -{ - if (out->rect_float) { - float *rect1 = NULL, *rect2 = NULL, *rect_out = NULL; - - slice_get_float_buffers(context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out); - - do_cross_effect_float(facf0, facf1, context->rectx, total_lines, rect1, rect2, rect_out); - } - else { - unsigned char *rect1 = NULL, *rect2 = NULL, *rect_out = NULL; - - slice_get_byte_buffers(context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out); - - do_cross_effect_byte(facf0, facf1, context->rectx, total_lines, rect1, rect2, rect_out); - } +static void do_cross_effect_byte(float facf0, + float facf1, + int x, + int y, + unsigned char *rect1, + unsigned char *rect2, + unsigned char *out) +{ + int fac1, fac2, fac3, fac4; + int xo; + unsigned char *rt1, *rt2, *rt; + + xo = x; + rt1 = rect1; + rt2 = rect2; + rt = out; + + fac2 = (int)(256.0f * facf0); + fac1 = 256 - fac2; + fac4 = (int)(256.0f * facf1); + fac3 = 256 - fac4; + + while (y--) { + x = xo; + while (x--) { + rt[0] = (fac1 * rt1[0] + fac2 * rt2[0]) >> 8; + rt[1] = (fac1 * rt1[1] + fac2 * rt2[1]) >> 8; + rt[2] = (fac1 * rt1[2] + fac2 * rt2[2]) >> 8; + rt[3] = (fac1 * rt1[3] + fac2 * rt2[3]) >> 8; + + rt1 += 4; + rt2 += 4; + rt += 4; + } + + if (y == 0) + break; + y--; + + x = xo; + while (x--) { + rt[0] = (fac3 * rt1[0] + fac4 * rt2[0]) >> 8; + rt[1] = (fac3 * rt1[1] + fac4 * rt2[1]) >> 8; + rt[2] = (fac3 * rt1[2] + fac4 * rt2[2]) >> 8; + rt[3] = (fac3 * rt1[3] + fac4 * rt2[3]) >> 8; + + rt1 += 4; + rt2 += 4; + rt += 4; + } + } +} + +static void do_cross_effect_float( + float facf0, float facf1, int x, int y, float *rect1, float *rect2, float *out) +{ + float fac1, fac2, fac3, fac4; + int xo; + float *rt1, *rt2, *rt; + + xo = x; + rt1 = rect1; + rt2 = rect2; + rt = out; + + fac2 = facf0; + fac1 = 1.0f - fac2; + fac4 = facf1; + fac3 = 1.0f - fac4; + + while (y--) { + x = xo; + while (x--) { + rt[0] = fac1 * rt1[0] + fac2 * rt2[0]; + rt[1] = fac1 * rt1[1] + fac2 * rt2[1]; + rt[2] = fac1 * rt1[2] + fac2 * rt2[2]; + rt[3] = fac1 * rt1[3] + fac2 * rt2[3]; + + rt1 += 4; + rt2 += 4; + rt += 4; + } + + if (y == 0) + break; + y--; + + x = xo; + while (x--) { + rt[0] = fac3 * rt1[0] + fac4 * rt2[0]; + rt[1] = fac3 * rt1[1] + fac4 * rt2[1]; + rt[2] = fac3 * rt1[2] + fac4 * rt2[2]; + rt[3] = fac3 * rt1[3] + fac4 * rt2[3]; + + rt1 += 4; + rt2 += 4; + rt += 4; + } + } +} + +static void do_cross_effect(const SeqRenderData *context, + Sequence *UNUSED(seq), + float UNUSED(cfra), + float facf0, + float facf1, + ImBuf *ibuf1, + ImBuf *ibuf2, + ImBuf *UNUSED(ibuf3), + int start_line, + int total_lines, + ImBuf *out) +{ + if (out->rect_float) { + float *rect1 = NULL, *rect2 = NULL, *rect_out = NULL; + + slice_get_float_buffers( + context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out); + + do_cross_effect_float(facf0, facf1, context->rectx, total_lines, rect1, rect2, rect_out); + } + else { + unsigned char *rect1 = NULL, *rect2 = NULL, *rect_out = NULL; + + slice_get_byte_buffers( + context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out); + + do_cross_effect_byte(facf0, facf1, context->rectx, total_lines, rect1, rect2, rect_out); + } } /*********************** Gamma Cross *************************/ @@ -635,111 +718,117 @@ static float valid_inv_gamma; static void makeGammaTables(float gamma) { - /* we need two tables: one forward, one backward */ - int i; - - valid_gamma = gamma; - valid_inv_gamma = 1.0f / gamma; - color_step = 1.0f / RE_GAMMA_TABLE_SIZE; - inv_color_step = (float) RE_GAMMA_TABLE_SIZE; - - /* We could squeeze out the two range tables to gain some memory */ - for (i = 0; i < RE_GAMMA_TABLE_SIZE; i++) { - color_domain_table[i] = i * color_step; - gamma_range_table[i] = pow(color_domain_table[i], valid_gamma); - inv_gamma_range_table[i] = pow(color_domain_table[i], valid_inv_gamma); - } - - /* The end of the table should match 1.0 carefully. In order to avoid - * rounding errors, we just set this explicitly. The last segment may - * have a different length than the other segments, but our - * interpolation is insensitive to that - */ - color_domain_table[RE_GAMMA_TABLE_SIZE] = 1.0; - gamma_range_table[RE_GAMMA_TABLE_SIZE] = 1.0; - inv_gamma_range_table[RE_GAMMA_TABLE_SIZE] = 1.0; - - /* To speed up calculations, we make these calc factor tables. They are - * multiplication factors used in scaling the interpolation - */ - for (i = 0; i < RE_GAMMA_TABLE_SIZE; i++) { - gamfactor_table[i] = inv_color_step * (gamma_range_table[i + 1] - gamma_range_table[i]); - inv_gamfactor_table[i] = inv_color_step * (inv_gamma_range_table[i + 1] - inv_gamma_range_table[i]); - } - + /* we need two tables: one forward, one backward */ + int i; + + valid_gamma = gamma; + valid_inv_gamma = 1.0f / gamma; + color_step = 1.0f / RE_GAMMA_TABLE_SIZE; + inv_color_step = (float)RE_GAMMA_TABLE_SIZE; + + /* We could squeeze out the two range tables to gain some memory */ + for (i = 0; i < RE_GAMMA_TABLE_SIZE; i++) { + color_domain_table[i] = i * color_step; + gamma_range_table[i] = pow(color_domain_table[i], valid_gamma); + inv_gamma_range_table[i] = pow(color_domain_table[i], valid_inv_gamma); + } + + /* The end of the table should match 1.0 carefully. In order to avoid + * rounding errors, we just set this explicitly. The last segment may + * have a different length than the other segments, but our + * interpolation is insensitive to that + */ + color_domain_table[RE_GAMMA_TABLE_SIZE] = 1.0; + gamma_range_table[RE_GAMMA_TABLE_SIZE] = 1.0; + inv_gamma_range_table[RE_GAMMA_TABLE_SIZE] = 1.0; + + /* To speed up calculations, we make these calc factor tables. They are + * multiplication factors used in scaling the interpolation + */ + for (i = 0; i < RE_GAMMA_TABLE_SIZE; i++) { + gamfactor_table[i] = inv_color_step * (gamma_range_table[i + 1] - gamma_range_table[i]); + inv_gamfactor_table[i] = inv_color_step * + (inv_gamma_range_table[i + 1] - inv_gamma_range_table[i]); + } } static float gammaCorrect(float c) { - int i; - float res; + int i; + float res; - i = floorf(c * inv_color_step); - /* Clip to range [0, 1]: outside, just do the complete calculation. - * We may have some performance problems here. Stretching up the LUT - * may help solve that, by exchanging LUT size for the interpolation. - * Negative colors are explicitly handled. - */ - if (UNLIKELY(i < 0)) res = -powf(-c, valid_gamma); - else if (i >= RE_GAMMA_TABLE_SIZE) res = powf(c, valid_gamma); - else res = gamma_range_table[i] + - ((c - color_domain_table[i]) * gamfactor_table[i]); + i = floorf(c * inv_color_step); + /* Clip to range [0, 1]: outside, just do the complete calculation. + * We may have some performance problems here. Stretching up the LUT + * may help solve that, by exchanging LUT size for the interpolation. + * Negative colors are explicitly handled. + */ + if (UNLIKELY(i < 0)) + res = -powf(-c, valid_gamma); + else if (i >= RE_GAMMA_TABLE_SIZE) + res = powf(c, valid_gamma); + else + res = gamma_range_table[i] + ((c - color_domain_table[i]) * gamfactor_table[i]); - return res; + return res; } /* ------------------------------------------------------------------------- */ static float invGammaCorrect(float c) { - int i; - float res = 0.0; + int i; + float res = 0.0; - i = floorf(c * inv_color_step); - /* Negative colors are explicitly handled */ - if (UNLIKELY(i < 0)) res = -powf(-c, valid_inv_gamma); - else if (i >= RE_GAMMA_TABLE_SIZE) res = powf(c, valid_inv_gamma); - else res = inv_gamma_range_table[i] + - ((c - color_domain_table[i]) * inv_gamfactor_table[i]); + i = floorf(c * inv_color_step); + /* Negative colors are explicitly handled */ + if (UNLIKELY(i < 0)) + res = -powf(-c, valid_inv_gamma); + else if (i >= RE_GAMMA_TABLE_SIZE) + res = powf(c, valid_inv_gamma); + else + res = inv_gamma_range_table[i] + ((c - color_domain_table[i]) * inv_gamfactor_table[i]); - return res; + return res; } static void gamtabs(float gamma) { - float val, igamma = 1.0f / gamma; - int a; - - /* gamtab: in short, out short */ - for (a = 0; a < 65536; a++) { - val = a; - val /= 65535.0f; - - if (gamma == 2.0f) - val = sqrtf(val); - else if (gamma != 1.0f) - val = powf(val, igamma); - - gamtab[a] = (65535.99f * val); - } - /* inverse gamtab1 : in byte, out short */ - for (a = 1; a <= 256; a++) { - if (gamma == 2.0f) igamtab1[a - 1] = a * a - 1; - else if (gamma == 1.0f) igamtab1[a - 1] = 256 * a - 1; - else { - val = a / 256.0f; - igamtab1[a - 1] = (65535.0 * pow(val, gamma)) - 1; - } - } + float val, igamma = 1.0f / gamma; + int a; + + /* gamtab: in short, out short */ + for (a = 0; a < 65536; a++) { + val = a; + val /= 65535.0f; + + if (gamma == 2.0f) + val = sqrtf(val); + else if (gamma != 1.0f) + val = powf(val, igamma); + + gamtab[a] = (65535.99f * val); + } + /* inverse gamtab1 : in byte, out short */ + for (a = 1; a <= 256; a++) { + if (gamma == 2.0f) + igamtab1[a - 1] = a * a - 1; + else if (gamma == 1.0f) + igamtab1[a - 1] = 256 * a - 1; + else { + val = a / 256.0f; + igamtab1[a - 1] = (65535.0 * pow(val, gamma)) - 1; + } + } } static void build_gammatabs(void) { - if (gamma_tabs_init == false) { - gamtabs(2.0f); - makeGammaTables(2.0f); - gamma_tabs_init = true; - } + if (gamma_tabs_init == false) { + gamtabs(2.0f); + makeGammaTables(2.0f); + gamma_tabs_init = true; + } } static void init_gammacross(Sequence *UNUSED(seq)) @@ -754,1756 +843,2022 @@ static void free_gammacross(Sequence *UNUSED(seq), const bool UNUSED(do_id_user) { } -static void do_gammacross_effect_byte( - float facf0, float UNUSED(facf1), int x, int y, unsigned char *rect1, - unsigned char *rect2, unsigned char *out) +static void do_gammacross_effect_byte(float facf0, + float UNUSED(facf1), + int x, + int y, + unsigned char *rect1, + unsigned char *rect2, + unsigned char *out) { - float fac1, fac2; - int xo; - unsigned char *cp1, *cp2, *rt; - float rt1[4], rt2[4], tempc[4]; + float fac1, fac2; + int xo; + unsigned char *cp1, *cp2, *rt; + float rt1[4], rt2[4], tempc[4]; - xo = x; - cp1 = rect1; - cp2 = rect2; - rt = out; + xo = x; + cp1 = rect1; + cp2 = rect2; + rt = out; - fac2 = facf0; - fac1 = 1.0f - fac2; + fac2 = facf0; + fac1 = 1.0f - fac2; - while (y--) { - x = xo; - while (x--) { - straight_uchar_to_premul_float(rt1, cp1); - straight_uchar_to_premul_float(rt2, cp2); + while (y--) { + x = xo; + while (x--) { + straight_uchar_to_premul_float(rt1, cp1); + straight_uchar_to_premul_float(rt2, cp2); - tempc[0] = gammaCorrect(fac1 * invGammaCorrect(rt1[0]) + fac2 * invGammaCorrect(rt2[0])); - tempc[1] = gammaCorrect(fac1 * invGammaCorrect(rt1[1]) + fac2 * invGammaCorrect(rt2[1])); - tempc[2] = gammaCorrect(fac1 * invGammaCorrect(rt1[2]) + fac2 * invGammaCorrect(rt2[2])); - tempc[3] = gammaCorrect(fac1 * invGammaCorrect(rt1[3]) + fac2 * invGammaCorrect(rt2[3])); + tempc[0] = gammaCorrect(fac1 * invGammaCorrect(rt1[0]) + fac2 * invGammaCorrect(rt2[0])); + tempc[1] = gammaCorrect(fac1 * invGammaCorrect(rt1[1]) + fac2 * invGammaCorrect(rt2[1])); + tempc[2] = gammaCorrect(fac1 * invGammaCorrect(rt1[2]) + fac2 * invGammaCorrect(rt2[2])); + tempc[3] = gammaCorrect(fac1 * invGammaCorrect(rt1[3]) + fac2 * invGammaCorrect(rt2[3])); - premul_float_to_straight_uchar(rt, tempc); - cp1 += 4; cp2 += 4; rt += 4; - } + premul_float_to_straight_uchar(rt, tempc); + cp1 += 4; + cp2 += 4; + rt += 4; + } - if (y == 0) - break; - y--; + if (y == 0) + break; + y--; - x = xo; - while (x--) { - straight_uchar_to_premul_float(rt1, cp1); - straight_uchar_to_premul_float(rt2, cp2); + x = xo; + while (x--) { + straight_uchar_to_premul_float(rt1, cp1); + straight_uchar_to_premul_float(rt2, cp2); - tempc[0] = gammaCorrect(fac1 * invGammaCorrect(rt1[0]) + fac2 * invGammaCorrect(rt2[0])); - tempc[1] = gammaCorrect(fac1 * invGammaCorrect(rt1[1]) + fac2 * invGammaCorrect(rt2[1])); - tempc[2] = gammaCorrect(fac1 * invGammaCorrect(rt1[2]) + fac2 * invGammaCorrect(rt2[2])); - tempc[3] = gammaCorrect(fac1 * invGammaCorrect(rt1[3]) + fac2 * invGammaCorrect(rt2[3])); + tempc[0] = gammaCorrect(fac1 * invGammaCorrect(rt1[0]) + fac2 * invGammaCorrect(rt2[0])); + tempc[1] = gammaCorrect(fac1 * invGammaCorrect(rt1[1]) + fac2 * invGammaCorrect(rt2[1])); + tempc[2] = gammaCorrect(fac1 * invGammaCorrect(rt1[2]) + fac2 * invGammaCorrect(rt2[2])); + tempc[3] = gammaCorrect(fac1 * invGammaCorrect(rt1[3]) + fac2 * invGammaCorrect(rt2[3])); - premul_float_to_straight_uchar(rt, tempc); - cp1 += 4; cp2 += 4; rt += 4; - } - } + premul_float_to_straight_uchar(rt, tempc); + cp1 += 4; + cp2 += 4; + rt += 4; + } + } } static void do_gammacross_effect_float( - float facf0, float UNUSED(facf1), int x, int y, float *rect1, - float *rect2, float *out) + float facf0, float UNUSED(facf1), int x, int y, float *rect1, float *rect2, float *out) { - float fac1, fac2; - int xo; - float *rt1, *rt2, *rt; + float fac1, fac2; + int xo; + float *rt1, *rt2, *rt; - xo = x; - rt1 = rect1; - rt2 = rect2; - rt = out; + xo = x; + rt1 = rect1; + rt2 = rect2; + rt = out; - fac2 = facf0; - fac1 = 1.0f - fac2; + fac2 = facf0; + fac1 = 1.0f - fac2; - while (y--) { - x = xo * 4; - while (x--) { - *rt = gammaCorrect(fac1 * invGammaCorrect(*rt1) + fac2 * invGammaCorrect(*rt2)); - rt1++; rt2++; rt++; - } + while (y--) { + x = xo * 4; + while (x--) { + *rt = gammaCorrect(fac1 * invGammaCorrect(*rt1) + fac2 * invGammaCorrect(*rt2)); + rt1++; + rt2++; + rt++; + } - if (y == 0) - break; - y--; + if (y == 0) + break; + y--; - x = xo * 4; - while (x--) { - *rt = gammaCorrect(fac1 * invGammaCorrect(*rt1) + fac2 * invGammaCorrect(*rt2)); + x = xo * 4; + while (x--) { + *rt = gammaCorrect(fac1 * invGammaCorrect(*rt1) + fac2 * invGammaCorrect(*rt2)); - rt1++; rt2++; rt++; - } - } + rt1++; + rt2++; + rt++; + } + } } -static struct ImBuf *gammacross_init_execution(const SeqRenderData *context, ImBuf *ibuf1, ImBuf *ibuf2, ImBuf *ibuf3) +static struct ImBuf *gammacross_init_execution(const SeqRenderData *context, + ImBuf *ibuf1, + ImBuf *ibuf2, + ImBuf *ibuf3) { - ImBuf *out = prepare_effect_imbufs(context, ibuf1, ibuf2, ibuf3); - build_gammatabs(); + ImBuf *out = prepare_effect_imbufs(context, ibuf1, ibuf2, ibuf3); + build_gammatabs(); - return out; + return out; } -static void do_gammacross_effect( - const SeqRenderData *context, Sequence *UNUSED(seq), float UNUSED(cfra), - float facf0, float facf1, ImBuf *ibuf1, ImBuf *ibuf2, ImBuf *UNUSED(ibuf3), - int start_line, int total_lines, ImBuf *out) +static void do_gammacross_effect(const SeqRenderData *context, + Sequence *UNUSED(seq), + float UNUSED(cfra), + float facf0, + float facf1, + ImBuf *ibuf1, + ImBuf *ibuf2, + ImBuf *UNUSED(ibuf3), + int start_line, + int total_lines, + ImBuf *out) { - if (out->rect_float) { - float *rect1 = NULL, *rect2 = NULL, *rect_out = NULL; + if (out->rect_float) { + float *rect1 = NULL, *rect2 = NULL, *rect_out = NULL; - slice_get_float_buffers(context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out); + slice_get_float_buffers( + context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out); - do_gammacross_effect_float(facf0, facf1, context->rectx, total_lines, rect1, rect2, rect_out); - } - else { - unsigned char *rect1 = NULL, *rect2 = NULL, *rect_out = NULL; + do_gammacross_effect_float(facf0, facf1, context->rectx, total_lines, rect1, rect2, rect_out); + } + else { + unsigned char *rect1 = NULL, *rect2 = NULL, *rect_out = NULL; - slice_get_byte_buffers(context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out); + slice_get_byte_buffers( + context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out); - do_gammacross_effect_byte(facf0, facf1, context->rectx, total_lines, rect1, rect2, rect_out); - } + do_gammacross_effect_byte(facf0, facf1, context->rectx, total_lines, rect1, rect2, rect_out); + } } /*********************** Add *************************/ -static void do_add_effect_byte( - float facf0, float facf1, int x, int y, - unsigned char *rect1, unsigned char *rect2, unsigned char *out) -{ - int xo, fac1, fac3; - unsigned char *cp1, *cp2, *rt; - - xo = x; - cp1 = rect1; - cp2 = rect2; - rt = out; - - fac1 = (int)(256.0f * facf0); - fac3 = (int)(256.0f * facf1); - - while (y--) { - x = xo; - - while (x--) { - const int m = fac1 * (int)cp2[3]; - rt[0] = min_ii(cp1[0] + ((m * cp2[0]) >> 16), 255); - rt[1] = min_ii(cp1[1] + ((m * cp2[1]) >> 16), 255); - rt[2] = min_ii(cp1[2] + ((m * cp2[2]) >> 16), 255); - rt[3] = cp1[3]; - - cp1 += 4; cp2 += 4; rt += 4; - } - - if (y == 0) - break; - y--; - - x = xo; - while (x--) { - const int m = fac3 * (int)cp2[3]; - rt[0] = min_ii(cp1[0] + ((m * cp2[0]) >> 16), 255); - rt[1] = min_ii(cp1[1] + ((m * cp2[1]) >> 16), 255); - rt[2] = min_ii(cp1[2] + ((m * cp2[2]) >> 16), 255); - rt[3] = cp1[3]; - - cp1 += 4; cp2 += 4; rt += 4; - } - } -} - -static void do_add_effect_float(float facf0, float facf1, int x, int y, float *rect1, float *rect2, float *out) -{ - int xo; - float fac1, fac3; - float *rt1, *rt2, *rt; - - xo = x; - rt1 = rect1; - rt2 = rect2; - rt = out; - - fac1 = facf0; - fac3 = facf1; - - while (y--) { - x = xo; - while (x--) { - const float m = (1.0f - (rt1[3] * (1.0f - fac1))) * rt2[3]; - rt[0] = rt1[0] + m * rt2[0]; - rt[1] = rt1[1] + m * rt2[1]; - rt[2] = rt1[2] + m * rt2[2]; - rt[3] = rt1[3]; - - rt1 += 4; rt2 += 4; rt += 4; - } - - if (y == 0) - break; - y--; - - x = xo; - while (x--) { - const float m = (1.0f - (rt1[3] * (1.0f - fac3))) * rt2[3]; - rt[0] = rt1[0] + m * rt2[0]; - rt[1] = rt1[1] + m * rt2[1]; - rt[2] = rt1[2] + m * rt2[2]; - rt[3] = rt1[3]; - - rt1 += 4; rt2 += 4; rt += 4; - } - } -} - -static void do_add_effect( - const SeqRenderData *context, Sequence *UNUSED(seq), float UNUSED(cfra), float facf0, float facf1, - ImBuf *ibuf1, ImBuf *ibuf2, ImBuf *UNUSED(ibuf3), int start_line, int total_lines, ImBuf *out) -{ - if (out->rect_float) { - float *rect1 = NULL, *rect2 = NULL, *rect_out = NULL; - - slice_get_float_buffers(context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out); - - do_add_effect_float(facf0, facf1, context->rectx, total_lines, rect1, rect2, rect_out); - } - else { - unsigned char *rect1 = NULL, *rect2 = NULL, *rect_out = NULL; - - slice_get_byte_buffers(context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out); - - do_add_effect_byte(facf0, facf1, context->rectx, total_lines, rect1, rect2, rect_out); - } +static void do_add_effect_byte(float facf0, + float facf1, + int x, + int y, + unsigned char *rect1, + unsigned char *rect2, + unsigned char *out) +{ + int xo, fac1, fac3; + unsigned char *cp1, *cp2, *rt; + + xo = x; + cp1 = rect1; + cp2 = rect2; + rt = out; + + fac1 = (int)(256.0f * facf0); + fac3 = (int)(256.0f * facf1); + + while (y--) { + x = xo; + + while (x--) { + const int m = fac1 * (int)cp2[3]; + rt[0] = min_ii(cp1[0] + ((m * cp2[0]) >> 16), 255); + rt[1] = min_ii(cp1[1] + ((m * cp2[1]) >> 16), 255); + rt[2] = min_ii(cp1[2] + ((m * cp2[2]) >> 16), 255); + rt[3] = cp1[3]; + + cp1 += 4; + cp2 += 4; + rt += 4; + } + + if (y == 0) + break; + y--; + + x = xo; + while (x--) { + const int m = fac3 * (int)cp2[3]; + rt[0] = min_ii(cp1[0] + ((m * cp2[0]) >> 16), 255); + rt[1] = min_ii(cp1[1] + ((m * cp2[1]) >> 16), 255); + rt[2] = min_ii(cp1[2] + ((m * cp2[2]) >> 16), 255); + rt[3] = cp1[3]; + + cp1 += 4; + cp2 += 4; + rt += 4; + } + } +} + +static void do_add_effect_float( + float facf0, float facf1, int x, int y, float *rect1, float *rect2, float *out) +{ + int xo; + float fac1, fac3; + float *rt1, *rt2, *rt; + + xo = x; + rt1 = rect1; + rt2 = rect2; + rt = out; + + fac1 = facf0; + fac3 = facf1; + + while (y--) { + x = xo; + while (x--) { + const float m = (1.0f - (rt1[3] * (1.0f - fac1))) * rt2[3]; + rt[0] = rt1[0] + m * rt2[0]; + rt[1] = rt1[1] + m * rt2[1]; + rt[2] = rt1[2] + m * rt2[2]; + rt[3] = rt1[3]; + + rt1 += 4; + rt2 += 4; + rt += 4; + } + + if (y == 0) + break; + y--; + + x = xo; + while (x--) { + const float m = (1.0f - (rt1[3] * (1.0f - fac3))) * rt2[3]; + rt[0] = rt1[0] + m * rt2[0]; + rt[1] = rt1[1] + m * rt2[1]; + rt[2] = rt1[2] + m * rt2[2]; + rt[3] = rt1[3]; + + rt1 += 4; + rt2 += 4; + rt += 4; + } + } +} + +static void do_add_effect(const SeqRenderData *context, + Sequence *UNUSED(seq), + float UNUSED(cfra), + float facf0, + float facf1, + ImBuf *ibuf1, + ImBuf *ibuf2, + ImBuf *UNUSED(ibuf3), + int start_line, + int total_lines, + ImBuf *out) +{ + if (out->rect_float) { + float *rect1 = NULL, *rect2 = NULL, *rect_out = NULL; + + slice_get_float_buffers( + context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out); + + do_add_effect_float(facf0, facf1, context->rectx, total_lines, rect1, rect2, rect_out); + } + else { + unsigned char *rect1 = NULL, *rect2 = NULL, *rect_out = NULL; + + slice_get_byte_buffers( + context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out); + + do_add_effect_byte(facf0, facf1, context->rectx, total_lines, rect1, rect2, rect_out); + } } /*********************** Sub *************************/ -static void do_sub_effect_byte( - float facf0, float facf1, int x, int y, - unsigned char *rect1, unsigned char *rect2, unsigned char *out) -{ - int xo, fac1, fac3; - unsigned char *cp1, *cp2, *rt; - - xo = x; - cp1 = rect1; - cp2 = rect2; - rt = out; - - fac1 = (int) (256.0f * facf0); - fac3 = (int) (256.0f * facf1); - - while (y--) { - x = xo; - while (x--) { - const int m = fac1 * (int)cp2[3]; - rt[0] = max_ii(cp1[0] - ((m * cp2[0]) >> 16), 0); - rt[1] = max_ii(cp1[1] - ((m * cp2[1]) >> 16), 0); - rt[2] = max_ii(cp1[2] - ((m * cp2[2]) >> 16), 0); - rt[3] = cp1[3]; - - cp1 += 4; cp2 += 4; rt += 4; - } - - if (y == 0) - break; - y--; - - x = xo; - while (x--) { - const int m = fac3 * (int)cp2[3]; - rt[0] = max_ii(cp1[0] - ((m * cp2[0]) >> 16), 0); - rt[1] = max_ii(cp1[1] - ((m * cp2[1]) >> 16), 0); - rt[2] = max_ii(cp1[2] - ((m * cp2[2]) >> 16), 0); - rt[3] = cp1[3]; - - cp1 += 4; cp2 += 4; rt += 4; - } - } +static void do_sub_effect_byte(float facf0, + float facf1, + int x, + int y, + unsigned char *rect1, + unsigned char *rect2, + unsigned char *out) +{ + int xo, fac1, fac3; + unsigned char *cp1, *cp2, *rt; + + xo = x; + cp1 = rect1; + cp2 = rect2; + rt = out; + + fac1 = (int)(256.0f * facf0); + fac3 = (int)(256.0f * facf1); + + while (y--) { + x = xo; + while (x--) { + const int m = fac1 * (int)cp2[3]; + rt[0] = max_ii(cp1[0] - ((m * cp2[0]) >> 16), 0); + rt[1] = max_ii(cp1[1] - ((m * cp2[1]) >> 16), 0); + rt[2] = max_ii(cp1[2] - ((m * cp2[2]) >> 16), 0); + rt[3] = cp1[3]; + + cp1 += 4; + cp2 += 4; + rt += 4; + } + + if (y == 0) + break; + y--; + + x = xo; + while (x--) { + const int m = fac3 * (int)cp2[3]; + rt[0] = max_ii(cp1[0] - ((m * cp2[0]) >> 16), 0); + rt[1] = max_ii(cp1[1] - ((m * cp2[1]) >> 16), 0); + rt[2] = max_ii(cp1[2] - ((m * cp2[2]) >> 16), 0); + rt[3] = cp1[3]; + + cp1 += 4; + cp2 += 4; + rt += 4; + } + } } static void do_sub_effect_float( - float UNUSED(facf0), float facf1, int x, int y, - float *rect1, float *rect2, float *out) -{ - int xo; - float /* fac1, */ fac3_inv; - float *rt1, *rt2, *rt; - - xo = x; - rt1 = rect1; - rt2 = rect2; - rt = out; - - /* UNUSED */ - // fac1 = facf0; - fac3_inv = 1.0f - facf1; - - while (y--) { - x = xo; - while (x--) { - const float m = (1.0f - (rt1[3] * fac3_inv)) * rt2[3]; - rt[0] = max_ff(rt1[0] - m * rt2[0], 0.0f); - rt[1] = max_ff(rt1[1] - m * rt2[1], 0.0f); - rt[2] = max_ff(rt1[2] - m * rt2[2], 0.0f); - rt[3] = rt1[3]; - - rt1 += 4; rt2 += 4; rt += 4; - } - - if (y == 0) - break; - y--; - - x = xo; - while (x--) { - const float m = (1.0f - (rt1[3] * fac3_inv)) * rt2[3]; - rt[0] = max_ff(rt1[0] - m * rt2[0], 0.0f); - rt[1] = max_ff(rt1[1] - m * rt2[1], 0.0f); - rt[2] = max_ff(rt1[2] - m * rt2[2], 0.0f); - rt[3] = rt1[3]; - - rt1 += 4; rt2 += 4; rt += 4; - } - } -} - -static void do_sub_effect( - const SeqRenderData *context, Sequence *UNUSED(seq), float UNUSED(cfra), float facf0, float facf1, - ImBuf *ibuf1, ImBuf *ibuf2, ImBuf *UNUSED(ibuf3), int start_line, int total_lines, ImBuf *out) -{ - if (out->rect_float) { - float *rect1 = NULL, *rect2 = NULL, *rect_out = NULL; - - slice_get_float_buffers(context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out); - - do_sub_effect_float(facf0, facf1, context->rectx, total_lines, rect1, rect2, rect_out); - } - else { - unsigned char *rect1 = NULL, *rect2 = NULL, *rect_out = NULL; - - slice_get_byte_buffers(context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out); - - do_sub_effect_byte(facf0, facf1, context->rectx, total_lines, rect1, rect2, rect_out); - } + float UNUSED(facf0), float facf1, int x, int y, float *rect1, float *rect2, float *out) +{ + int xo; + float /* fac1, */ fac3_inv; + float *rt1, *rt2, *rt; + + xo = x; + rt1 = rect1; + rt2 = rect2; + rt = out; + + /* UNUSED */ + // fac1 = facf0; + fac3_inv = 1.0f - facf1; + + while (y--) { + x = xo; + while (x--) { + const float m = (1.0f - (rt1[3] * fac3_inv)) * rt2[3]; + rt[0] = max_ff(rt1[0] - m * rt2[0], 0.0f); + rt[1] = max_ff(rt1[1] - m * rt2[1], 0.0f); + rt[2] = max_ff(rt1[2] - m * rt2[2], 0.0f); + rt[3] = rt1[3]; + + rt1 += 4; + rt2 += 4; + rt += 4; + } + + if (y == 0) + break; + y--; + + x = xo; + while (x--) { + const float m = (1.0f - (rt1[3] * fac3_inv)) * rt2[3]; + rt[0] = max_ff(rt1[0] - m * rt2[0], 0.0f); + rt[1] = max_ff(rt1[1] - m * rt2[1], 0.0f); + rt[2] = max_ff(rt1[2] - m * rt2[2], 0.0f); + rt[3] = rt1[3]; + + rt1 += 4; + rt2 += 4; + rt += 4; + } + } +} + +static void do_sub_effect(const SeqRenderData *context, + Sequence *UNUSED(seq), + float UNUSED(cfra), + float facf0, + float facf1, + ImBuf *ibuf1, + ImBuf *ibuf2, + ImBuf *UNUSED(ibuf3), + int start_line, + int total_lines, + ImBuf *out) +{ + if (out->rect_float) { + float *rect1 = NULL, *rect2 = NULL, *rect_out = NULL; + + slice_get_float_buffers( + context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out); + + do_sub_effect_float(facf0, facf1, context->rectx, total_lines, rect1, rect2, rect_out); + } + else { + unsigned char *rect1 = NULL, *rect2 = NULL, *rect_out = NULL; + + slice_get_byte_buffers( + context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out); + + do_sub_effect_byte(facf0, facf1, context->rectx, total_lines, rect1, rect2, rect_out); + } } /*********************** Drop *************************/ /* Must be > 0 or add precopy, etc to the function */ -#define XOFF 8 -#define YOFF 8 - -static void do_drop_effect_byte( - float facf0, float facf1, int x, int y, - unsigned char *rect2i, unsigned char *rect1i, unsigned char *outi) -{ - int temp, fac, fac1, fac2; - unsigned char *rt1, *rt2, *out; - int field = 1; - - const int width = x; - const int height = y; - const int xoff = min_ii(XOFF, width); - const int yoff = min_ii(YOFF, height); - - fac1 = (int) (70.0f * facf0); - fac2 = (int) (70.0f * facf1); - - rt2 = rect2i + yoff * 4 * width; - rt1 = rect1i; - out = outi; - for (y = 0; y < height - yoff; y++) { - if (field) fac = fac1; - else fac = fac2; - field = !field; - - memcpy(out, rt1, sizeof(*out) * xoff * 4); - rt1 += xoff * 4; - out += xoff * 4; - - for (x = xoff; x < width; x++) { - temp = ((fac * rt2[3]) >> 8); - - *(out++) = MAX2(0, *rt1 - temp); rt1++; - *(out++) = MAX2(0, *rt1 - temp); rt1++; - *(out++) = MAX2(0, *rt1 - temp); rt1++; - *(out++) = MAX2(0, *rt1 - temp); rt1++; - rt2 += 4; - } - rt2 += xoff * 4; - } - memcpy(out, rt1, sizeof(*out) * yoff * 4 * width); +#define XOFF 8 +#define YOFF 8 + +static void do_drop_effect_byte(float facf0, + float facf1, + int x, + int y, + unsigned char *rect2i, + unsigned char *rect1i, + unsigned char *outi) +{ + int temp, fac, fac1, fac2; + unsigned char *rt1, *rt2, *out; + int field = 1; + + const int width = x; + const int height = y; + const int xoff = min_ii(XOFF, width); + const int yoff = min_ii(YOFF, height); + + fac1 = (int)(70.0f * facf0); + fac2 = (int)(70.0f * facf1); + + rt2 = rect2i + yoff * 4 * width; + rt1 = rect1i; + out = outi; + for (y = 0; y < height - yoff; y++) { + if (field) + fac = fac1; + else + fac = fac2; + field = !field; + + memcpy(out, rt1, sizeof(*out) * xoff * 4); + rt1 += xoff * 4; + out += xoff * 4; + + for (x = xoff; x < width; x++) { + temp = ((fac * rt2[3]) >> 8); + + *(out++) = MAX2(0, *rt1 - temp); + rt1++; + *(out++) = MAX2(0, *rt1 - temp); + rt1++; + *(out++) = MAX2(0, *rt1 - temp); + rt1++; + *(out++) = MAX2(0, *rt1 - temp); + rt1++; + rt2 += 4; + } + rt2 += xoff * 4; + } + memcpy(out, rt1, sizeof(*out) * yoff * 4 * width); } static void do_drop_effect_float( - float facf0, float facf1, int x, int y, - float *rect2i, float *rect1i, float *outi) -{ - float temp, fac, fac1, fac2; - float *rt1, *rt2, *out; - int field = 1; - - const int width = x; - const int height = y; - const int xoff = min_ii(XOFF, width); - const int yoff = min_ii(YOFF, height); - - fac1 = 70.0f * facf0; - fac2 = 70.0f * facf1; - - rt2 = rect2i + yoff * 4 * width; - rt1 = rect1i; - out = outi; - for (y = 0; y < height - yoff; y++) { - if (field) fac = fac1; - else fac = fac2; - field = !field; - - memcpy(out, rt1, sizeof(*out) * xoff * 4); - rt1 += xoff * 4; - out += xoff * 4; - - for (x = xoff; x < width; x++) { - temp = fac * rt2[3]; - - *(out++) = MAX2(0.0f, *rt1 - temp); rt1++; - *(out++) = MAX2(0.0f, *rt1 - temp); rt1++; - *(out++) = MAX2(0.0f, *rt1 - temp); rt1++; - *(out++) = MAX2(0.0f, *rt1 - temp); rt1++; - rt2 += 4; - } - rt2 += xoff * 4; - } - memcpy(out, rt1, sizeof(*out) * yoff * 4 * width); + float facf0, float facf1, int x, int y, float *rect2i, float *rect1i, float *outi) +{ + float temp, fac, fac1, fac2; + float *rt1, *rt2, *out; + int field = 1; + + const int width = x; + const int height = y; + const int xoff = min_ii(XOFF, width); + const int yoff = min_ii(YOFF, height); + + fac1 = 70.0f * facf0; + fac2 = 70.0f * facf1; + + rt2 = rect2i + yoff * 4 * width; + rt1 = rect1i; + out = outi; + for (y = 0; y < height - yoff; y++) { + if (field) + fac = fac1; + else + fac = fac2; + field = !field; + + memcpy(out, rt1, sizeof(*out) * xoff * 4); + rt1 += xoff * 4; + out += xoff * 4; + + for (x = xoff; x < width; x++) { + temp = fac * rt2[3]; + + *(out++) = MAX2(0.0f, *rt1 - temp); + rt1++; + *(out++) = MAX2(0.0f, *rt1 - temp); + rt1++; + *(out++) = MAX2(0.0f, *rt1 - temp); + rt1++; + *(out++) = MAX2(0.0f, *rt1 - temp); + rt1++; + rt2 += 4; + } + rt2 += xoff * 4; + } + memcpy(out, rt1, sizeof(*out) * yoff * 4 * width); } /*********************** Mul *************************/ -static void do_mul_effect_byte( - float facf0, float facf1, int x, int y, - unsigned char *rect1, unsigned char *rect2, unsigned char *out) +static void do_mul_effect_byte(float facf0, + float facf1, + int x, + int y, + unsigned char *rect1, + unsigned char *rect2, + unsigned char *out) { - int xo, fac1, fac3; - unsigned char *rt1, *rt2, *rt; + int xo, fac1, fac3; + unsigned char *rt1, *rt2, *rt; - xo = x; - rt1 = rect1; - rt2 = rect2; - rt = out; + xo = x; + rt1 = rect1; + rt2 = rect2; + rt = out; - fac1 = (int)(256.0f * facf0); - fac3 = (int)(256.0f * facf1); + fac1 = (int)(256.0f * facf0); + fac3 = (int)(256.0f * facf1); - /* formula: - * fac * (a * b) + (1 - fac) * a => fac * a * (b - 1) + axaux = c * px + py * s; //+centx - * yaux = -s * px + c * py; //+centy - */ + /* formula: + * fac * (a * b) + (1 - fac) * a => fac * a * (b - 1) + axaux = c * px + py * s; //+centx + * yaux = -s * px + c * py; //+centy + */ - while (y--) { + while (y--) { - x = xo; - while (x--) { + x = xo; + while (x--) { - rt[0] = rt1[0] + ((fac1 * rt1[0] * (rt2[0] - 255)) >> 16); - rt[1] = rt1[1] + ((fac1 * rt1[1] * (rt2[1] - 255)) >> 16); - rt[2] = rt1[2] + ((fac1 * rt1[2] * (rt2[2] - 255)) >> 16); - rt[3] = rt1[3] + ((fac1 * rt1[3] * (rt2[3] - 255)) >> 16); + rt[0] = rt1[0] + ((fac1 * rt1[0] * (rt2[0] - 255)) >> 16); + rt[1] = rt1[1] + ((fac1 * rt1[1] * (rt2[1] - 255)) >> 16); + rt[2] = rt1[2] + ((fac1 * rt1[2] * (rt2[2] - 255)) >> 16); + rt[3] = rt1[3] + ((fac1 * rt1[3] * (rt2[3] - 255)) >> 16); - rt1 += 4; rt2 += 4; rt += 4; - } + rt1 += 4; + rt2 += 4; + rt += 4; + } - if (y == 0) break; - y--; + if (y == 0) + break; + y--; - x = xo; - while (x--) { + x = xo; + while (x--) { - rt[0] = rt1[0] + ((fac3 * rt1[0] * (rt2[0] - 255)) >> 16); - rt[1] = rt1[1] + ((fac3 * rt1[1] * (rt2[1] - 255)) >> 16); - rt[2] = rt1[2] + ((fac3 * rt1[2] * (rt2[2] - 255)) >> 16); - rt[3] = rt1[3] + ((fac3 * rt1[3] * (rt2[3] - 255)) >> 16); + rt[0] = rt1[0] + ((fac3 * rt1[0] * (rt2[0] - 255)) >> 16); + rt[1] = rt1[1] + ((fac3 * rt1[1] * (rt2[1] - 255)) >> 16); + rt[2] = rt1[2] + ((fac3 * rt1[2] * (rt2[2] - 255)) >> 16); + rt[3] = rt1[3] + ((fac3 * rt1[3] * (rt2[3] - 255)) >> 16); - rt1 += 4; rt2 += 4; rt += 4; - } - } + rt1 += 4; + rt2 += 4; + rt += 4; + } + } } static void do_mul_effect_float( - float facf0, float facf1, int x, int y, - float *rect1, float *rect2, float *out) -{ - int xo; - float fac1, fac3; - float *rt1, *rt2, *rt; - - xo = x; - rt1 = rect1; - rt2 = rect2; - rt = out; - - fac1 = facf0; - fac3 = facf1; - - /* formula: - * fac * (a * b) + (1 - fac) * a => fac * a * (b - 1) + a - */ - - while (y--) { - x = xo; - while (x--) { - rt[0] = rt1[0] + fac1 * rt1[0] * (rt2[0] - 1.0f); - rt[1] = rt1[1] + fac1 * rt1[1] * (rt2[1] - 1.0f); - rt[2] = rt1[2] + fac1 * rt1[2] * (rt2[2] - 1.0f); - rt[3] = rt1[3] + fac1 * rt1[3] * (rt2[3] - 1.0f); - - rt1 += 4; rt2 += 4; rt += 4; - } - - if (y == 0) - break; - y--; - - x = xo; - while (x--) { - rt[0] = rt1[0] + fac3 * rt1[0] * (rt2[0] - 1.0f); - rt[1] = rt1[1] + fac3 * rt1[1] * (rt2[1] - 1.0f); - rt[2] = rt1[2] + fac3 * rt1[2] * (rt2[2] - 1.0f); - rt[3] = rt1[3] + fac3 * rt1[3] * (rt2[3] - 1.0f); - - rt1 += 4; rt2 += 4; rt += 4; - } - } -} - -static void do_mul_effect( - const SeqRenderData *context, Sequence *UNUSED(seq), float UNUSED(cfra), float facf0, float facf1, - ImBuf *ibuf1, ImBuf *ibuf2, ImBuf *UNUSED(ibuf3), int start_line, int total_lines, ImBuf *out) -{ - if (out->rect_float) { - float *rect1 = NULL, *rect2 = NULL, *rect_out = NULL; - - slice_get_float_buffers(context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out); - - do_mul_effect_float(facf0, facf1, context->rectx, total_lines, rect1, rect2, rect_out); - } - else { - unsigned char *rect1 = NULL, *rect2 = NULL, *rect_out = NULL; - - slice_get_byte_buffers(context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out); - - do_mul_effect_byte(facf0, facf1, context->rectx, total_lines, rect1, rect2, rect_out); - } + float facf0, float facf1, int x, int y, float *rect1, float *rect2, float *out) +{ + int xo; + float fac1, fac3; + float *rt1, *rt2, *rt; + + xo = x; + rt1 = rect1; + rt2 = rect2; + rt = out; + + fac1 = facf0; + fac3 = facf1; + + /* formula: + * fac * (a * b) + (1 - fac) * a => fac * a * (b - 1) + a + */ + + while (y--) { + x = xo; + while (x--) { + rt[0] = rt1[0] + fac1 * rt1[0] * (rt2[0] - 1.0f); + rt[1] = rt1[1] + fac1 * rt1[1] * (rt2[1] - 1.0f); + rt[2] = rt1[2] + fac1 * rt1[2] * (rt2[2] - 1.0f); + rt[3] = rt1[3] + fac1 * rt1[3] * (rt2[3] - 1.0f); + + rt1 += 4; + rt2 += 4; + rt += 4; + } + + if (y == 0) + break; + y--; + + x = xo; + while (x--) { + rt[0] = rt1[0] + fac3 * rt1[0] * (rt2[0] - 1.0f); + rt[1] = rt1[1] + fac3 * rt1[1] * (rt2[1] - 1.0f); + rt[2] = rt1[2] + fac3 * rt1[2] * (rt2[2] - 1.0f); + rt[3] = rt1[3] + fac3 * rt1[3] * (rt2[3] - 1.0f); + + rt1 += 4; + rt2 += 4; + rt += 4; + } + } +} + +static void do_mul_effect(const SeqRenderData *context, + Sequence *UNUSED(seq), + float UNUSED(cfra), + float facf0, + float facf1, + ImBuf *ibuf1, + ImBuf *ibuf2, + ImBuf *UNUSED(ibuf3), + int start_line, + int total_lines, + ImBuf *out) +{ + if (out->rect_float) { + float *rect1 = NULL, *rect2 = NULL, *rect_out = NULL; + + slice_get_float_buffers( + context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out); + + do_mul_effect_float(facf0, facf1, context->rectx, total_lines, rect1, rect2, rect_out); + } + else { + unsigned char *rect1 = NULL, *rect2 = NULL, *rect_out = NULL; + + slice_get_byte_buffers( + context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out); + + do_mul_effect_byte(facf0, facf1, context->rectx, total_lines, rect1, rect2, rect_out); + } } /*********************** Blend Mode ***************************************/ -typedef void (*IMB_blend_func_byte)(unsigned char *dst, const unsigned char *src1, const unsigned char *src2); +typedef void (*IMB_blend_func_byte)(unsigned char *dst, + const unsigned char *src1, + const unsigned char *src2); typedef void (*IMB_blend_func_float)(float *dst, const float *src1, const float *src2); -BLI_INLINE void apply_blend_function_byte( - float facf0, float facf1, int x, int y, - unsigned char *rect1, unsigned char *rect2, unsigned char *out, IMB_blend_func_byte blend_function) -{ - int xo; - unsigned char *rt1, *rt2, *rt; - unsigned int achannel; - xo = x; - rt1 = rect1; - rt2 = rect2; - rt = out; - while (y--) { - for (x = xo; x > 0; x--) { - achannel = rt1[3]; - rt1[3] = (unsigned int) achannel * facf0; - blend_function(rt, rt1, rt2); - rt1[3] = achannel; - rt[3] = rt1[3]; - rt1 += 4; - rt2 += 4; - rt += 4; - } - if (y == 0) { - break; - } - y--; - for (x = xo; x > 0; x--) { - achannel = rt1[3]; - rt1[3] = (unsigned int) achannel * facf1; - blend_function(rt, rt1, rt2); - rt1[3] = achannel; - rt[3] = rt1[3]; - rt1 += 4; - rt2 += 4; - rt += 4; - } - } -} - -BLI_INLINE void apply_blend_function_float( - float facf0, float facf1, int x, int y, - float *rect1, float *rect2, float *out, IMB_blend_func_float blend_function) -{ - int xo; - float *rt1, *rt2, *rt; - float achannel; - xo = x; - rt1 = rect1; - rt2 = rect2; - rt = out; - while (y--) { - for (x = xo; x > 0; x--) { - achannel = rt1[3]; - rt1[3] = achannel * facf0; - blend_function(rt, rt1, rt2); - rt1[3] = achannel; - rt[3] = rt1[3]; - rt1 += 4; - rt2 += 4; - rt += 4; - } - if (y == 0) { - break; - } - y--; - for (x = xo; x > 0; x--) { - achannel = rt1[3]; - rt1[3] = achannel * facf1; - blend_function(rt, rt1, rt2); - rt1[3] = achannel; - rt[3] = rt1[3]; - rt1 += 4; - rt2 += 4; - rt += 4; - } - } +BLI_INLINE void apply_blend_function_byte(float facf0, + float facf1, + int x, + int y, + unsigned char *rect1, + unsigned char *rect2, + unsigned char *out, + IMB_blend_func_byte blend_function) +{ + int xo; + unsigned char *rt1, *rt2, *rt; + unsigned int achannel; + xo = x; + rt1 = rect1; + rt2 = rect2; + rt = out; + while (y--) { + for (x = xo; x > 0; x--) { + achannel = rt1[3]; + rt1[3] = (unsigned int)achannel * facf0; + blend_function(rt, rt1, rt2); + rt1[3] = achannel; + rt[3] = rt1[3]; + rt1 += 4; + rt2 += 4; + rt += 4; + } + if (y == 0) { + break; + } + y--; + for (x = xo; x > 0; x--) { + achannel = rt1[3]; + rt1[3] = (unsigned int)achannel * facf1; + blend_function(rt, rt1, rt2); + rt1[3] = achannel; + rt[3] = rt1[3]; + rt1 += 4; + rt2 += 4; + rt += 4; + } + } +} + +BLI_INLINE void apply_blend_function_float(float facf0, + float facf1, + int x, + int y, + float *rect1, + float *rect2, + float *out, + IMB_blend_func_float blend_function) +{ + int xo; + float *rt1, *rt2, *rt; + float achannel; + xo = x; + rt1 = rect1; + rt2 = rect2; + rt = out; + while (y--) { + for (x = xo; x > 0; x--) { + achannel = rt1[3]; + rt1[3] = achannel * facf0; + blend_function(rt, rt1, rt2); + rt1[3] = achannel; + rt[3] = rt1[3]; + rt1 += 4; + rt2 += 4; + rt += 4; + } + if (y == 0) { + break; + } + y--; + for (x = xo; x > 0; x--) { + achannel = rt1[3]; + rt1[3] = achannel * facf1; + blend_function(rt, rt1, rt2); + rt1[3] = achannel; + rt[3] = rt1[3]; + rt1 += 4; + rt2 += 4; + rt += 4; + } + } } static void do_blend_effect_float( - float facf0, float facf1, int x, int y, - float *rect1, float *rect2, int btype, float *out) -{ - switch (btype) { - case SEQ_TYPE_ADD: - apply_blend_function_float(facf0, facf1, x, y, rect1, rect2, out, blend_color_add_float); - break; - case SEQ_TYPE_SUB: - apply_blend_function_float(facf0, facf1, x, y, rect1, rect2, out, blend_color_sub_float); - break; - case SEQ_TYPE_MUL: - apply_blend_function_float(facf0, facf1, x, y, rect1, rect2, out, blend_color_mul_float); - break; - case SEQ_TYPE_DARKEN: - apply_blend_function_float(facf0, facf1, x, y, rect1, rect2, out, blend_color_darken_float); - break; - case SEQ_TYPE_BURN: - apply_blend_function_float(facf0, facf1, x, y, rect1, rect2, out, blend_color_burn_float); - break; - case SEQ_TYPE_LINEAR_BURN: - apply_blend_function_float(facf0, facf1, x, y, rect1, rect2, out, blend_color_linearburn_float); - break; - case SEQ_TYPE_SCREEN: - apply_blend_function_float(facf0, facf1, x, y, rect1, rect2, out, blend_color_screen_float); - break; - case SEQ_TYPE_LIGHTEN: - apply_blend_function_float(facf0, facf1, x, y, rect1, rect2, out, blend_color_lighten_float); - break; - case SEQ_TYPE_DODGE: - apply_blend_function_float(facf0, facf1, x, y, rect1, rect2, out, blend_color_dodge_float); - break; - case SEQ_TYPE_OVERLAY: - apply_blend_function_float(facf0, facf1, x, y, rect1, rect2, out, blend_color_overlay_float); - break; - case SEQ_TYPE_SOFT_LIGHT: - apply_blend_function_float(facf0, facf1, x, y, rect1, rect2, out, blend_color_softlight_float); - break; - case SEQ_TYPE_HARD_LIGHT: - apply_blend_function_float(facf0, facf1, x, y, rect1, rect2, out, blend_color_hardlight_float); - break; - case SEQ_TYPE_PIN_LIGHT: - apply_blend_function_float(facf0, facf1, x, y, rect1, rect2, out, blend_color_pinlight_float); - break; - case SEQ_TYPE_LIN_LIGHT: - apply_blend_function_float(facf0, facf1, x, y, rect1, rect2, out, blend_color_linearlight_float); - break; - case SEQ_TYPE_VIVID_LIGHT: - apply_blend_function_float(facf0, facf1, x, y, rect1, rect2, out, blend_color_vividlight_float); - break; - case SEQ_TYPE_BLEND_COLOR: - apply_blend_function_float(facf0, facf1, x, y, rect1, rect2, out, blend_color_color_float); - break; - case SEQ_TYPE_HUE: - apply_blend_function_float(facf0, facf1, x, y, rect1, rect2, out, blend_color_hue_float); - break; - case SEQ_TYPE_SATURATION: - apply_blend_function_float(facf0, facf1, x, y, rect1, rect2, out, blend_color_saturation_float); - break; - case SEQ_TYPE_VALUE: - apply_blend_function_float(facf0, facf1, x, y, rect1, rect2, out, blend_color_luminosity_float); - break; - case SEQ_TYPE_DIFFERENCE: - apply_blend_function_float(facf0, facf1, x, y, rect1, rect2, out, blend_color_difference_float); - break; - case SEQ_TYPE_EXCLUSION: - apply_blend_function_float(facf0, facf1, x, y, rect1, rect2, out, blend_color_exclusion_float); - break; - default: - break; - } -} - -static void do_blend_effect_byte( - float facf0, float facf1, int x, int y, - unsigned char *rect1, unsigned char *rect2, int btype, unsigned char *out) -{ - switch (btype) { - case SEQ_TYPE_ADD: - apply_blend_function_byte(facf0, facf1, x, y, rect1, rect2, out, blend_color_add_byte); - break; - case SEQ_TYPE_SUB: - apply_blend_function_byte(facf0, facf1, x, y, rect1, rect2, out, blend_color_sub_byte); - break; - case SEQ_TYPE_MUL: - apply_blend_function_byte(facf0, facf1, x, y, rect1, rect2, out, blend_color_mul_byte); - break; - case SEQ_TYPE_DARKEN: - apply_blend_function_byte(facf0, facf1, x, y, rect1, rect2, out, blend_color_darken_byte); - break; - case SEQ_TYPE_BURN: - apply_blend_function_byte(facf0, facf1, x, y, rect1, rect2, out, blend_color_burn_byte); - break; - case SEQ_TYPE_LINEAR_BURN: - apply_blend_function_byte(facf0, facf1, x, y, rect1, rect2, out, blend_color_linearburn_byte); - break; - case SEQ_TYPE_SCREEN: - apply_blend_function_byte(facf0, facf1, x, y, rect1, rect2, out, blend_color_screen_byte); - break; - case SEQ_TYPE_LIGHTEN: - apply_blend_function_byte(facf0, facf1, x, y, rect1, rect2, out, blend_color_lighten_byte); - break; - case SEQ_TYPE_DODGE: - apply_blend_function_byte(facf0, facf1, x, y, rect1, rect2, out, blend_color_dodge_byte); - break; - case SEQ_TYPE_OVERLAY: - apply_blend_function_byte(facf0, facf1, x, y, rect1, rect2, out, blend_color_overlay_byte); - break; - case SEQ_TYPE_SOFT_LIGHT: - apply_blend_function_byte(facf0, facf1, x, y, rect1, rect2, out, blend_color_softlight_byte); - break; - case SEQ_TYPE_HARD_LIGHT: - apply_blend_function_byte(facf0, facf1, x, y, rect1, rect2, out, blend_color_hardlight_byte); - break; - case SEQ_TYPE_PIN_LIGHT: - apply_blend_function_byte(facf0, facf1, x, y, rect1, rect2, out, blend_color_pinlight_byte); - break; - case SEQ_TYPE_LIN_LIGHT: - apply_blend_function_byte(facf0, facf1, x, y, rect1, rect2, out, blend_color_linearlight_byte); - break; - case SEQ_TYPE_VIVID_LIGHT: - apply_blend_function_byte(facf0, facf1, x, y, rect1, rect2, out, blend_color_vividlight_byte); - break; - case SEQ_TYPE_BLEND_COLOR: - apply_blend_function_byte(facf0, facf1, x, y, rect1, rect2, out, blend_color_color_byte); - break; - case SEQ_TYPE_HUE: - apply_blend_function_byte(facf0, facf1, x, y, rect1, rect2, out, blend_color_hue_byte); - break; - case SEQ_TYPE_SATURATION: - apply_blend_function_byte(facf0, facf1, x, y, rect1, rect2, out, blend_color_saturation_byte); - break; - case SEQ_TYPE_VALUE: - apply_blend_function_byte(facf0, facf1, x, y, rect1, rect2, out, blend_color_luminosity_byte); - break; - case SEQ_TYPE_DIFFERENCE: - apply_blend_function_byte(facf0, facf1, x, y, rect1, rect2, out, blend_color_difference_byte); - break; - case SEQ_TYPE_EXCLUSION: - apply_blend_function_byte(facf0, facf1, x, y, rect1, rect2, out, blend_color_exclusion_byte); - break; - default: - break; - } -} - -static void do_blend_mode_effect( - const SeqRenderData *context, Sequence *seq, float UNUSED(cfra), float facf0, float facf1, - ImBuf *ibuf1, ImBuf *ibuf2, ImBuf *UNUSED(ibuf3), int start_line, int total_lines, ImBuf *out) -{ - if (out->rect_float) { - float *rect1 = NULL, *rect2 = NULL, *rect_out = NULL; - slice_get_float_buffers(context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out); - do_blend_effect_float(facf0, facf1, context->rectx, total_lines, rect1, rect2, seq->blend_mode, rect_out); - } - else { - unsigned char *rect1 = NULL, *rect2 = NULL, *rect_out = NULL; - slice_get_byte_buffers(context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out); - do_blend_effect_byte(facf0, facf1, context->rectx, total_lines, rect1, rect2, seq->blend_mode, rect_out); - } + float facf0, float facf1, int x, int y, float *rect1, float *rect2, int btype, float *out) +{ + switch (btype) { + case SEQ_TYPE_ADD: + apply_blend_function_float(facf0, facf1, x, y, rect1, rect2, out, blend_color_add_float); + break; + case SEQ_TYPE_SUB: + apply_blend_function_float(facf0, facf1, x, y, rect1, rect2, out, blend_color_sub_float); + break; + case SEQ_TYPE_MUL: + apply_blend_function_float(facf0, facf1, x, y, rect1, rect2, out, blend_color_mul_float); + break; + case SEQ_TYPE_DARKEN: + apply_blend_function_float(facf0, facf1, x, y, rect1, rect2, out, blend_color_darken_float); + break; + case SEQ_TYPE_BURN: + apply_blend_function_float(facf0, facf1, x, y, rect1, rect2, out, blend_color_burn_float); + break; + case SEQ_TYPE_LINEAR_BURN: + apply_blend_function_float( + facf0, facf1, x, y, rect1, rect2, out, blend_color_linearburn_float); + break; + case SEQ_TYPE_SCREEN: + apply_blend_function_float(facf0, facf1, x, y, rect1, rect2, out, blend_color_screen_float); + break; + case SEQ_TYPE_LIGHTEN: + apply_blend_function_float(facf0, facf1, x, y, rect1, rect2, out, blend_color_lighten_float); + break; + case SEQ_TYPE_DODGE: + apply_blend_function_float(facf0, facf1, x, y, rect1, rect2, out, blend_color_dodge_float); + break; + case SEQ_TYPE_OVERLAY: + apply_blend_function_float(facf0, facf1, x, y, rect1, rect2, out, blend_color_overlay_float); + break; + case SEQ_TYPE_SOFT_LIGHT: + apply_blend_function_float( + facf0, facf1, x, y, rect1, rect2, out, blend_color_softlight_float); + break; + case SEQ_TYPE_HARD_LIGHT: + apply_blend_function_float( + facf0, facf1, x, y, rect1, rect2, out, blend_color_hardlight_float); + break; + case SEQ_TYPE_PIN_LIGHT: + apply_blend_function_float( + facf0, facf1, x, y, rect1, rect2, out, blend_color_pinlight_float); + break; + case SEQ_TYPE_LIN_LIGHT: + apply_blend_function_float( + facf0, facf1, x, y, rect1, rect2, out, blend_color_linearlight_float); + break; + case SEQ_TYPE_VIVID_LIGHT: + apply_blend_function_float( + facf0, facf1, x, y, rect1, rect2, out, blend_color_vividlight_float); + break; + case SEQ_TYPE_BLEND_COLOR: + apply_blend_function_float(facf0, facf1, x, y, rect1, rect2, out, blend_color_color_float); + break; + case SEQ_TYPE_HUE: + apply_blend_function_float(facf0, facf1, x, y, rect1, rect2, out, blend_color_hue_float); + break; + case SEQ_TYPE_SATURATION: + apply_blend_function_float( + facf0, facf1, x, y, rect1, rect2, out, blend_color_saturation_float); + break; + case SEQ_TYPE_VALUE: + apply_blend_function_float( + facf0, facf1, x, y, rect1, rect2, out, blend_color_luminosity_float); + break; + case SEQ_TYPE_DIFFERENCE: + apply_blend_function_float( + facf0, facf1, x, y, rect1, rect2, out, blend_color_difference_float); + break; + case SEQ_TYPE_EXCLUSION: + apply_blend_function_float( + facf0, facf1, x, y, rect1, rect2, out, blend_color_exclusion_float); + break; + default: + break; + } +} + +static void do_blend_effect_byte(float facf0, + float facf1, + int x, + int y, + unsigned char *rect1, + unsigned char *rect2, + int btype, + unsigned char *out) +{ + switch (btype) { + case SEQ_TYPE_ADD: + apply_blend_function_byte(facf0, facf1, x, y, rect1, rect2, out, blend_color_add_byte); + break; + case SEQ_TYPE_SUB: + apply_blend_function_byte(facf0, facf1, x, y, rect1, rect2, out, blend_color_sub_byte); + break; + case SEQ_TYPE_MUL: + apply_blend_function_byte(facf0, facf1, x, y, rect1, rect2, out, blend_color_mul_byte); + break; + case SEQ_TYPE_DARKEN: + apply_blend_function_byte(facf0, facf1, x, y, rect1, rect2, out, blend_color_darken_byte); + break; + case SEQ_TYPE_BURN: + apply_blend_function_byte(facf0, facf1, x, y, rect1, rect2, out, blend_color_burn_byte); + break; + case SEQ_TYPE_LINEAR_BURN: + apply_blend_function_byte( + facf0, facf1, x, y, rect1, rect2, out, blend_color_linearburn_byte); + break; + case SEQ_TYPE_SCREEN: + apply_blend_function_byte(facf0, facf1, x, y, rect1, rect2, out, blend_color_screen_byte); + break; + case SEQ_TYPE_LIGHTEN: + apply_blend_function_byte(facf0, facf1, x, y, rect1, rect2, out, blend_color_lighten_byte); + break; + case SEQ_TYPE_DODGE: + apply_blend_function_byte(facf0, facf1, x, y, rect1, rect2, out, blend_color_dodge_byte); + break; + case SEQ_TYPE_OVERLAY: + apply_blend_function_byte(facf0, facf1, x, y, rect1, rect2, out, blend_color_overlay_byte); + break; + case SEQ_TYPE_SOFT_LIGHT: + apply_blend_function_byte(facf0, facf1, x, y, rect1, rect2, out, blend_color_softlight_byte); + break; + case SEQ_TYPE_HARD_LIGHT: + apply_blend_function_byte(facf0, facf1, x, y, rect1, rect2, out, blend_color_hardlight_byte); + break; + case SEQ_TYPE_PIN_LIGHT: + apply_blend_function_byte(facf0, facf1, x, y, rect1, rect2, out, blend_color_pinlight_byte); + break; + case SEQ_TYPE_LIN_LIGHT: + apply_blend_function_byte( + facf0, facf1, x, y, rect1, rect2, out, blend_color_linearlight_byte); + break; + case SEQ_TYPE_VIVID_LIGHT: + apply_blend_function_byte( + facf0, facf1, x, y, rect1, rect2, out, blend_color_vividlight_byte); + break; + case SEQ_TYPE_BLEND_COLOR: + apply_blend_function_byte(facf0, facf1, x, y, rect1, rect2, out, blend_color_color_byte); + break; + case SEQ_TYPE_HUE: + apply_blend_function_byte(facf0, facf1, x, y, rect1, rect2, out, blend_color_hue_byte); + break; + case SEQ_TYPE_SATURATION: + apply_blend_function_byte( + facf0, facf1, x, y, rect1, rect2, out, blend_color_saturation_byte); + break; + case SEQ_TYPE_VALUE: + apply_blend_function_byte( + facf0, facf1, x, y, rect1, rect2, out, blend_color_luminosity_byte); + break; + case SEQ_TYPE_DIFFERENCE: + apply_blend_function_byte( + facf0, facf1, x, y, rect1, rect2, out, blend_color_difference_byte); + break; + case SEQ_TYPE_EXCLUSION: + apply_blend_function_byte(facf0, facf1, x, y, rect1, rect2, out, blend_color_exclusion_byte); + break; + default: + break; + } +} + +static void do_blend_mode_effect(const SeqRenderData *context, + Sequence *seq, + float UNUSED(cfra), + float facf0, + float facf1, + ImBuf *ibuf1, + ImBuf *ibuf2, + ImBuf *UNUSED(ibuf3), + int start_line, + int total_lines, + ImBuf *out) +{ + if (out->rect_float) { + float *rect1 = NULL, *rect2 = NULL, *rect_out = NULL; + slice_get_float_buffers( + context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out); + do_blend_effect_float( + facf0, facf1, context->rectx, total_lines, rect1, rect2, seq->blend_mode, rect_out); + } + else { + unsigned char *rect1 = NULL, *rect2 = NULL, *rect_out = NULL; + slice_get_byte_buffers( + context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out); + do_blend_effect_byte( + facf0, facf1, context->rectx, total_lines, rect1, rect2, seq->blend_mode, rect_out); + } } /*********************** Color Mix Effect *************************/ static void init_colormix_effect(Sequence *seq) { - ColorMixVars *data; - - if (seq->effectdata) { - MEM_freeN(seq->effectdata); - } - seq->effectdata = MEM_callocN(sizeof(ColorMixVars), "colormixvars"); - data = (ColorMixVars *) seq->effectdata; - data->blend_effect = SEQ_TYPE_OVERLAY; - data->factor = 1.0f; -} - -static void do_colormix_effect( - const SeqRenderData *context, Sequence *seq, float UNUSED(cfra), float UNUSED(facf0), float UNUSED(facf1), - ImBuf *ibuf1, ImBuf *ibuf2, ImBuf *UNUSED(ibuf3), int start_line, int total_lines, ImBuf *out) -{ - float facf; - - ColorMixVars *data = seq->effectdata; - facf = data->factor; - - if (out->rect_float) { - float *rect1 = NULL, *rect2 = NULL, *rect_out = NULL; - slice_get_float_buffers(context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out); - do_blend_effect_float(facf, facf, context->rectx, total_lines, rect1, rect2, data->blend_effect, rect_out); - } - else { - unsigned char *rect1 = NULL, *rect2 = NULL, *rect_out = NULL; - slice_get_byte_buffers(context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out); - do_blend_effect_byte(facf, facf, context->rectx, total_lines, rect1, rect2, data->blend_effect, rect_out); - } + ColorMixVars *data; + + if (seq->effectdata) { + MEM_freeN(seq->effectdata); + } + seq->effectdata = MEM_callocN(sizeof(ColorMixVars), "colormixvars"); + data = (ColorMixVars *)seq->effectdata; + data->blend_effect = SEQ_TYPE_OVERLAY; + data->factor = 1.0f; +} + +static void do_colormix_effect(const SeqRenderData *context, + Sequence *seq, + float UNUSED(cfra), + float UNUSED(facf0), + float UNUSED(facf1), + ImBuf *ibuf1, + ImBuf *ibuf2, + ImBuf *UNUSED(ibuf3), + int start_line, + int total_lines, + ImBuf *out) +{ + float facf; + + ColorMixVars *data = seq->effectdata; + facf = data->factor; + + if (out->rect_float) { + float *rect1 = NULL, *rect2 = NULL, *rect_out = NULL; + slice_get_float_buffers( + context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out); + do_blend_effect_float( + facf, facf, context->rectx, total_lines, rect1, rect2, data->blend_effect, rect_out); + } + else { + unsigned char *rect1 = NULL, *rect2 = NULL, *rect_out = NULL; + slice_get_byte_buffers( + context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out); + do_blend_effect_byte( + facf, facf, context->rectx, total_lines, rect1, rect2, data->blend_effect, rect_out); + } } /*********************** Wipe *************************/ typedef struct WipeZone { - float angle; - int flip; - int xo, yo; - int width; - float pythangle; + float angle; + int flip; + int xo, yo; + int width; + float pythangle; } WipeZone; static void precalc_wipe_zone(WipeZone *wipezone, WipeVars *wipe, int xo, int yo) { - wipezone->flip = (wipe->angle < 0.0f); - wipezone->angle = tanf(fabsf(wipe->angle)); - wipezone->xo = xo; - wipezone->yo = yo; - wipezone->width = (int)(wipe->edgeWidth * ((xo + yo) / 2.0f)); - wipezone->pythangle = 1.0f / sqrtf(wipezone->angle * wipezone->angle + 1.0f); + wipezone->flip = (wipe->angle < 0.0f); + wipezone->angle = tanf(fabsf(wipe->angle)); + wipezone->xo = xo; + wipezone->yo = yo; + wipezone->width = (int)(wipe->edgeWidth * ((xo + yo) / 2.0f)); + wipezone->pythangle = 1.0f / sqrtf(wipezone->angle * wipezone->angle + 1.0f); } /* This function calculates the blur band for the wipe effects */ static float in_band(float width, float dist, int side, int dir) { - float alpha; + float alpha; - if (width == 0) - return (float)side; + if (width == 0) + return (float)side; - if (width < dist) - return (float)side; + if (width < dist) + return (float)side; - if (side == 1) - alpha = (dist + 0.5f * width) / (width); - else - alpha = (0.5f * width - dist) / (width); + if (side == 1) + alpha = (dist + 0.5f * width) / (width); + else + alpha = (0.5f * width - dist) / (width); - if (dir == 0) - alpha = 1 - alpha; + if (dir == 0) + alpha = 1 - alpha; - return alpha; + return alpha; } static float check_zone(WipeZone *wipezone, int x, int y, Sequence *seq, float facf0) { - float posx, posy, hyp, hyp2, angle, hwidth, b1, b2, b3, pointdist; - /* some future stuff */ - /* float hyp3, hyp4, b4, b5 */ - float temp1, temp2, temp3, temp4; /* some placeholder variables */ - int xo = wipezone->xo; - int yo = wipezone->yo; - float halfx = xo * 0.5f; - float halfy = yo * 0.5f; - float widthf, output = 0; - WipeVars *wipe = (WipeVars *)seq->effectdata; - int width; - - if (wipezone->flip) x = xo - x; - angle = wipezone->angle; - - if (wipe->forward) { - posx = facf0 * xo; - posy = facf0 * yo; - } - else { - posx = xo - facf0 * xo; - posy = yo - facf0 * yo; - } - - switch (wipe->wipetype) { - case DO_SINGLE_WIPE: - width = min_ii(wipezone->width, facf0 * yo); - width = min_ii(width, yo - facf0 * yo); - - if (angle == 0.0f) { - b1 = posy; - b2 = y; - hyp = fabsf(y - posy); - } - else { - b1 = posy - (-angle) * posx; - b2 = y - (-angle) * x; - hyp = fabsf(angle * x + y + (-posy - angle * posx)) * wipezone->pythangle; - } - - if (angle < 0) { - temp1 = b1; - b1 = b2; - b2 = temp1; - } - - if (wipe->forward) { - if (b1 < b2) - output = in_band(width, hyp, 1, 1); - else - output = in_band(width, hyp, 0, 1); - } - else { - if (b1 < b2) - output = in_band(width, hyp, 0, 1); - else - output = in_band(width, hyp, 1, 1); - } - break; - - case DO_DOUBLE_WIPE: - if (!wipe->forward) - facf0 = 1.0f - facf0; /* Go the other direction */ - - width = wipezone->width; /* calculate the blur width */ - hwidth = width * 0.5f; - if (angle == 0) { - b1 = posy * 0.5f; - b3 = yo - posy * 0.5f; - b2 = y; - - hyp = fabsf(y - posy * 0.5f); - hyp2 = fabsf(y - (yo - posy * 0.5f)); - } - else { - b1 = posy * 0.5f - (-angle) * posx * 0.5f; - b3 = (yo - posy * 0.5f) - (-angle) * (xo - posx * 0.5f); - b2 = y - (-angle) * x; - - hyp = fabsf(angle * x + y + (-posy * 0.5f - angle * posx * 0.5f)) * wipezone->pythangle; - hyp2 = fabsf(angle * x + y + (-(yo - posy * 0.5f) - angle * (xo - posx * 0.5f))) * wipezone->pythangle; - } - - hwidth = min_ff(hwidth, fabsf(b3 - b1) / 2.0f); - - if (b2 < b1 && b2 < b3) { - output = in_band(hwidth, hyp, 0, 1); - } - else if (b2 > b1 && b2 > b3) { - output = in_band(hwidth, hyp2, 0, 1); - } - else { - if (hyp < hwidth && hyp2 > hwidth) - output = in_band(hwidth, hyp, 1, 1); - else if (hyp > hwidth && hyp2 < hwidth) - output = in_band(hwidth, hyp2, 1, 1); - else - output = in_band(hwidth, hyp2, 1, 1) * in_band(hwidth, hyp, 1, 1); - } - if (!wipe->forward) output = 1 - output; - break; - case DO_CLOCK_WIPE: - /* - * temp1: angle of effect center in rads - * temp2: angle of line through (halfx, halfy) and (x, y) in rads - * temp3: angle of low side of blur - * temp4: angle of high side of blur - */ - output = 1.0f - facf0; - widthf = wipe->edgeWidth * 2.0f * (float)M_PI; - temp1 = 2.0f * (float)M_PI * facf0; - - if (wipe->forward) { - temp1 = 2.0f * (float)M_PI - temp1; - } - - x = x - halfx; - y = y - halfy; - - temp2 = asin(abs(y) / hypot(x, y)); - if (x <= 0 && y >= 0) temp2 = (float)M_PI - temp2; - else if (x <= 0 && y <= 0) temp2 += (float)M_PI; - else if (x >= 0 && y <= 0) temp2 = 2.0f * (float)M_PI - temp2; - - if (wipe->forward) { - temp3 = temp1 - (widthf * 0.5f) * facf0; - temp4 = temp1 + (widthf * 0.5f) * (1 - facf0); - } - else { - temp3 = temp1 - (widthf * 0.5f) * (1 - facf0); - temp4 = temp1 + (widthf * 0.5f) * facf0; - } - if (temp3 < 0) temp3 = 0; - if (temp4 > 2.0f * (float)M_PI) temp4 = 2.0f * (float)M_PI; - - - if (temp2 < temp3) output = 0; - else if (temp2 > temp4) output = 1; - else output = (temp2 - temp3) / (temp4 - temp3); - if (x == 0 && y == 0) output = 1; - if (output != output) output = 1; - if (wipe->forward) output = 1 - output; - break; - case DO_IRIS_WIPE: - if (xo > yo) yo = xo; - else xo = yo; - - if (!wipe->forward) facf0 = 1 - facf0; - - width = wipezone->width; - hwidth = width * 0.5f; - - temp1 = (halfx - (halfx) * facf0); - pointdist = hypotf(temp1, temp1); - - temp2 = hypotf(halfx - x, halfy - y); - if (temp2 > pointdist) output = in_band(hwidth, fabsf(temp2 - pointdist), 0, 1); - else output = in_band(hwidth, fabsf(temp2 - pointdist), 1, 1); - - if (!wipe->forward) output = 1 - output; - - break; - } - if (output < 0) output = 0; - else if (output > 1) output = 1; - return output; + float posx, posy, hyp, hyp2, angle, hwidth, b1, b2, b3, pointdist; + /* some future stuff */ + /* float hyp3, hyp4, b4, b5 */ + float temp1, temp2, temp3, temp4; /* some placeholder variables */ + int xo = wipezone->xo; + int yo = wipezone->yo; + float halfx = xo * 0.5f; + float halfy = yo * 0.5f; + float widthf, output = 0; + WipeVars *wipe = (WipeVars *)seq->effectdata; + int width; + + if (wipezone->flip) + x = xo - x; + angle = wipezone->angle; + + if (wipe->forward) { + posx = facf0 * xo; + posy = facf0 * yo; + } + else { + posx = xo - facf0 * xo; + posy = yo - facf0 * yo; + } + + switch (wipe->wipetype) { + case DO_SINGLE_WIPE: + width = min_ii(wipezone->width, facf0 * yo); + width = min_ii(width, yo - facf0 * yo); + + if (angle == 0.0f) { + b1 = posy; + b2 = y; + hyp = fabsf(y - posy); + } + else { + b1 = posy - (-angle) * posx; + b2 = y - (-angle) * x; + hyp = fabsf(angle * x + y + (-posy - angle * posx)) * wipezone->pythangle; + } + + if (angle < 0) { + temp1 = b1; + b1 = b2; + b2 = temp1; + } + + if (wipe->forward) { + if (b1 < b2) + output = in_band(width, hyp, 1, 1); + else + output = in_band(width, hyp, 0, 1); + } + else { + if (b1 < b2) + output = in_band(width, hyp, 0, 1); + else + output = in_band(width, hyp, 1, 1); + } + break; + + case DO_DOUBLE_WIPE: + if (!wipe->forward) + facf0 = 1.0f - facf0; /* Go the other direction */ + + width = wipezone->width; /* calculate the blur width */ + hwidth = width * 0.5f; + if (angle == 0) { + b1 = posy * 0.5f; + b3 = yo - posy * 0.5f; + b2 = y; + + hyp = fabsf(y - posy * 0.5f); + hyp2 = fabsf(y - (yo - posy * 0.5f)); + } + else { + b1 = posy * 0.5f - (-angle) * posx * 0.5f; + b3 = (yo - posy * 0.5f) - (-angle) * (xo - posx * 0.5f); + b2 = y - (-angle) * x; + + hyp = fabsf(angle * x + y + (-posy * 0.5f - angle * posx * 0.5f)) * wipezone->pythangle; + hyp2 = fabsf(angle * x + y + (-(yo - posy * 0.5f) - angle * (xo - posx * 0.5f))) * + wipezone->pythangle; + } + + hwidth = min_ff(hwidth, fabsf(b3 - b1) / 2.0f); + + if (b2 < b1 && b2 < b3) { + output = in_band(hwidth, hyp, 0, 1); + } + else if (b2 > b1 && b2 > b3) { + output = in_band(hwidth, hyp2, 0, 1); + } + else { + if (hyp < hwidth && hyp2 > hwidth) + output = in_band(hwidth, hyp, 1, 1); + else if (hyp > hwidth && hyp2 < hwidth) + output = in_band(hwidth, hyp2, 1, 1); + else + output = in_band(hwidth, hyp2, 1, 1) * in_band(hwidth, hyp, 1, 1); + } + if (!wipe->forward) + output = 1 - output; + break; + case DO_CLOCK_WIPE: + /* + * temp1: angle of effect center in rads + * temp2: angle of line through (halfx, halfy) and (x, y) in rads + * temp3: angle of low side of blur + * temp4: angle of high side of blur + */ + output = 1.0f - facf0; + widthf = wipe->edgeWidth * 2.0f * (float)M_PI; + temp1 = 2.0f * (float)M_PI * facf0; + + if (wipe->forward) { + temp1 = 2.0f * (float)M_PI - temp1; + } + + x = x - halfx; + y = y - halfy; + + temp2 = asin(abs(y) / hypot(x, y)); + if (x <= 0 && y >= 0) + temp2 = (float)M_PI - temp2; + else if (x <= 0 && y <= 0) + temp2 += (float)M_PI; + else if (x >= 0 && y <= 0) + temp2 = 2.0f * (float)M_PI - temp2; + + if (wipe->forward) { + temp3 = temp1 - (widthf * 0.5f) * facf0; + temp4 = temp1 + (widthf * 0.5f) * (1 - facf0); + } + else { + temp3 = temp1 - (widthf * 0.5f) * (1 - facf0); + temp4 = temp1 + (widthf * 0.5f) * facf0; + } + if (temp3 < 0) + temp3 = 0; + if (temp4 > 2.0f * (float)M_PI) + temp4 = 2.0f * (float)M_PI; + + if (temp2 < temp3) + output = 0; + else if (temp2 > temp4) + output = 1; + else + output = (temp2 - temp3) / (temp4 - temp3); + if (x == 0 && y == 0) + output = 1; + if (output != output) + output = 1; + if (wipe->forward) + output = 1 - output; + break; + case DO_IRIS_WIPE: + if (xo > yo) + yo = xo; + else + xo = yo; + + if (!wipe->forward) + facf0 = 1 - facf0; + + width = wipezone->width; + hwidth = width * 0.5f; + + temp1 = (halfx - (halfx)*facf0); + pointdist = hypotf(temp1, temp1); + + temp2 = hypotf(halfx - x, halfy - y); + if (temp2 > pointdist) + output = in_band(hwidth, fabsf(temp2 - pointdist), 0, 1); + else + output = in_band(hwidth, fabsf(temp2 - pointdist), 1, 1); + + if (!wipe->forward) + output = 1 - output; + + break; + } + if (output < 0) + output = 0; + else if (output > 1) + output = 1; + return output; } static void init_wipe_effect(Sequence *seq) { - if (seq->effectdata) - MEM_freeN(seq->effectdata); + if (seq->effectdata) + MEM_freeN(seq->effectdata); - seq->effectdata = MEM_callocN(sizeof(WipeVars), "wipevars"); + seq->effectdata = MEM_callocN(sizeof(WipeVars), "wipevars"); } static int num_inputs_wipe(void) { - return 2; + return 2; } static void free_wipe_effect(Sequence *seq, const bool UNUSED(do_id_user)) { - if (seq->effectdata) - MEM_freeN(seq->effectdata); + if (seq->effectdata) + MEM_freeN(seq->effectdata); - seq->effectdata = NULL; + seq->effectdata = NULL; } static void copy_wipe_effect(Sequence *dst, Sequence *src, const int UNUSED(flag)) { - dst->effectdata = MEM_dupallocN(src->effectdata); -} - -static void do_wipe_effect_byte( - Sequence *seq, float facf0, float UNUSED(facf1), int x, int y, - unsigned char *rect1, unsigned char *rect2, unsigned char *out) -{ - WipeZone wipezone; - WipeVars *wipe = (WipeVars *)seq->effectdata; - int xo, yo; - unsigned char *cp1, *cp2, *rt; - - precalc_wipe_zone(&wipezone, wipe, x, y); - - cp1 = rect1; - cp2 = rect2; - rt = out; - - xo = x; - yo = y; - for (y = 0; y < yo; y++) { - for (x = 0; x < xo; x++) { - float check = check_zone(&wipezone, x, y, seq, facf0); - if (check) { - if (cp1) { - float rt1[4], rt2[4], tempc[4]; - - straight_uchar_to_premul_float(rt1, cp1); - straight_uchar_to_premul_float(rt2, cp2); - - tempc[0] = rt1[0] * check + rt2[0] * (1 - check); - tempc[1] = rt1[1] * check + rt2[1] * (1 - check); - tempc[2] = rt1[2] * check + rt2[2] * (1 - check); - tempc[3] = rt1[3] * check + rt2[3] * (1 - check); - - premul_float_to_straight_uchar(rt, tempc); - } - else { - rt[0] = 0; - rt[1] = 0; - rt[2] = 0; - rt[3] = 255; - } - } - else { - if (cp2) { - rt[0] = cp2[0]; - rt[1] = cp2[1]; - rt[2] = cp2[2]; - rt[3] = cp2[3]; - } - else { - rt[0] = 0; - rt[1] = 0; - rt[2] = 0; - rt[3] = 255; - } - } - - rt += 4; - if (cp1 != NULL) { - cp1 += 4; - } - if (cp2 != NULL) { - cp2 += 4; - } - } - } -} - -static void do_wipe_effect_float( - Sequence *seq, float facf0, float UNUSED(facf1), int x, int y, - float *rect1, float *rect2, float *out) -{ - WipeZone wipezone; - WipeVars *wipe = (WipeVars *)seq->effectdata; - int xo, yo; - float *rt1, *rt2, *rt; - - precalc_wipe_zone(&wipezone, wipe, x, y); - - rt1 = rect1; - rt2 = rect2; - rt = out; - - xo = x; - yo = y; - for (y = 0; y < yo; y++) { - for (x = 0; x < xo; x++) { - float check = check_zone(&wipezone, x, y, seq, facf0); - if (check) { - if (rt1) { - rt[0] = rt1[0] * check + rt2[0] * (1 - check); - rt[1] = rt1[1] * check + rt2[1] * (1 - check); - rt[2] = rt1[2] * check + rt2[2] * (1 - check); - rt[3] = rt1[3] * check + rt2[3] * (1 - check); - } - else { - rt[0] = 0; - rt[1] = 0; - rt[2] = 0; - rt[3] = 1.0; - } - } - else { - if (rt2) { - rt[0] = rt2[0]; - rt[1] = rt2[1]; - rt[2] = rt2[2]; - rt[3] = rt2[3]; - } - else { - rt[0] = 0; - rt[1] = 0; - rt[2] = 0; - rt[3] = 1.0; - } - } - - rt += 4; - if (rt1 != NULL) { - rt1 += 4; - } - if (rt2 != NULL) { - rt2 += 4; - } - } - } -} - -static ImBuf *do_wipe_effect( - const SeqRenderData *context, Sequence *seq, float UNUSED(cfra), float facf0, float facf1, - ImBuf *ibuf1, ImBuf *ibuf2, ImBuf *ibuf3) -{ - ImBuf *out = prepare_effect_imbufs(context, ibuf1, ibuf2, ibuf3); - - if (out->rect_float) { - do_wipe_effect_float( - seq, facf0, facf1, context->rectx, context->recty, ibuf1->rect_float, - ibuf2->rect_float, out->rect_float); - } - else { - do_wipe_effect_byte( - seq, facf0, facf1, context->rectx, context->recty, (unsigned char *) ibuf1->rect, - (unsigned char *) ibuf2->rect, (unsigned char *) out->rect); - } - - return out; + dst->effectdata = MEM_dupallocN(src->effectdata); +} + +static void do_wipe_effect_byte(Sequence *seq, + float facf0, + float UNUSED(facf1), + int x, + int y, + unsigned char *rect1, + unsigned char *rect2, + unsigned char *out) +{ + WipeZone wipezone; + WipeVars *wipe = (WipeVars *)seq->effectdata; + int xo, yo; + unsigned char *cp1, *cp2, *rt; + + precalc_wipe_zone(&wipezone, wipe, x, y); + + cp1 = rect1; + cp2 = rect2; + rt = out; + + xo = x; + yo = y; + for (y = 0; y < yo; y++) { + for (x = 0; x < xo; x++) { + float check = check_zone(&wipezone, x, y, seq, facf0); + if (check) { + if (cp1) { + float rt1[4], rt2[4], tempc[4]; + + straight_uchar_to_premul_float(rt1, cp1); + straight_uchar_to_premul_float(rt2, cp2); + + tempc[0] = rt1[0] * check + rt2[0] * (1 - check); + tempc[1] = rt1[1] * check + rt2[1] * (1 - check); + tempc[2] = rt1[2] * check + rt2[2] * (1 - check); + tempc[3] = rt1[3] * check + rt2[3] * (1 - check); + + premul_float_to_straight_uchar(rt, tempc); + } + else { + rt[0] = 0; + rt[1] = 0; + rt[2] = 0; + rt[3] = 255; + } + } + else { + if (cp2) { + rt[0] = cp2[0]; + rt[1] = cp2[1]; + rt[2] = cp2[2]; + rt[3] = cp2[3]; + } + else { + rt[0] = 0; + rt[1] = 0; + rt[2] = 0; + rt[3] = 255; + } + } + + rt += 4; + if (cp1 != NULL) { + cp1 += 4; + } + if (cp2 != NULL) { + cp2 += 4; + } + } + } +} + +static void do_wipe_effect_float(Sequence *seq, + float facf0, + float UNUSED(facf1), + int x, + int y, + float *rect1, + float *rect2, + float *out) +{ + WipeZone wipezone; + WipeVars *wipe = (WipeVars *)seq->effectdata; + int xo, yo; + float *rt1, *rt2, *rt; + + precalc_wipe_zone(&wipezone, wipe, x, y); + + rt1 = rect1; + rt2 = rect2; + rt = out; + + xo = x; + yo = y; + for (y = 0; y < yo; y++) { + for (x = 0; x < xo; x++) { + float check = check_zone(&wipezone, x, y, seq, facf0); + if (check) { + if (rt1) { + rt[0] = rt1[0] * check + rt2[0] * (1 - check); + rt[1] = rt1[1] * check + rt2[1] * (1 - check); + rt[2] = rt1[2] * check + rt2[2] * (1 - check); + rt[3] = rt1[3] * check + rt2[3] * (1 - check); + } + else { + rt[0] = 0; + rt[1] = 0; + rt[2] = 0; + rt[3] = 1.0; + } + } + else { + if (rt2) { + rt[0] = rt2[0]; + rt[1] = rt2[1]; + rt[2] = rt2[2]; + rt[3] = rt2[3]; + } + else { + rt[0] = 0; + rt[1] = 0; + rt[2] = 0; + rt[3] = 1.0; + } + } + + rt += 4; + if (rt1 != NULL) { + rt1 += 4; + } + if (rt2 != NULL) { + rt2 += 4; + } + } + } +} + +static ImBuf *do_wipe_effect(const SeqRenderData *context, + Sequence *seq, + float UNUSED(cfra), + float facf0, + float facf1, + ImBuf *ibuf1, + ImBuf *ibuf2, + ImBuf *ibuf3) +{ + ImBuf *out = prepare_effect_imbufs(context, ibuf1, ibuf2, ibuf3); + + if (out->rect_float) { + do_wipe_effect_float(seq, + facf0, + facf1, + context->rectx, + context->recty, + ibuf1->rect_float, + ibuf2->rect_float, + out->rect_float); + } + else { + do_wipe_effect_byte(seq, + facf0, + facf1, + context->rectx, + context->recty, + (unsigned char *)ibuf1->rect, + (unsigned char *)ibuf2->rect, + (unsigned char *)out->rect); + } + + return out; } /*********************** Transform *************************/ static void init_transform_effect(Sequence *seq) { - TransformVars *transform; + TransformVars *transform; - if (seq->effectdata) - MEM_freeN(seq->effectdata); + if (seq->effectdata) + MEM_freeN(seq->effectdata); - seq->effectdata = MEM_callocN(sizeof(TransformVars), "transformvars"); + seq->effectdata = MEM_callocN(sizeof(TransformVars), "transformvars"); - transform = (TransformVars *) seq->effectdata; + transform = (TransformVars *)seq->effectdata; - transform->ScalexIni = 1.0f; - transform->ScaleyIni = 1.0f; + transform->ScalexIni = 1.0f; + transform->ScaleyIni = 1.0f; - transform->xIni = 0.0f; - transform->yIni = 0.0f; + transform->xIni = 0.0f; + transform->yIni = 0.0f; - transform->rotIni = 0.0f; + transform->rotIni = 0.0f; - transform->interpolation = 1; - transform->percent = 1; - transform->uniform_scale = 0; + transform->interpolation = 1; + transform->percent = 1; + transform->uniform_scale = 0; } static int num_inputs_transform(void) { - return 1; + return 1; } static void free_transform_effect(Sequence *seq, const bool UNUSED(do_id_user)) { - if (seq->effectdata) MEM_freeN(seq->effectdata); - seq->effectdata = NULL; + if (seq->effectdata) + MEM_freeN(seq->effectdata); + seq->effectdata = NULL; } static void copy_transform_effect(Sequence *dst, Sequence *src, const int UNUSED(flag)) { - dst->effectdata = MEM_dupallocN(src->effectdata); -} - -static void transform_image( - int x, int y, ImBuf *ibuf1, ImBuf *out, float scale_x, float scale_y, - float translate_x, float translate_y, float rotate, int interpolation) -{ - int xo, yo, xi, yi; - float xt, yt, xr, yr; - float s, c; - - xo = x; - yo = y; - - /* Rotate */ - s = sinf(rotate); - c = cosf(rotate); - - for (yi = 0; yi < yo; yi++) { - for (xi = 0; xi < xo; xi++) { - /* translate point */ - xt = xi - translate_x; - yt = yi - translate_y; - - /* rotate point with center ref */ - xr = c * xt + s * yt; - yr = -s * xt + c * yt; - - /* scale point with center ref */ - xt = xr / scale_x; - yt = yr / scale_y; - - /* undo reference center point */ - xt += (xo / 2.0f); - yt += (yo / 2.0f); - - /* interpolate */ - switch (interpolation) { - case 0: - nearest_interpolation(ibuf1, out, xt, yt, xi, yi); - break; - case 1: - bilinear_interpolation(ibuf1, out, xt, yt, xi, yi); - break; - case 2: - bicubic_interpolation(ibuf1, out, xt, yt, xi, yi); - break; - } - } - } -} - -static void do_transform(Scene *scene, Sequence *seq, float UNUSED(facf0), int x, int y, ImBuf *ibuf1, ImBuf *out) -{ - TransformVars *transform = (TransformVars *) seq->effectdata; - float scale_x, scale_y, translate_x, translate_y, rotate_radians; - - /* Scale */ - if (transform->uniform_scale) { - scale_x = scale_y = transform->ScalexIni; - } - else { - scale_x = transform->ScalexIni; - scale_y = transform->ScaleyIni; - } - - /* Translate */ - if (!transform->percent) { - float rd_s = (scene->r.size / 100.0f); - - translate_x = transform->xIni * rd_s + (x / 2.0f); - translate_y = transform->yIni * rd_s + (y / 2.0f); - } - else { - translate_x = x * (transform->xIni / 100.0f) + (x / 2.0f); - translate_y = y * (transform->yIni / 100.0f) + (y / 2.0f); - } - - /* Rotate */ - rotate_radians = DEG2RADF(transform->rotIni); - - transform_image(x, y, ibuf1, out, scale_x, scale_y, translate_x, translate_y, rotate_radians, transform->interpolation); -} - - -static ImBuf *do_transform_effect( - const SeqRenderData *context, Sequence *seq, float UNUSED(cfra), float facf0, - float UNUSED(facf1), ImBuf *ibuf1, ImBuf *ibuf2, ImBuf *ibuf3) -{ - ImBuf *out = prepare_effect_imbufs(context, ibuf1, ibuf2, ibuf3); - - do_transform(context->scene, seq, facf0, context->rectx, context->recty, ibuf1, out); - - return out; + dst->effectdata = MEM_dupallocN(src->effectdata); +} + +static void transform_image(int x, + int y, + ImBuf *ibuf1, + ImBuf *out, + float scale_x, + float scale_y, + float translate_x, + float translate_y, + float rotate, + int interpolation) +{ + int xo, yo, xi, yi; + float xt, yt, xr, yr; + float s, c; + + xo = x; + yo = y; + + /* Rotate */ + s = sinf(rotate); + c = cosf(rotate); + + for (yi = 0; yi < yo; yi++) { + for (xi = 0; xi < xo; xi++) { + /* translate point */ + xt = xi - translate_x; + yt = yi - translate_y; + + /* rotate point with center ref */ + xr = c * xt + s * yt; + yr = -s * xt + c * yt; + + /* scale point with center ref */ + xt = xr / scale_x; + yt = yr / scale_y; + + /* undo reference center point */ + xt += (xo / 2.0f); + yt += (yo / 2.0f); + + /* interpolate */ + switch (interpolation) { + case 0: + nearest_interpolation(ibuf1, out, xt, yt, xi, yi); + break; + case 1: + bilinear_interpolation(ibuf1, out, xt, yt, xi, yi); + break; + case 2: + bicubic_interpolation(ibuf1, out, xt, yt, xi, yi); + break; + } + } + } +} + +static void do_transform( + Scene *scene, Sequence *seq, float UNUSED(facf0), int x, int y, ImBuf *ibuf1, ImBuf *out) +{ + TransformVars *transform = (TransformVars *)seq->effectdata; + float scale_x, scale_y, translate_x, translate_y, rotate_radians; + + /* Scale */ + if (transform->uniform_scale) { + scale_x = scale_y = transform->ScalexIni; + } + else { + scale_x = transform->ScalexIni; + scale_y = transform->ScaleyIni; + } + + /* Translate */ + if (!transform->percent) { + float rd_s = (scene->r.size / 100.0f); + + translate_x = transform->xIni * rd_s + (x / 2.0f); + translate_y = transform->yIni * rd_s + (y / 2.0f); + } + else { + translate_x = x * (transform->xIni / 100.0f) + (x / 2.0f); + translate_y = y * (transform->yIni / 100.0f) + (y / 2.0f); + } + + /* Rotate */ + rotate_radians = DEG2RADF(transform->rotIni); + + transform_image(x, + y, + ibuf1, + out, + scale_x, + scale_y, + translate_x, + translate_y, + rotate_radians, + transform->interpolation); +} + +static ImBuf *do_transform_effect(const SeqRenderData *context, + Sequence *seq, + float UNUSED(cfra), + float facf0, + float UNUSED(facf1), + ImBuf *ibuf1, + ImBuf *ibuf2, + ImBuf *ibuf3) +{ + ImBuf *out = prepare_effect_imbufs(context, ibuf1, ibuf2, ibuf3); + + do_transform(context->scene, seq, facf0, context->rectx, context->recty, ibuf1, out); + + return out; } /*********************** Glow *************************/ static void RVBlurBitmap2_float(float *map, int width, int height, float blur, int quality) -/* MUUUCCH better than the previous blur. */ -/* We do the blurring in two passes which is a whole lot faster. */ -/* I changed the math around to implement an actual Gaussian */ -/* distribution. */ +/* MUUUCCH better than the previous blur. */ +/* We do the blurring in two passes which is a whole lot faster. */ +/* I changed the math around to implement an actual Gaussian */ +/* distribution. */ /* */ -/* Watch out though, it tends to misbehaven with large blur values on */ -/* a small bitmap. Avoid avoid avoid. */ +/* Watch out though, it tends to misbehaven with large blur values on */ +/* a small bitmap. Avoid avoid avoid. */ /*=============================== */ { - float *temp = NULL, *swap; - float *filter = NULL; - int x, y, i, fx, fy; - int index, ix, halfWidth; - float fval, k, curColor[4], curColor2[4], weight = 0; - - /* If we're not really blurring, bail out */ - if (blur <= 0) - return; - - /* Allocate memory for the tempmap and the blur filter matrix */ - temp = MEM_mallocN((width * height * 4 * sizeof(float)), "blurbitmaptemp"); - if (!temp) - return; - - /* Allocate memory for the filter elements */ - halfWidth = ((quality + 1) * blur); - filter = (float *)MEM_mallocN(sizeof(float) * halfWidth * 2, "blurbitmapfilter"); - if (!filter) { - MEM_freeN(temp); - return; - } - - /* Apparently we're calculating a bell curve based on the standard deviation (or radius) - * This code is based on an example posted to comp.graphics.algorithms by - * Blancmange (bmange@airdmhor.gen.nz) - */ - - k = -1.0f / (2.0f * (float)M_PI * blur * blur); - - for (ix = 0; ix < halfWidth; ix++) { - weight = (float)exp(k * (ix * ix)); - filter[halfWidth - ix] = weight; - filter[halfWidth + ix] = weight; - } - filter[0] = weight; - - /* Normalize the array */ - fval = 0; - for (ix = 0; ix < halfWidth * 2; ix++) - fval += filter[ix]; - - for (ix = 0; ix < halfWidth * 2; ix++) - filter[ix] /= fval; - - /* Blur the rows */ - for (y = 0; y < height; y++) { - /* Do the left & right strips */ - for (x = 0; x < halfWidth; x++) { - fx = 0; - zero_v4(curColor); - zero_v4(curColor2); - - for (i = x - halfWidth; i < x + halfWidth; i++) { - if ((i >= 0) && (i < width)) { - index = (i + y * width) * 4; - madd_v4_v4fl(curColor, map + index, filter[fx]); - - index = (width - 1 - i + y * width) * 4; - madd_v4_v4fl(curColor2, map + index, filter[fx]); - } - fx++; - } - index = (x + y * width) * 4; - copy_v4_v4(temp + index, curColor); - - index = (width - 1 - x + y * width) * 4; - copy_v4_v4(temp + index, curColor2); - } - - /* Do the main body */ - for (x = halfWidth; x < width - halfWidth; x++) { - fx = 0; - zero_v4(curColor); - for (i = x - halfWidth; i < x + halfWidth; i++) { - index = (i + y * width) * 4; - madd_v4_v4fl(curColor, map + index, filter[fx]); - fx++; - } - index = (x + y * width) * 4; - copy_v4_v4(temp + index, curColor); - } - } - - /* Swap buffers */ - swap = temp; temp = map; map = swap; - - /* Blur the columns */ - for (x = 0; x < width; x++) { - /* Do the top & bottom strips */ - for (y = 0; y < halfWidth; y++) { - fy = 0; - zero_v4(curColor); - zero_v4(curColor2); - for (i = y - halfWidth; i < y + halfWidth; i++) { - if ((i >= 0) && (i < height)) { - /* Bottom */ - index = (x + i * width) * 4; - madd_v4_v4fl(curColor, map + index, filter[fy]); - - /* Top */ - index = (x + (height - 1 - i) * width) * 4; - madd_v4_v4fl(curColor2, map + index, filter[fy]); - } - fy++; - } - index = (x + y * width) * 4; - copy_v4_v4(temp + index, curColor); - - index = (x + (height - 1 - y) * width) * 4; - copy_v4_v4(temp + index, curColor2); - } - - /* Do the main body */ - for (y = halfWidth; y < height - halfWidth; y++) { - fy = 0; - zero_v4(curColor); - for (i = y - halfWidth; i < y + halfWidth; i++) { - index = (x + i * width) * 4; - madd_v4_v4fl(curColor, map + index, filter[fy]); - fy++; - } - index = (x + y * width) * 4; - copy_v4_v4(temp + index, curColor); - } - } - - /* Swap buffers */ - swap = temp; temp = map; /* map = swap; */ /* UNUSED */ - - /* Tidy up */ - MEM_freeN(filter); - MEM_freeN(temp); + float *temp = NULL, *swap; + float *filter = NULL; + int x, y, i, fx, fy; + int index, ix, halfWidth; + float fval, k, curColor[4], curColor2[4], weight = 0; + + /* If we're not really blurring, bail out */ + if (blur <= 0) + return; + + /* Allocate memory for the tempmap and the blur filter matrix */ + temp = MEM_mallocN((width * height * 4 * sizeof(float)), "blurbitmaptemp"); + if (!temp) + return; + + /* Allocate memory for the filter elements */ + halfWidth = ((quality + 1) * blur); + filter = (float *)MEM_mallocN(sizeof(float) * halfWidth * 2, "blurbitmapfilter"); + if (!filter) { + MEM_freeN(temp); + return; + } + + /* Apparently we're calculating a bell curve based on the standard deviation (or radius) + * This code is based on an example posted to comp.graphics.algorithms by + * Blancmange (bmange@airdmhor.gen.nz) + */ + + k = -1.0f / (2.0f * (float)M_PI * blur * blur); + + for (ix = 0; ix < halfWidth; ix++) { + weight = (float)exp(k * (ix * ix)); + filter[halfWidth - ix] = weight; + filter[halfWidth + ix] = weight; + } + filter[0] = weight; + + /* Normalize the array */ + fval = 0; + for (ix = 0; ix < halfWidth * 2; ix++) + fval += filter[ix]; + + for (ix = 0; ix < halfWidth * 2; ix++) + filter[ix] /= fval; + + /* Blur the rows */ + for (y = 0; y < height; y++) { + /* Do the left & right strips */ + for (x = 0; x < halfWidth; x++) { + fx = 0; + zero_v4(curColor); + zero_v4(curColor2); + + for (i = x - halfWidth; i < x + halfWidth; i++) { + if ((i >= 0) && (i < width)) { + index = (i + y * width) * 4; + madd_v4_v4fl(curColor, map + index, filter[fx]); + + index = (width - 1 - i + y * width) * 4; + madd_v4_v4fl(curColor2, map + index, filter[fx]); + } + fx++; + } + index = (x + y * width) * 4; + copy_v4_v4(temp + index, curColor); + + index = (width - 1 - x + y * width) * 4; + copy_v4_v4(temp + index, curColor2); + } + + /* Do the main body */ + for (x = halfWidth; x < width - halfWidth; x++) { + fx = 0; + zero_v4(curColor); + for (i = x - halfWidth; i < x + halfWidth; i++) { + index = (i + y * width) * 4; + madd_v4_v4fl(curColor, map + index, filter[fx]); + fx++; + } + index = (x + y * width) * 4; + copy_v4_v4(temp + index, curColor); + } + } + + /* Swap buffers */ + swap = temp; + temp = map; + map = swap; + + /* Blur the columns */ + for (x = 0; x < width; x++) { + /* Do the top & bottom strips */ + for (y = 0; y < halfWidth; y++) { + fy = 0; + zero_v4(curColor); + zero_v4(curColor2); + for (i = y - halfWidth; i < y + halfWidth; i++) { + if ((i >= 0) && (i < height)) { + /* Bottom */ + index = (x + i * width) * 4; + madd_v4_v4fl(curColor, map + index, filter[fy]); + + /* Top */ + index = (x + (height - 1 - i) * width) * 4; + madd_v4_v4fl(curColor2, map + index, filter[fy]); + } + fy++; + } + index = (x + y * width) * 4; + copy_v4_v4(temp + index, curColor); + + index = (x + (height - 1 - y) * width) * 4; + copy_v4_v4(temp + index, curColor2); + } + + /* Do the main body */ + for (y = halfWidth; y < height - halfWidth; y++) { + fy = 0; + zero_v4(curColor); + for (i = y - halfWidth; i < y + halfWidth; i++) { + index = (x + i * width) * 4; + madd_v4_v4fl(curColor, map + index, filter[fy]); + fy++; + } + index = (x + y * width) * 4; + copy_v4_v4(temp + index, curColor); + } + } + + /* Swap buffers */ + swap = temp; + temp = map; /* map = swap; */ /* UNUSED */ + + /* Tidy up */ + MEM_freeN(filter); + MEM_freeN(temp); } static void RVAddBitmaps_float(float *a, float *b, float *c, int width, int height) { - int x, y, index; + int x, y, index; - for (y = 0; y < height; y++) { - for (x = 0; x < width; x++) { - index = (x + y * width) * 4; - c[index + GlowR] = min_ff(1.0f, a[index + GlowR] + b[index + GlowR]); - c[index + GlowG] = min_ff(1.0f, a[index + GlowG] + b[index + GlowG]); - c[index + GlowB] = min_ff(1.0f, a[index + GlowB] + b[index + GlowB]); - c[index + GlowA] = min_ff(1.0f, a[index + GlowA] + b[index + GlowA]); - } - } + for (y = 0; y < height; y++) { + for (x = 0; x < width; x++) { + index = (x + y * width) * 4; + c[index + GlowR] = min_ff(1.0f, a[index + GlowR] + b[index + GlowR]); + c[index + GlowG] = min_ff(1.0f, a[index + GlowG] + b[index + GlowG]); + c[index + GlowB] = min_ff(1.0f, a[index + GlowB] + b[index + GlowB]); + c[index + GlowA] = min_ff(1.0f, a[index + GlowA] + b[index + GlowA]); + } + } } static void RVIsolateHighlights_float( - float *in, float *out, int width, int height, - float threshold, float boost, float clamp) -{ - int x, y, index; - float intensity; - - for (y = 0; y < height; y++) { - for (x = 0; x < width; x++) { - index = (x + y * width) * 4; - - /* Isolate the intensity */ - intensity = (in[index + GlowR] + in[index + GlowG] + in[index + GlowB] - threshold); - if (intensity > 0) { - out[index + GlowR] = min_ff(clamp, (in[index + GlowR] * boost * intensity)); - out[index + GlowG] = min_ff(clamp, (in[index + GlowG] * boost * intensity)); - out[index + GlowB] = min_ff(clamp, (in[index + GlowB] * boost * intensity)); - out[index + GlowA] = min_ff(clamp, (in[index + GlowA] * boost * intensity)); - } - else { - out[index + GlowR] = 0; - out[index + GlowG] = 0; - out[index + GlowB] = 0; - out[index + GlowA] = 0; - } - } - } + float *in, float *out, int width, int height, float threshold, float boost, float clamp) +{ + int x, y, index; + float intensity; + + for (y = 0; y < height; y++) { + for (x = 0; x < width; x++) { + index = (x + y * width) * 4; + + /* Isolate the intensity */ + intensity = (in[index + GlowR] + in[index + GlowG] + in[index + GlowB] - threshold); + if (intensity > 0) { + out[index + GlowR] = min_ff(clamp, (in[index + GlowR] * boost * intensity)); + out[index + GlowG] = min_ff(clamp, (in[index + GlowG] * boost * intensity)); + out[index + GlowB] = min_ff(clamp, (in[index + GlowB] * boost * intensity)); + out[index + GlowA] = min_ff(clamp, (in[index + GlowA] * boost * intensity)); + } + else { + out[index + GlowR] = 0; + out[index + GlowG] = 0; + out[index + GlowB] = 0; + out[index + GlowA] = 0; + } + } + } } static void init_glow_effect(Sequence *seq) { - GlowVars *glow; + GlowVars *glow; - if (seq->effectdata) - MEM_freeN(seq->effectdata); + if (seq->effectdata) + MEM_freeN(seq->effectdata); - seq->effectdata = MEM_callocN(sizeof(GlowVars), "glowvars"); + seq->effectdata = MEM_callocN(sizeof(GlowVars), "glowvars"); - glow = (GlowVars *)seq->effectdata; - glow->fMini = 0.25; - glow->fClamp = 1.0; - glow->fBoost = 0.5; - glow->dDist = 3.0; - glow->dQuality = 3; - glow->bNoComp = 0; + glow = (GlowVars *)seq->effectdata; + glow->fMini = 0.25; + glow->fClamp = 1.0; + glow->fBoost = 0.5; + glow->dDist = 3.0; + glow->dQuality = 3; + glow->bNoComp = 0; } static int num_inputs_glow(void) { - return 1; + return 1; } static void free_glow_effect(Sequence *seq, const bool UNUSED(do_id_user)) { - if (seq->effectdata) - MEM_freeN(seq->effectdata); + if (seq->effectdata) + MEM_freeN(seq->effectdata); - seq->effectdata = NULL; + seq->effectdata = NULL; } static void copy_glow_effect(Sequence *dst, Sequence *src, const int UNUSED(flag)) { - dst->effectdata = MEM_dupallocN(src->effectdata); -} - -static void do_glow_effect_byte( - Sequence *seq, int render_size, float facf0, float UNUSED(facf1), int x, int y, - unsigned char *rect1, unsigned char *UNUSED(rect2), unsigned char *out) -{ - float *outbuf, *inbuf; - GlowVars *glow = (GlowVars *)seq->effectdata; - - inbuf = MEM_mallocN(4 * sizeof(float) * x * y, "glow effect input"); - outbuf = MEM_mallocN(4 * sizeof(float) * x * y, "glow effect output"); - - IMB_buffer_float_from_byte(inbuf, rect1, IB_PROFILE_SRGB, IB_PROFILE_SRGB, false, x, y, x, x); - IMB_buffer_float_premultiply(inbuf, x, y); - - RVIsolateHighlights_float(inbuf, outbuf, x, y, glow->fMini * 3.0f, glow->fBoost * facf0, glow->fClamp); - RVBlurBitmap2_float(outbuf, x, y, glow->dDist * (render_size / 100.0f), glow->dQuality); - if (!glow->bNoComp) - RVAddBitmaps_float(inbuf, outbuf, outbuf, x, y); - - IMB_buffer_float_unpremultiply(outbuf, x, y); - IMB_buffer_byte_from_float(out, outbuf, 4, 0.0f, IB_PROFILE_SRGB, IB_PROFILE_SRGB, false, x, y, x, x); - - MEM_freeN(inbuf); - MEM_freeN(outbuf); -} - -static void do_glow_effect_float( - Sequence *seq, int render_size, float facf0, float UNUSED(facf1), int x, int y, - float *rect1, float *UNUSED(rect2), float *out) -{ - float *outbuf = out; - float *inbuf = rect1; - GlowVars *glow = (GlowVars *)seq->effectdata; - - RVIsolateHighlights_float(inbuf, outbuf, x, y, glow->fMini * 3.0f, glow->fBoost * facf0, glow->fClamp); - RVBlurBitmap2_float(outbuf, x, y, glow->dDist * (render_size / 100.0f), glow->dQuality); - if (!glow->bNoComp) - RVAddBitmaps_float(inbuf, outbuf, outbuf, x, y); -} - -static ImBuf *do_glow_effect( - const SeqRenderData *context, Sequence *seq, float UNUSED(cfra), float facf0, float facf1, - ImBuf *ibuf1, ImBuf *ibuf2, ImBuf *ibuf3) -{ - ImBuf *out = prepare_effect_imbufs(context, ibuf1, ibuf2, ibuf3); - - int render_size = 100 * context->rectx / context->scene->r.xsch; - - if (out->rect_float) { - do_glow_effect_float( - seq, render_size, facf0, facf1, context->rectx, context->recty, - ibuf1->rect_float, ibuf2->rect_float, out->rect_float); - } - else { - do_glow_effect_byte( - seq, render_size, facf0, facf1, context->rectx, context->recty, - (unsigned char *) ibuf1->rect, (unsigned char *) ibuf2->rect, (unsigned char *) out->rect); - } - - return out; + dst->effectdata = MEM_dupallocN(src->effectdata); +} + +static void do_glow_effect_byte(Sequence *seq, + int render_size, + float facf0, + float UNUSED(facf1), + int x, + int y, + unsigned char *rect1, + unsigned char *UNUSED(rect2), + unsigned char *out) +{ + float *outbuf, *inbuf; + GlowVars *glow = (GlowVars *)seq->effectdata; + + inbuf = MEM_mallocN(4 * sizeof(float) * x * y, "glow effect input"); + outbuf = MEM_mallocN(4 * sizeof(float) * x * y, "glow effect output"); + + IMB_buffer_float_from_byte(inbuf, rect1, IB_PROFILE_SRGB, IB_PROFILE_SRGB, false, x, y, x, x); + IMB_buffer_float_premultiply(inbuf, x, y); + + RVIsolateHighlights_float( + inbuf, outbuf, x, y, glow->fMini * 3.0f, glow->fBoost * facf0, glow->fClamp); + RVBlurBitmap2_float(outbuf, x, y, glow->dDist * (render_size / 100.0f), glow->dQuality); + if (!glow->bNoComp) + RVAddBitmaps_float(inbuf, outbuf, outbuf, x, y); + + IMB_buffer_float_unpremultiply(outbuf, x, y); + IMB_buffer_byte_from_float( + out, outbuf, 4, 0.0f, IB_PROFILE_SRGB, IB_PROFILE_SRGB, false, x, y, x, x); + + MEM_freeN(inbuf); + MEM_freeN(outbuf); +} + +static void do_glow_effect_float(Sequence *seq, + int render_size, + float facf0, + float UNUSED(facf1), + int x, + int y, + float *rect1, + float *UNUSED(rect2), + float *out) +{ + float *outbuf = out; + float *inbuf = rect1; + GlowVars *glow = (GlowVars *)seq->effectdata; + + RVIsolateHighlights_float( + inbuf, outbuf, x, y, glow->fMini * 3.0f, glow->fBoost * facf0, glow->fClamp); + RVBlurBitmap2_float(outbuf, x, y, glow->dDist * (render_size / 100.0f), glow->dQuality); + if (!glow->bNoComp) + RVAddBitmaps_float(inbuf, outbuf, outbuf, x, y); +} + +static ImBuf *do_glow_effect(const SeqRenderData *context, + Sequence *seq, + float UNUSED(cfra), + float facf0, + float facf1, + ImBuf *ibuf1, + ImBuf *ibuf2, + ImBuf *ibuf3) +{ + ImBuf *out = prepare_effect_imbufs(context, ibuf1, ibuf2, ibuf3); + + int render_size = 100 * context->rectx / context->scene->r.xsch; + + if (out->rect_float) { + do_glow_effect_float(seq, + render_size, + facf0, + facf1, + context->rectx, + context->recty, + ibuf1->rect_float, + ibuf2->rect_float, + out->rect_float); + } + else { + do_glow_effect_byte(seq, + render_size, + facf0, + facf1, + context->rectx, + context->recty, + (unsigned char *)ibuf1->rect, + (unsigned char *)ibuf2->rect, + (unsigned char *)out->rect); + } + + return out; } /*********************** Solid color *************************/ static void init_solid_color(Sequence *seq) { - SolidColorVars *cv; + SolidColorVars *cv; - if (seq->effectdata) - MEM_freeN(seq->effectdata); + if (seq->effectdata) + MEM_freeN(seq->effectdata); - seq->effectdata = MEM_callocN(sizeof(SolidColorVars), "solidcolor"); + seq->effectdata = MEM_callocN(sizeof(SolidColorVars), "solidcolor"); - cv = (SolidColorVars *)seq->effectdata; - cv->col[0] = cv->col[1] = cv->col[2] = 0.5; + cv = (SolidColorVars *)seq->effectdata; + cv->col[0] = cv->col[1] = cv->col[2] = 0.5; } static int num_inputs_color(void) { - return 0; + return 0; } static void free_solid_color(Sequence *seq, const bool UNUSED(do_id_user)) { - if (seq->effectdata) - MEM_freeN(seq->effectdata); + if (seq->effectdata) + MEM_freeN(seq->effectdata); - seq->effectdata = NULL; + seq->effectdata = NULL; } static void copy_solid_color(Sequence *dst, Sequence *src, const int UNUSED(flag)) { - dst->effectdata = MEM_dupallocN(src->effectdata); + dst->effectdata = MEM_dupallocN(src->effectdata); } static int early_out_color(Sequence *UNUSED(seq), float UNUSED(facf0), float UNUSED(facf1)) { - return EARLY_NO_INPUT; -} - -static ImBuf *do_solid_color( - const SeqRenderData *context, Sequence *seq, float UNUSED(cfra), float facf0, float facf1, - ImBuf *ibuf1, ImBuf *ibuf2, ImBuf *ibuf3) -{ - ImBuf *out = prepare_effect_imbufs(context, ibuf1, ibuf2, ibuf3); - - SolidColorVars *cv = (SolidColorVars *)seq->effectdata; - - unsigned char *rect; - float *rect_float; - int x; /*= context->rectx;*/ /*UNUSED*/ - int y; /*= context->recty;*/ /*UNUSED*/ - - if (out->rect) { - unsigned char col0[3]; - unsigned char col1[3]; - - col0[0] = facf0 * cv->col[0] * 255; - col0[1] = facf0 * cv->col[1] * 255; - col0[2] = facf0 * cv->col[2] * 255; - - col1[0] = facf1 * cv->col[0] * 255; - col1[1] = facf1 * cv->col[1] * 255; - col1[2] = facf1 * cv->col[2] * 255; - - rect = (unsigned char *)out->rect; - - for (y = 0; y < out->y; y++) { - for (x = 0; x < out->x; x++, rect += 4) { - rect[0] = col0[0]; - rect[1] = col0[1]; - rect[2] = col0[2]; - rect[3] = 255; - } - y++; - if (y < out->y) { - for (x = 0; x < out->x; x++, rect += 4) { - rect[0] = col1[0]; - rect[1] = col1[1]; - rect[2] = col1[2]; - rect[3] = 255; - } - } - } - - } - else if (out->rect_float) { - float col0[3]; - float col1[3]; - - col0[0] = facf0 * cv->col[0]; - col0[1] = facf0 * cv->col[1]; - col0[2] = facf0 * cv->col[2]; - - col1[0] = facf1 * cv->col[0]; - col1[1] = facf1 * cv->col[1]; - col1[2] = facf1 * cv->col[2]; - - rect_float = out->rect_float; - - for (y = 0; y < out->y; y++) { - for (x = 0; x < out->x; x++, rect_float += 4) { - rect_float[0] = col0[0]; - rect_float[1] = col0[1]; - rect_float[2] = col0[2]; - rect_float[3] = 1.0; - } - y++; - if (y < out->y) { - for (x = 0; x < out->x; x++, rect_float += 4) { - rect_float[0] = col1[0]; - rect_float[1] = col1[1]; - rect_float[2] = col1[2]; - rect_float[3] = 1.0; - } - } - } - } - return out; + return EARLY_NO_INPUT; +} + +static ImBuf *do_solid_color(const SeqRenderData *context, + Sequence *seq, + float UNUSED(cfra), + float facf0, + float facf1, + ImBuf *ibuf1, + ImBuf *ibuf2, + ImBuf *ibuf3) +{ + ImBuf *out = prepare_effect_imbufs(context, ibuf1, ibuf2, ibuf3); + + SolidColorVars *cv = (SolidColorVars *)seq->effectdata; + + unsigned char *rect; + float *rect_float; + int x; /*= context->rectx;*/ /*UNUSED*/ + int y; /*= context->recty;*/ /*UNUSED*/ + + if (out->rect) { + unsigned char col0[3]; + unsigned char col1[3]; + + col0[0] = facf0 * cv->col[0] * 255; + col0[1] = facf0 * cv->col[1] * 255; + col0[2] = facf0 * cv->col[2] * 255; + + col1[0] = facf1 * cv->col[0] * 255; + col1[1] = facf1 * cv->col[1] * 255; + col1[2] = facf1 * cv->col[2] * 255; + + rect = (unsigned char *)out->rect; + + for (y = 0; y < out->y; y++) { + for (x = 0; x < out->x; x++, rect += 4) { + rect[0] = col0[0]; + rect[1] = col0[1]; + rect[2] = col0[2]; + rect[3] = 255; + } + y++; + if (y < out->y) { + for (x = 0; x < out->x; x++, rect += 4) { + rect[0] = col1[0]; + rect[1] = col1[1]; + rect[2] = col1[2]; + rect[3] = 255; + } + } + } + } + else if (out->rect_float) { + float col0[3]; + float col1[3]; + + col0[0] = facf0 * cv->col[0]; + col0[1] = facf0 * cv->col[1]; + col0[2] = facf0 * cv->col[2]; + + col1[0] = facf1 * cv->col[0]; + col1[1] = facf1 * cv->col[1]; + col1[2] = facf1 * cv->col[2]; + + rect_float = out->rect_float; + + for (y = 0; y < out->y; y++) { + for (x = 0; x < out->x; x++, rect_float += 4) { + rect_float[0] = col0[0]; + rect_float[1] = col0[1]; + rect_float[2] = col0[2]; + rect_float[3] = 1.0; + } + y++; + if (y < out->y) { + for (x = 0; x < out->x; x++, rect_float += 4) { + rect_float[0] = col1[0]; + rect_float[1] = col1[1]; + rect_float[2] = col1[2]; + rect_float[3] = 1.0; + } + } + } + } + return out; } /*********************** Mulitcam *************************/ @@ -2511,50 +2866,55 @@ static ImBuf *do_solid_color( /* no effect inputs for multicam, we use give_ibuf_seq */ static int num_inputs_multicam(void) { - return 0; + return 0; } static int early_out_multicam(Sequence *UNUSED(seq), float UNUSED(facf0), float UNUSED(facf1)) { - return EARLY_NO_INPUT; + return EARLY_NO_INPUT; } -static ImBuf *do_multicam( - const SeqRenderData *context, Sequence *seq, float cfra, float UNUSED(facf0), float UNUSED(facf1), - ImBuf *UNUSED(ibuf1), ImBuf *UNUSED(ibuf2), ImBuf *UNUSED(ibuf3)) +static ImBuf *do_multicam(const SeqRenderData *context, + Sequence *seq, + float cfra, + float UNUSED(facf0), + float UNUSED(facf1), + ImBuf *UNUSED(ibuf1), + ImBuf *UNUSED(ibuf2), + ImBuf *UNUSED(ibuf3)) { - ImBuf *i; - ImBuf *out; - Editing *ed; - ListBase *seqbasep; + ImBuf *i; + ImBuf *out; + Editing *ed; + ListBase *seqbasep; - if (seq->multicam_source == 0 || seq->multicam_source >= seq->machine) { - return NULL; - } + if (seq->multicam_source == 0 || seq->multicam_source >= seq->machine) { + return NULL; + } - ed = context->scene->ed; - if (!ed) { - return NULL; - } - seqbasep = BKE_sequence_seqbase(&ed->seqbase, seq); - if (!seqbasep) { - return NULL; - } + ed = context->scene->ed; + if (!ed) { + return NULL; + } + seqbasep = BKE_sequence_seqbase(&ed->seqbase, seq); + if (!seqbasep) { + return NULL; + } - i = BKE_sequencer_give_ibuf_seqbase(context, cfra, seq->multicam_source, seqbasep); - if (!i) { - return NULL; - } + i = BKE_sequencer_give_ibuf_seqbase(context, cfra, seq->multicam_source, seqbasep); + if (!i) { + return NULL; + } - if (BKE_sequencer_input_have_to_preprocess(context, seq, cfra)) { - out = IMB_dupImBuf(i); - IMB_freeImBuf(i); - } - else { - out = i; - } + if (BKE_sequencer_input_have_to_preprocess(context, seq, cfra)) { + out = IMB_dupImBuf(i); + IMB_freeImBuf(i); + } + else { + out = i; + } - return out; + return out; } /*********************** Adjustment *************************/ @@ -2562,307 +2922,330 @@ static ImBuf *do_multicam( /* no effect inputs for adjustment, we use give_ibuf_seq */ static int num_inputs_adjustment(void) { - return 0; + return 0; } static int early_out_adjustment(Sequence *UNUSED(seq), float UNUSED(facf0), float UNUSED(facf1)) { - return EARLY_NO_INPUT; + return EARLY_NO_INPUT; } static ImBuf *do_adjustment_impl(const SeqRenderData *context, Sequence *seq, float cfra) { - Editing *ed; - ListBase *seqbasep; - ImBuf *i = NULL; + Editing *ed; + ListBase *seqbasep; + ImBuf *i = NULL; - ed = context->scene->ed; + ed = context->scene->ed; - seqbasep = BKE_sequence_seqbase(&ed->seqbase, seq); + seqbasep = BKE_sequence_seqbase(&ed->seqbase, seq); - if (seq->machine > 1) { - i = BKE_sequencer_give_ibuf_seqbase(context, cfra, seq->machine - 1, seqbasep); - } + if (seq->machine > 1) { + i = BKE_sequencer_give_ibuf_seqbase(context, cfra, seq->machine - 1, seqbasep); + } - /* found nothing? so let's work the way up the metastrip stack, so - * that it is possible to group a bunch of adjustment strips into - * a metastrip and have that work on everything below the metastrip - */ + /* found nothing? so let's work the way up the metastrip stack, so + * that it is possible to group a bunch of adjustment strips into + * a metastrip and have that work on everything below the metastrip + */ - if (!i) { - Sequence *meta; + if (!i) { + Sequence *meta; - meta = BKE_sequence_metastrip(&ed->seqbase, NULL, seq); + meta = BKE_sequence_metastrip(&ed->seqbase, NULL, seq); - if (meta) { - i = do_adjustment_impl(context, meta, cfra); - } - } + if (meta) { + i = do_adjustment_impl(context, meta, cfra); + } + } - return i; + return i; } -static ImBuf *do_adjustment( - const SeqRenderData *context, Sequence *seq, float cfra, float UNUSED(facf0), float UNUSED(facf1), - ImBuf *UNUSED(ibuf1), ImBuf *UNUSED(ibuf2), ImBuf *UNUSED(ibuf3)) +static ImBuf *do_adjustment(const SeqRenderData *context, + Sequence *seq, + float cfra, + float UNUSED(facf0), + float UNUSED(facf1), + ImBuf *UNUSED(ibuf1), + ImBuf *UNUSED(ibuf2), + ImBuf *UNUSED(ibuf3)) { - ImBuf *i = NULL; - ImBuf *out; - Editing *ed; + ImBuf *i = NULL; + ImBuf *out; + Editing *ed; - ed = context->scene->ed; + ed = context->scene->ed; - if (!ed) { - return NULL; - } + if (!ed) { + return NULL; + } - i = do_adjustment_impl(context, seq, cfra); + i = do_adjustment_impl(context, seq, cfra); - if (BKE_sequencer_input_have_to_preprocess(context, seq, cfra)) { - out = IMB_dupImBuf(i); - if (out) { - IMB_metadata_copy(out, i); - } - IMB_freeImBuf(i); - } - else { - out = i; - } + if (BKE_sequencer_input_have_to_preprocess(context, seq, cfra)) { + out = IMB_dupImBuf(i); + if (out) { + IMB_metadata_copy(out, i); + } + IMB_freeImBuf(i); + } + else { + out = i; + } - return out; + return out; } /*********************** Speed *************************/ static void init_speed_effect(Sequence *seq) { - SpeedControlVars *v; + SpeedControlVars *v; - if (seq->effectdata) - MEM_freeN(seq->effectdata); + if (seq->effectdata) + MEM_freeN(seq->effectdata); - seq->effectdata = MEM_callocN(sizeof(SpeedControlVars), "speedcontrolvars"); + seq->effectdata = MEM_callocN(sizeof(SpeedControlVars), "speedcontrolvars"); - v = (SpeedControlVars *)seq->effectdata; - v->globalSpeed = 1.0; - v->frameMap = NULL; - v->flags |= SEQ_SPEED_INTEGRATE; /* should be default behavior */ - v->length = 0; + v = (SpeedControlVars *)seq->effectdata; + v->globalSpeed = 1.0; + v->frameMap = NULL; + v->flags |= SEQ_SPEED_INTEGRATE; /* should be default behavior */ + v->length = 0; } static void load_speed_effect(Sequence *seq) { - SpeedControlVars *v = (SpeedControlVars *)seq->effectdata; + SpeedControlVars *v = (SpeedControlVars *)seq->effectdata; - v->frameMap = NULL; - v->length = 0; + v->frameMap = NULL; + v->length = 0; } static int num_inputs_speed(void) { - return 1; + return 1; } static void free_speed_effect(Sequence *seq, const bool UNUSED(do_id_user)) { - SpeedControlVars *v = (SpeedControlVars *)seq->effectdata; - if (v->frameMap) - MEM_freeN(v->frameMap); - if (seq->effectdata) - MEM_freeN(seq->effectdata); - seq->effectdata = NULL; + SpeedControlVars *v = (SpeedControlVars *)seq->effectdata; + if (v->frameMap) + MEM_freeN(v->frameMap); + if (seq->effectdata) + MEM_freeN(seq->effectdata); + seq->effectdata = NULL; } static void copy_speed_effect(Sequence *dst, Sequence *src, const int UNUSED(flag)) { - SpeedControlVars *v; - dst->effectdata = MEM_dupallocN(src->effectdata); - v = (SpeedControlVars *)dst->effectdata; - v->frameMap = NULL; - v->length = 0; + SpeedControlVars *v; + dst->effectdata = MEM_dupallocN(src->effectdata); + v = (SpeedControlVars *)dst->effectdata; + v->frameMap = NULL; + v->length = 0; } static int early_out_speed(Sequence *UNUSED(seq), float UNUSED(facf0), float UNUSED(facf1)) { - return EARLY_USE_INPUT_1; + return EARLY_USE_INPUT_1; } static void store_icu_yrange_speed(Sequence *seq, short UNUSED(adrcode), float *ymin, float *ymax) { - SpeedControlVars *v = (SpeedControlVars *)seq->effectdata; + SpeedControlVars *v = (SpeedControlVars *)seq->effectdata; - /* if not already done, load / initialize data */ - BKE_sequence_get_effect(seq); + /* if not already done, load / initialize data */ + BKE_sequence_get_effect(seq); - if ((v->flags & SEQ_SPEED_INTEGRATE) != 0) { - *ymin = -100.0; - *ymax = 100.0; - } - else { - if (v->flags & SEQ_SPEED_COMPRESS_IPO_Y) { - *ymin = 0.0; - *ymax = 1.0; - } - else { - *ymin = 0.0; - *ymax = seq->len; - } - } + if ((v->flags & SEQ_SPEED_INTEGRATE) != 0) { + *ymin = -100.0; + *ymax = 100.0; + } + else { + if (v->flags & SEQ_SPEED_COMPRESS_IPO_Y) { + *ymin = 0.0; + *ymax = 1.0; + } + else { + *ymin = 0.0; + *ymax = seq->len; + } + } } void BKE_sequence_effect_speed_rebuild_map(Scene *scene, Sequence *seq, bool force) { - int cfra; - float fallback_fac = 1.0f; - SpeedControlVars *v = (SpeedControlVars *) seq->effectdata; - FCurve *fcu = NULL; - int flags = v->flags; - - /* if not already done, load / initialize data */ - BKE_sequence_get_effect(seq); - - if ((force == false) && - (seq->len == v->length) && - (v->frameMap != NULL)) - { - return; - } - if ((seq->seq1 == NULL) || (seq->len < 1)) { - /* make coverity happy and check for (CID 598) input strip ... */ - return; - } - - /* XXX - new in 2.5x. should we use the animation system this way? - * The fcurve is needed because many frames need evaluating at once - campbell */ - fcu = id_data_find_fcurve(&scene->id, seq, &RNA_Sequence, "speed_factor", 0, NULL); - - - if (!v->frameMap || v->length != seq->len) { - if (v->frameMap) MEM_freeN(v->frameMap); - - v->length = seq->len; - - v->frameMap = MEM_callocN(sizeof(float) * v->length, "speedcontrol frameMap"); - } - - fallback_fac = 1.0; - - if (seq->flag & SEQ_USE_EFFECT_DEFAULT_FADE) { - if ((seq->seq1->enddisp != seq->seq1->start) && - (seq->seq1->len != 0)) - { - fallback_fac = (float) seq->seq1->len / (float) (seq->seq1->enddisp - seq->seq1->start); - flags = SEQ_SPEED_INTEGRATE; - fcu = NULL; - } - } - else { - /* if there is no fcurve, use value as simple multiplier */ - if (!fcu) { - fallback_fac = seq->speed_fader; /* same as speed_factor in rna*/ - } - } - - if (flags & SEQ_SPEED_INTEGRATE) { - float cursor = 0; - float facf; - - v->frameMap[0] = 0; - v->lastValidFrame = 0; - - for (cfra = 1; cfra < v->length; cfra++) { - if (fcu) { - facf = evaluate_fcurve(fcu, seq->startdisp + cfra); - } - else { - facf = fallback_fac; - } - facf *= v->globalSpeed; - - cursor += facf; - - if (cursor >= seq->seq1->len) { - v->frameMap[cfra] = seq->seq1->len - 1; - } - else { - v->frameMap[cfra] = cursor; - v->lastValidFrame = cfra; - } - } - } - else { - float facf; - - v->lastValidFrame = 0; - for (cfra = 0; cfra < v->length; cfra++) { - - if (fcu) { - facf = evaluate_fcurve(fcu, seq->startdisp + cfra); - } - else { - facf = fallback_fac; - } - - if (flags & SEQ_SPEED_COMPRESS_IPO_Y) { - facf *= seq->seq1->len; - } - facf *= v->globalSpeed; - - if (facf >= seq->seq1->len) { - facf = seq->seq1->len - 1; - } - else { - v->lastValidFrame = cfra; - } - v->frameMap[cfra] = facf; - } - } -} - -static ImBuf *do_speed_effect( - const SeqRenderData *context, Sequence *UNUSED(seq), float UNUSED(cfra), - float facf0, float facf1, ImBuf *ibuf1, ImBuf *ibuf2, ImBuf *ibuf3) -{ - ImBuf *out = prepare_effect_imbufs(context, ibuf1, ibuf2, ibuf3); - - if (out->rect_float) { - do_cross_effect_float( - facf0, facf1, context->rectx, context->recty, - ibuf1->rect_float, ibuf2->rect_float, out->rect_float); - } - else { - do_cross_effect_byte( - facf0, facf1, context->rectx, context->recty, - (unsigned char *) ibuf1->rect, (unsigned char *) ibuf2->rect, (unsigned char *) out->rect); - } - return out; + int cfra; + float fallback_fac = 1.0f; + SpeedControlVars *v = (SpeedControlVars *)seq->effectdata; + FCurve *fcu = NULL; + int flags = v->flags; + + /* if not already done, load / initialize data */ + BKE_sequence_get_effect(seq); + + if ((force == false) && (seq->len == v->length) && (v->frameMap != NULL)) { + return; + } + if ((seq->seq1 == NULL) || (seq->len < 1)) { + /* make coverity happy and check for (CID 598) input strip ... */ + return; + } + + /* XXX - new in 2.5x. should we use the animation system this way? + * The fcurve is needed because many frames need evaluating at once - campbell */ + fcu = id_data_find_fcurve(&scene->id, seq, &RNA_Sequence, "speed_factor", 0, NULL); + + if (!v->frameMap || v->length != seq->len) { + if (v->frameMap) + MEM_freeN(v->frameMap); + + v->length = seq->len; + + v->frameMap = MEM_callocN(sizeof(float) * v->length, "speedcontrol frameMap"); + } + + fallback_fac = 1.0; + + if (seq->flag & SEQ_USE_EFFECT_DEFAULT_FADE) { + if ((seq->seq1->enddisp != seq->seq1->start) && (seq->seq1->len != 0)) { + fallback_fac = (float)seq->seq1->len / (float)(seq->seq1->enddisp - seq->seq1->start); + flags = SEQ_SPEED_INTEGRATE; + fcu = NULL; + } + } + else { + /* if there is no fcurve, use value as simple multiplier */ + if (!fcu) { + fallback_fac = seq->speed_fader; /* same as speed_factor in rna*/ + } + } + + if (flags & SEQ_SPEED_INTEGRATE) { + float cursor = 0; + float facf; + + v->frameMap[0] = 0; + v->lastValidFrame = 0; + + for (cfra = 1; cfra < v->length; cfra++) { + if (fcu) { + facf = evaluate_fcurve(fcu, seq->startdisp + cfra); + } + else { + facf = fallback_fac; + } + facf *= v->globalSpeed; + + cursor += facf; + + if (cursor >= seq->seq1->len) { + v->frameMap[cfra] = seq->seq1->len - 1; + } + else { + v->frameMap[cfra] = cursor; + v->lastValidFrame = cfra; + } + } + } + else { + float facf; + + v->lastValidFrame = 0; + for (cfra = 0; cfra < v->length; cfra++) { + + if (fcu) { + facf = evaluate_fcurve(fcu, seq->startdisp + cfra); + } + else { + facf = fallback_fac; + } + + if (flags & SEQ_SPEED_COMPRESS_IPO_Y) { + facf *= seq->seq1->len; + } + facf *= v->globalSpeed; + + if (facf >= seq->seq1->len) { + facf = seq->seq1->len - 1; + } + else { + v->lastValidFrame = cfra; + } + v->frameMap[cfra] = facf; + } + } +} + +static ImBuf *do_speed_effect(const SeqRenderData *context, + Sequence *UNUSED(seq), + float UNUSED(cfra), + float facf0, + float facf1, + ImBuf *ibuf1, + ImBuf *ibuf2, + ImBuf *ibuf3) +{ + ImBuf *out = prepare_effect_imbufs(context, ibuf1, ibuf2, ibuf3); + + if (out->rect_float) { + do_cross_effect_float(facf0, + facf1, + context->rectx, + context->recty, + ibuf1->rect_float, + ibuf2->rect_float, + out->rect_float); + } + else { + do_cross_effect_byte(facf0, + facf1, + context->rectx, + context->recty, + (unsigned char *)ibuf1->rect, + (unsigned char *)ibuf2->rect, + (unsigned char *)out->rect); + } + return out; } /*********************** overdrop *************************/ -static void do_overdrop_effect( - const SeqRenderData *context, Sequence *UNUSED(seq), float UNUSED(cfra), float facf0, float facf1, - ImBuf *ibuf1, ImBuf *ibuf2, ImBuf *UNUSED(ibuf3), int start_line, int total_lines, ImBuf *out) +static void do_overdrop_effect(const SeqRenderData *context, + Sequence *UNUSED(seq), + float UNUSED(cfra), + float facf0, + float facf1, + ImBuf *ibuf1, + ImBuf *ibuf2, + ImBuf *UNUSED(ibuf3), + int start_line, + int total_lines, + ImBuf *out) { - int x = context->rectx; - int y = total_lines; + int x = context->rectx; + int y = total_lines; - if (out->rect_float) { - float *rect1 = NULL, *rect2 = NULL, *rect_out = NULL; + if (out->rect_float) { + float *rect1 = NULL, *rect2 = NULL, *rect_out = NULL; - slice_get_float_buffers(context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out); + slice_get_float_buffers( + context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out); - do_drop_effect_float(facf0, facf1, x, y, rect1, rect2, rect_out); - do_alphaover_effect_float(facf0, facf1, x, y, rect1, rect2, rect_out); - } - else { - unsigned char *rect1 = NULL, *rect2 = NULL, *rect_out = NULL; + do_drop_effect_float(facf0, facf1, x, y, rect1, rect2, rect_out); + do_alphaover_effect_float(facf0, facf1, x, y, rect1, rect2, rect_out); + } + else { + unsigned char *rect1 = NULL, *rect2 = NULL, *rect_out = NULL; - slice_get_byte_buffers(context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out); + slice_get_byte_buffers( + context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out); - do_drop_effect_byte(facf0, facf1, x, y, rect1, rect2, rect_out); - do_alphaover_effect_byte(facf0, facf1, x, y, rect1, rect2, rect_out); - } + do_drop_effect_byte(facf0, facf1, x, y, rect1, rect2, rect_out); + do_alphaover_effect_byte(facf0, facf1, x, y, rect1, rect2, rect_out); + } } /*********************** Gaussian Blur *************************/ @@ -2877,997 +3260,944 @@ static void do_overdrop_effect( static void init_gaussian_blur_effect(Sequence *seq) { - if (seq->effectdata) - MEM_freeN(seq->effectdata); + if (seq->effectdata) + MEM_freeN(seq->effectdata); - seq->effectdata = MEM_callocN(sizeof(WipeVars), "wipevars"); + seq->effectdata = MEM_callocN(sizeof(WipeVars), "wipevars"); } static int num_inputs_gaussian_blur(void) { - return 1; + return 1; } static void free_gaussian_blur_effect(Sequence *seq, const bool UNUSED(do_id_user)) { - if (seq->effectdata) - MEM_freeN(seq->effectdata); + if (seq->effectdata) + MEM_freeN(seq->effectdata); - seq->effectdata = NULL; + seq->effectdata = NULL; } static void copy_gaussian_blur_effect(Sequence *dst, Sequence *src, const int UNUSED(flag)) { - dst->effectdata = MEM_dupallocN(src->effectdata); + dst->effectdata = MEM_dupallocN(src->effectdata); } static int early_out_gaussian_blur(Sequence *seq, float UNUSED(facf0), float UNUSED(facf1)) { - GaussianBlurVars *data = seq->effectdata; - if (data->size_x == 0.0f && data->size_y == 0) { - return EARLY_USE_INPUT_1; - } - return EARLY_DO_EFFECT; + GaussianBlurVars *data = seq->effectdata; + if (data->size_x == 0.0f && data->size_y == 0) { + return EARLY_USE_INPUT_1; + } + return EARLY_DO_EFFECT; } /* TODO(sergey): De-duplicate with compositor. */ static float *make_gaussian_blur_kernel(float rad, int size) { - float *gausstab, sum, val; - float fac; - int i, n; + float *gausstab, sum, val; + float fac; + int i, n; - n = 2 * size + 1; + n = 2 * size + 1; - gausstab = (float *)MEM_mallocN(sizeof(float) * n, __func__); + gausstab = (float *)MEM_mallocN(sizeof(float) * n, __func__); - sum = 0.0f; - fac = (rad > 0.0f ? 1.0f / rad : 0.0f); - for (i = -size; i <= size; i++) { - val = RE_filter_value(R_FILTER_GAUSS, (float)i * fac); - sum += val; - gausstab[i + size] = val; - } + sum = 0.0f; + fac = (rad > 0.0f ? 1.0f / rad : 0.0f); + for (i = -size; i <= size; i++) { + val = RE_filter_value(R_FILTER_GAUSS, (float)i * fac); + sum += val; + gausstab[i + size] = val; + } - sum = 1.0f / sum; - for (i = 0; i < n; i++) - gausstab[i] *= sum; + sum = 1.0f / sum; + for (i = 0; i < n; i++) + gausstab[i] *= sum; - return gausstab; + return gausstab; } -static void do_gaussian_blur_effect_byte_x( - Sequence *seq, - int start_line, - int x, int y, - int frame_width, - int UNUSED(frame_height), - unsigned char *rect, - unsigned char *out) +static void do_gaussian_blur_effect_byte_x(Sequence *seq, + int start_line, + int x, + int y, + int frame_width, + int UNUSED(frame_height), + unsigned char *rect, + unsigned char *out) { #define INDEX(_x, _y) (((_y) * (x) + (_x)) * 4) - GaussianBlurVars *data = seq->effectdata; - const int size_x = (int) (data->size_x + 0.5f); - int i, j; - - /* Make gaussian weight table. */ - float *gausstab_x; - gausstab_x = make_gaussian_blur_kernel(data->size_x, size_x); - - for (i = 0; i < y; ++i) { - for (j = 0; j < x; ++j) { - int out_index = INDEX(j, i); - float accum[4] = {0.0f, 0.0f, 0.0f, 0.0f}; - float accum_weight = 0.0f; - - for (int current_x = j - size_x; - current_x <= j + size_x; - ++current_x) - { - if (current_x < 0 || current_x >= frame_width) { - /* Out of bounds. */ - continue; - } - int index = INDEX(current_x, i + start_line); - float weight = gausstab_x[current_x - j + size_x]; - accum[0] += rect[index] * weight; - accum[1] += rect[index + 1] * weight; - accum[2] += rect[index + 2] * weight; - accum[3] += rect[index + 3] * weight; - accum_weight += weight; - } - - float inv_accum_weight = 1.0f / accum_weight; - out[out_index + 0] = accum[0] * inv_accum_weight; - out[out_index + 1] = accum[1] * inv_accum_weight; - out[out_index + 2] = accum[2] * inv_accum_weight; - out[out_index + 3] = accum[3] * inv_accum_weight; - } - } - - MEM_freeN(gausstab_x); + GaussianBlurVars *data = seq->effectdata; + const int size_x = (int)(data->size_x + 0.5f); + int i, j; + + /* Make gaussian weight table. */ + float *gausstab_x; + gausstab_x = make_gaussian_blur_kernel(data->size_x, size_x); + + for (i = 0; i < y; ++i) { + for (j = 0; j < x; ++j) { + int out_index = INDEX(j, i); + float accum[4] = {0.0f, 0.0f, 0.0f, 0.0f}; + float accum_weight = 0.0f; + + for (int current_x = j - size_x; current_x <= j + size_x; ++current_x) { + if (current_x < 0 || current_x >= frame_width) { + /* Out of bounds. */ + continue; + } + int index = INDEX(current_x, i + start_line); + float weight = gausstab_x[current_x - j + size_x]; + accum[0] += rect[index] * weight; + accum[1] += rect[index + 1] * weight; + accum[2] += rect[index + 2] * weight; + accum[3] += rect[index + 3] * weight; + accum_weight += weight; + } + + float inv_accum_weight = 1.0f / accum_weight; + out[out_index + 0] = accum[0] * inv_accum_weight; + out[out_index + 1] = accum[1] * inv_accum_weight; + out[out_index + 2] = accum[2] * inv_accum_weight; + out[out_index + 3] = accum[3] * inv_accum_weight; + } + } + + MEM_freeN(gausstab_x); #undef INDEX } -static void do_gaussian_blur_effect_byte_y( - Sequence *seq, - int start_line, - int x, int y, - int UNUSED(frame_width), - int frame_height, - unsigned char *rect, - unsigned char *out) +static void do_gaussian_blur_effect_byte_y(Sequence *seq, + int start_line, + int x, + int y, + int UNUSED(frame_width), + int frame_height, + unsigned char *rect, + unsigned char *out) { #define INDEX(_x, _y) (((_y) * (x) + (_x)) * 4) - GaussianBlurVars *data = seq->effectdata; - const int size_y = (int) (data->size_y + 0.5f); - int i, j; - - /* Make gaussian weight table. */ - float *gausstab_y; - gausstab_y = make_gaussian_blur_kernel(data->size_y, size_y); - - for (i = 0; i < y; ++i) { - for (j = 0; j < x; ++j) { - int out_index = INDEX(j, i); - float accum[4] = {0.0f, 0.0f, 0.0f, 0.0f}; - float accum_weight = 0.0f; - for (int current_y = i - size_y; - current_y <= i + size_y; - ++current_y) - { - if (current_y < -start_line || - current_y + start_line >= frame_height) - { - /* Out of bounds. */ - continue; - } - int index = INDEX(j, current_y + start_line); - float weight = gausstab_y[current_y - i + size_y]; - accum[0] += rect[index] * weight; - accum[1] += rect[index + 1] * weight; - accum[2] += rect[index + 2] * weight; - accum[3] += rect[index + 3] * weight; - accum_weight += weight; - } - float inv_accum_weight = 1.0f / accum_weight; - out[out_index + 0] = accum[0] * inv_accum_weight; - out[out_index + 1] = accum[1] * inv_accum_weight; - out[out_index + 2] = accum[2] * inv_accum_weight; - out[out_index + 3] = accum[3] * inv_accum_weight; - } - } - - MEM_freeN(gausstab_y); + GaussianBlurVars *data = seq->effectdata; + const int size_y = (int)(data->size_y + 0.5f); + int i, j; + + /* Make gaussian weight table. */ + float *gausstab_y; + gausstab_y = make_gaussian_blur_kernel(data->size_y, size_y); + + for (i = 0; i < y; ++i) { + for (j = 0; j < x; ++j) { + int out_index = INDEX(j, i); + float accum[4] = {0.0f, 0.0f, 0.0f, 0.0f}; + float accum_weight = 0.0f; + for (int current_y = i - size_y; current_y <= i + size_y; ++current_y) { + if (current_y < -start_line || current_y + start_line >= frame_height) { + /* Out of bounds. */ + continue; + } + int index = INDEX(j, current_y + start_line); + float weight = gausstab_y[current_y - i + size_y]; + accum[0] += rect[index] * weight; + accum[1] += rect[index + 1] * weight; + accum[2] += rect[index + 2] * weight; + accum[3] += rect[index + 3] * weight; + accum_weight += weight; + } + float inv_accum_weight = 1.0f / accum_weight; + out[out_index + 0] = accum[0] * inv_accum_weight; + out[out_index + 1] = accum[1] * inv_accum_weight; + out[out_index + 2] = accum[2] * inv_accum_weight; + out[out_index + 3] = accum[3] * inv_accum_weight; + } + } + + MEM_freeN(gausstab_y); #undef INDEX } -static void do_gaussian_blur_effect_float_x( - Sequence *seq, - int start_line, - int x, int y, - int frame_width, - int UNUSED(frame_height), - float *rect, - float *out) +static void do_gaussian_blur_effect_float_x(Sequence *seq, + int start_line, + int x, + int y, + int frame_width, + int UNUSED(frame_height), + float *rect, + float *out) { #define INDEX(_x, _y) (((_y) * (x) + (_x)) * 4) - GaussianBlurVars *data = seq->effectdata; - const int size_x = (int) (data->size_x + 0.5f); - int i, j; - - /* Make gaussian weight table. */ - float *gausstab_x; - gausstab_x = make_gaussian_blur_kernel(data->size_x, size_x); - - for (i = 0; i < y; ++i) { - for (j = 0; j < x; ++j) { - int out_index = INDEX(j, i); - float accum[4] = {0.0f, 0.0f, 0.0f, 0.0f}; - float accum_weight = 0.0f; - for (int current_x = j - size_x; - current_x <= j + size_x; - ++current_x) - { - if (current_x < 0 || current_x >= frame_width) { - /* Out of bounds. */ - continue; - } - int index = INDEX(current_x, i + start_line); - float weight = gausstab_x[current_x - j + size_x]; - madd_v4_v4fl(accum, &rect[index], weight); - accum_weight += weight; - } - mul_v4_v4fl(&out[out_index], accum, 1.0f / accum_weight); - } - } - - MEM_freeN(gausstab_x); + GaussianBlurVars *data = seq->effectdata; + const int size_x = (int)(data->size_x + 0.5f); + int i, j; + + /* Make gaussian weight table. */ + float *gausstab_x; + gausstab_x = make_gaussian_blur_kernel(data->size_x, size_x); + + for (i = 0; i < y; ++i) { + for (j = 0; j < x; ++j) { + int out_index = INDEX(j, i); + float accum[4] = {0.0f, 0.0f, 0.0f, 0.0f}; + float accum_weight = 0.0f; + for (int current_x = j - size_x; current_x <= j + size_x; ++current_x) { + if (current_x < 0 || current_x >= frame_width) { + /* Out of bounds. */ + continue; + } + int index = INDEX(current_x, i + start_line); + float weight = gausstab_x[current_x - j + size_x]; + madd_v4_v4fl(accum, &rect[index], weight); + accum_weight += weight; + } + mul_v4_v4fl(&out[out_index], accum, 1.0f / accum_weight); + } + } + + MEM_freeN(gausstab_x); #undef INDEX } -static void do_gaussian_blur_effect_float_y( - Sequence *seq, - int start_line, - int x, int y, - int UNUSED(frame_width), - int frame_height, - float *rect, - float *out) +static void do_gaussian_blur_effect_float_y(Sequence *seq, + int start_line, + int x, + int y, + int UNUSED(frame_width), + int frame_height, + float *rect, + float *out) { #define INDEX(_x, _y) (((_y) * (x) + (_x)) * 4) - GaussianBlurVars *data = seq->effectdata; - const int size_y = (int) (data->size_y + 0.5f); - int i, j; - - /* Make gaussian weight table. */ - float *gausstab_y; - gausstab_y = make_gaussian_blur_kernel(data->size_y, size_y); - - for (i = 0; i < y; ++i) { - for (j = 0; j < x; ++j) { - int out_index = INDEX(j, i); - float accum[4] = {0.0f, 0.0f, 0.0f, 0.0f}; - float accum_weight = 0.0f; - for (int current_y = i - size_y; - current_y <= i + size_y; - ++current_y) - { - if (current_y < -start_line || - current_y + start_line >= frame_height) - { - /* Out of bounds. */ - continue; - } - int index = INDEX(j, current_y + start_line); - float weight = gausstab_y[current_y - i + size_y]; - madd_v4_v4fl(accum, &rect[index], weight); - accum_weight += weight; - } - mul_v4_v4fl(&out[out_index], accum, 1.0f / accum_weight); - } - } - - MEM_freeN(gausstab_y); + GaussianBlurVars *data = seq->effectdata; + const int size_y = (int)(data->size_y + 0.5f); + int i, j; + + /* Make gaussian weight table. */ + float *gausstab_y; + gausstab_y = make_gaussian_blur_kernel(data->size_y, size_y); + + for (i = 0; i < y; ++i) { + for (j = 0; j < x; ++j) { + int out_index = INDEX(j, i); + float accum[4] = {0.0f, 0.0f, 0.0f, 0.0f}; + float accum_weight = 0.0f; + for (int current_y = i - size_y; current_y <= i + size_y; ++current_y) { + if (current_y < -start_line || current_y + start_line >= frame_height) { + /* Out of bounds. */ + continue; + } + int index = INDEX(j, current_y + start_line); + float weight = gausstab_y[current_y - i + size_y]; + madd_v4_v4fl(accum, &rect[index], weight); + accum_weight += weight; + } + mul_v4_v4fl(&out[out_index], accum, 1.0f / accum_weight); + } + } + + MEM_freeN(gausstab_y); #undef INDEX } -static void do_gaussian_blur_effect_x_cb( - const SeqRenderData *context, - Sequence *seq, - ImBuf *ibuf, - int start_line, - int total_lines, - ImBuf *out) -{ - if (out->rect_float) { - float *rect1 = NULL, *rect2 = NULL, *rect_out = NULL; - - slice_get_float_buffers( - context, - ibuf, - NULL, - NULL, - out, - start_line, - &rect1, - &rect2, - NULL, - &rect_out); - - do_gaussian_blur_effect_float_x( - seq, - start_line, - context->rectx, - total_lines, - context->rectx, - context->recty, - ibuf->rect_float, - rect_out); - } - else { - unsigned char *rect1 = NULL, *rect2 = NULL, *rect_out = NULL; - - slice_get_byte_buffers( - context, - ibuf, - NULL, - NULL, - out, - start_line, - &rect1, - &rect2, - NULL, - &rect_out); - - do_gaussian_blur_effect_byte_x( - seq, - start_line, - context->rectx, - total_lines, - context->rectx, - context->recty, - (unsigned char *) ibuf->rect, - rect_out); - } -} - -static void do_gaussian_blur_effect_y_cb( - const SeqRenderData *context, - Sequence *seq, - ImBuf *ibuf, - int start_line, - int total_lines, - ImBuf *out) -{ - if (out->rect_float) { - float *rect1 = NULL, *rect2 = NULL, *rect_out = NULL; - - slice_get_float_buffers( - context, - ibuf, - NULL, - NULL, - out, - start_line, - &rect1, - &rect2, - NULL, - &rect_out); - - do_gaussian_blur_effect_float_y( - seq, - start_line, - context->rectx, - total_lines, - context->rectx, - context->recty, - ibuf->rect_float, - rect_out); - } - else { - unsigned char *rect1 = NULL, *rect2 = NULL, *rect_out = NULL; - - slice_get_byte_buffers( - context, - ibuf, - NULL, - NULL, - out, - start_line, - &rect1, - &rect2, - NULL, - &rect_out); - - do_gaussian_blur_effect_byte_y( - seq, - start_line, - context->rectx, - total_lines, - context->rectx, - context->recty, - (unsigned char *) ibuf->rect, - rect_out); - } +static void do_gaussian_blur_effect_x_cb(const SeqRenderData *context, + Sequence *seq, + ImBuf *ibuf, + int start_line, + int total_lines, + ImBuf *out) +{ + if (out->rect_float) { + float *rect1 = NULL, *rect2 = NULL, *rect_out = NULL; + + slice_get_float_buffers( + context, ibuf, NULL, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out); + + do_gaussian_blur_effect_float_x(seq, + start_line, + context->rectx, + total_lines, + context->rectx, + context->recty, + ibuf->rect_float, + rect_out); + } + else { + unsigned char *rect1 = NULL, *rect2 = NULL, *rect_out = NULL; + + slice_get_byte_buffers( + context, ibuf, NULL, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out); + + do_gaussian_blur_effect_byte_x(seq, + start_line, + context->rectx, + total_lines, + context->rectx, + context->recty, + (unsigned char *)ibuf->rect, + rect_out); + } +} + +static void do_gaussian_blur_effect_y_cb(const SeqRenderData *context, + Sequence *seq, + ImBuf *ibuf, + int start_line, + int total_lines, + ImBuf *out) +{ + if (out->rect_float) { + float *rect1 = NULL, *rect2 = NULL, *rect_out = NULL; + + slice_get_float_buffers( + context, ibuf, NULL, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out); + + do_gaussian_blur_effect_float_y(seq, + start_line, + context->rectx, + total_lines, + context->rectx, + context->recty, + ibuf->rect_float, + rect_out); + } + else { + unsigned char *rect1 = NULL, *rect2 = NULL, *rect_out = NULL; + + slice_get_byte_buffers( + context, ibuf, NULL, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out); + + do_gaussian_blur_effect_byte_y(seq, + start_line, + context->rectx, + total_lines, + context->rectx, + context->recty, + (unsigned char *)ibuf->rect, + rect_out); + } } typedef struct RenderGaussianBlurEffectInitData { - const SeqRenderData *context; - Sequence *seq; - ImBuf *ibuf; - ImBuf *out; + const SeqRenderData *context; + Sequence *seq; + ImBuf *ibuf; + ImBuf *out; } RenderGaussianBlurEffectInitData; typedef struct RenderGaussianBlurEffectThread { - const SeqRenderData *context; - Sequence *seq; - ImBuf *ibuf; - ImBuf *out; - int start_line, tot_line; + const SeqRenderData *context; + Sequence *seq; + ImBuf *ibuf; + ImBuf *out; + int start_line, tot_line; } RenderGaussianBlurEffectThread; -static void render_effect_execute_init_handle( - void *handle_v, - int start_line, - int tot_line, - void *init_data_v) +static void render_effect_execute_init_handle(void *handle_v, + int start_line, + int tot_line, + void *init_data_v) { - RenderGaussianBlurEffectThread *handle = (RenderGaussianBlurEffectThread *) handle_v; - RenderGaussianBlurEffectInitData *init_data = (RenderGaussianBlurEffectInitData *) init_data_v; + RenderGaussianBlurEffectThread *handle = (RenderGaussianBlurEffectThread *)handle_v; + RenderGaussianBlurEffectInitData *init_data = (RenderGaussianBlurEffectInitData *)init_data_v; - handle->context = init_data->context; - handle->seq = init_data->seq; - handle->ibuf = init_data->ibuf; - handle->out = init_data->out; + handle->context = init_data->context; + handle->seq = init_data->seq; + handle->ibuf = init_data->ibuf; + handle->out = init_data->out; - handle->start_line = start_line; - handle->tot_line = tot_line; + handle->start_line = start_line; + handle->tot_line = tot_line; } static void *render_effect_execute_do_x_thread(void *thread_data_v) { - RenderGaussianBlurEffectThread *thread_data = (RenderGaussianBlurEffectThread *) thread_data_v; - do_gaussian_blur_effect_x_cb( - thread_data->context, - thread_data->seq, - thread_data->ibuf, - thread_data->start_line, - thread_data->tot_line, - thread_data->out); - return NULL; + RenderGaussianBlurEffectThread *thread_data = (RenderGaussianBlurEffectThread *)thread_data_v; + do_gaussian_blur_effect_x_cb(thread_data->context, + thread_data->seq, + thread_data->ibuf, + thread_data->start_line, + thread_data->tot_line, + thread_data->out); + return NULL; } static void *render_effect_execute_do_y_thread(void *thread_data_v) { - RenderGaussianBlurEffectThread *thread_data = (RenderGaussianBlurEffectThread *) thread_data_v; - do_gaussian_blur_effect_y_cb( - thread_data->context, - thread_data->seq, - thread_data->ibuf, - thread_data->start_line, - thread_data->tot_line, - thread_data->out); + RenderGaussianBlurEffectThread *thread_data = (RenderGaussianBlurEffectThread *)thread_data_v; + do_gaussian_blur_effect_y_cb(thread_data->context, + thread_data->seq, + thread_data->ibuf, + thread_data->start_line, + thread_data->tot_line, + thread_data->out); - return NULL; + return NULL; } -static ImBuf *do_gaussian_blur_effect( - const SeqRenderData *context, - Sequence *seq, - float UNUSED(cfra), - float UNUSED(facf0), - float UNUSED(facf1), - ImBuf *ibuf1, - ImBuf *UNUSED(ibuf2), - ImBuf *UNUSED(ibuf3)) +static ImBuf *do_gaussian_blur_effect(const SeqRenderData *context, + Sequence *seq, + float UNUSED(cfra), + float UNUSED(facf0), + float UNUSED(facf1), + ImBuf *ibuf1, + ImBuf *UNUSED(ibuf2), + ImBuf *UNUSED(ibuf3)) { - ImBuf *out = prepare_effect_imbufs(context, ibuf1, NULL, NULL); + ImBuf *out = prepare_effect_imbufs(context, ibuf1, NULL, NULL); - RenderGaussianBlurEffectInitData init_data; + RenderGaussianBlurEffectInitData init_data; - init_data.context = context; - init_data.seq = seq; - init_data.ibuf = ibuf1; - init_data.out = out; + init_data.context = context; + init_data.seq = seq; + init_data.ibuf = ibuf1; + init_data.out = out; - IMB_processor_apply_threaded( - out->y, - sizeof(RenderGaussianBlurEffectThread), - &init_data, - render_effect_execute_init_handle, - render_effect_execute_do_x_thread); + IMB_processor_apply_threaded(out->y, + sizeof(RenderGaussianBlurEffectThread), + &init_data, + render_effect_execute_init_handle, + render_effect_execute_do_x_thread); - ibuf1 = out; - init_data.ibuf = ibuf1; - out = prepare_effect_imbufs(context, ibuf1, NULL, NULL); - init_data.out = out; + ibuf1 = out; + init_data.ibuf = ibuf1; + out = prepare_effect_imbufs(context, ibuf1, NULL, NULL); + init_data.out = out; - IMB_processor_apply_threaded( - out->y, - sizeof(RenderGaussianBlurEffectThread), - &init_data, - render_effect_execute_init_handle, - render_effect_execute_do_y_thread); + IMB_processor_apply_threaded(out->y, + sizeof(RenderGaussianBlurEffectThread), + &init_data, + render_effect_execute_init_handle, + render_effect_execute_do_y_thread); - IMB_freeImBuf(ibuf1); + IMB_freeImBuf(ibuf1); - return out; + return out; } /*********************** text *************************/ static void init_text_effect(Sequence *seq) { - TextVars *data; + TextVars *data; - if (seq->effectdata) - MEM_freeN(seq->effectdata); + if (seq->effectdata) + MEM_freeN(seq->effectdata); - data = seq->effectdata = MEM_callocN(sizeof(TextVars), "textvars"); - data->text_font = NULL; - data->text_blf_id = -1; - data->text_size = 30; + data = seq->effectdata = MEM_callocN(sizeof(TextVars), "textvars"); + data->text_font = NULL; + data->text_blf_id = -1; + data->text_size = 30; - copy_v4_fl(data->color, 1.0f); - data->shadow_color[3] = 1.0f; + copy_v4_fl(data->color, 1.0f); + data->shadow_color[3] = 1.0f; - BLI_strncpy(data->text, "Text", sizeof(data->text)); + BLI_strncpy(data->text, "Text", sizeof(data->text)); - data->loc[0] = 0.5f; - data->align = SEQ_TEXT_ALIGN_X_CENTER; - data->align_y = SEQ_TEXT_ALIGN_Y_BOTTOM; + data->loc[0] = 0.5f; + data->align = SEQ_TEXT_ALIGN_X_CENTER; + data->align_y = SEQ_TEXT_ALIGN_Y_BOTTOM; } void BKE_sequencer_text_font_unload(TextVars *data, const bool do_id_user) { - if (data) { - /* Unlink the VFont */ - if (do_id_user && data->text_font != NULL) { - id_us_min(&data->text_font->id); - data->text_font = NULL; - } + if (data) { + /* Unlink the VFont */ + if (do_id_user && data->text_font != NULL) { + id_us_min(&data->text_font->id); + data->text_font = NULL; + } - /* Unload the BLF font. */ - if (data->text_blf_id >= 0) { - BLF_unload_id(data->text_blf_id); - } - } + /* Unload the BLF font. */ + if (data->text_blf_id >= 0) { + BLF_unload_id(data->text_blf_id); + } + } } void BKE_sequencer_text_font_load(TextVars *data, const bool do_id_user) { - if (data->text_font != NULL) { - if (do_id_user) { - id_us_plus(&data->text_font->id); - } + if (data->text_font != NULL) { + if (do_id_user) { + id_us_plus(&data->text_font->id); + } - char path[FILE_MAX]; - STRNCPY(path, data->text_font->name); - BLI_assert(BLI_thread_is_main()); - BLI_path_abs(path, BKE_main_blendfile_path_from_global()); + char path[FILE_MAX]; + STRNCPY(path, data->text_font->name); + BLI_assert(BLI_thread_is_main()); + BLI_path_abs(path, BKE_main_blendfile_path_from_global()); - data->text_blf_id = BLF_load(path); - } + data->text_blf_id = BLF_load(path); + } } static void free_text_effect(Sequence *seq, const bool do_id_user) { - TextVars *data = seq->effectdata; - BKE_sequencer_text_font_unload(data, do_id_user); + TextVars *data = seq->effectdata; + BKE_sequencer_text_font_unload(data, do_id_user); - if (data) { - MEM_freeN(data); - seq->effectdata = NULL; - } + if (data) { + MEM_freeN(data); + seq->effectdata = NULL; + } } static void load_text_effect(Sequence *seq) { - TextVars *data = seq->effectdata; - BKE_sequencer_text_font_load(data, false); + TextVars *data = seq->effectdata; + BKE_sequencer_text_font_load(data, false); } static void copy_text_effect(Sequence *dst, Sequence *src, const int flag) { - dst->effectdata = MEM_dupallocN(src->effectdata); - TextVars *data = dst->effectdata; + dst->effectdata = MEM_dupallocN(src->effectdata); + TextVars *data = dst->effectdata; - data->text_blf_id = -1; - BKE_sequencer_text_font_load(data, (flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0); + data->text_blf_id = -1; + BKE_sequencer_text_font_load(data, (flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0); } static int num_inputs_text(void) { - return 0; + return 0; } static int early_out_text(Sequence *seq, float UNUSED(facf0), float UNUSED(facf1)) { - TextVars *data = seq->effectdata; - if (data->text[0] == 0 || data->text_size < 1 || - ((data->color[3] == 0.0f) && (data->shadow_color[3] == 0.0f || (data->flag & SEQ_TEXT_SHADOW) == 0))) - { - return EARLY_USE_INPUT_1; - } - return EARLY_NO_INPUT; -} - -static ImBuf *do_text_effect( - const SeqRenderData *context, Sequence *seq, float UNUSED(cfra), float UNUSED(facf0), float UNUSED(facf1), - ImBuf *ibuf1, ImBuf *ibuf2, ImBuf *ibuf3) -{ - ImBuf *out = prepare_effect_imbufs(context, ibuf1, ibuf2, ibuf3); - TextVars *data = seq->effectdata; - int width = out->x; - int height = out->y; - struct ColorManagedDisplay *display; - const char *display_device; - int font = blf_mono_font_render; - int line_height; - int y_ofs, x, y; - float proxy_size_comp; - - if (data->text_blf_id == SEQ_FONT_NOT_LOADED) { - data->text_blf_id = -1; - - if (data->text_font) { - data->text_blf_id = BLF_load(data->text_font->name); - } - } - - if (data->text_blf_id >= 0) { - font = data->text_blf_id; - } - - display_device = context->scene->display_settings.display_device; - display = IMB_colormanagement_display_get_named(display_device); - - /* Compensate text size for preview render size. */ - if (ELEM(context->preview_render_size, SEQ_PROXY_RENDER_SIZE_SCENE, SEQ_PROXY_RENDER_SIZE_FULL)) { - proxy_size_comp = context->scene->r.size / 100.0f; - } - else if (context->preview_render_size == SEQ_PROXY_RENDER_SIZE_100) { - proxy_size_comp = 1.0f; - } - else { - proxy_size_comp = context->preview_render_size / 100.0f; - } - - /* set before return */ - BLF_size(font, proxy_size_comp * data->text_size, 72); - - BLF_enable(font, BLF_WORD_WRAP); - - /* use max width to enable newlines only */ - BLF_wordwrap(font, (data->wrap_width != 0.0f) ? data->wrap_width * width : -1); - - BLF_buffer(font, out->rect_float, (unsigned char *)out->rect, width, height, out->channels, display); - - line_height = BLF_height_max(font); - - y_ofs = -BLF_descender(font); - - x = (data->loc[0] * width); - y = (data->loc[1] * height) + y_ofs; - - if ((data->align == SEQ_TEXT_ALIGN_X_LEFT) && - (data->align_y == SEQ_TEXT_ALIGN_Y_TOP)) - { - y -= line_height; - } - else { - /* vars for calculating wordwrap */ - struct { - struct ResultBLF info; - rctf rect; - } wrap; - - BLF_boundbox_ex(font, data->text, sizeof(data->text), &wrap.rect, &wrap.info); - - if (data->align == SEQ_TEXT_ALIGN_X_RIGHT) { - x -= BLI_rctf_size_x(&wrap.rect); - } - else if (data->align == SEQ_TEXT_ALIGN_X_CENTER) { - x -= BLI_rctf_size_x(&wrap.rect) / 2; - } - - if (data->align_y == SEQ_TEXT_ALIGN_Y_TOP) { - y -= line_height; - } - else if (data->align_y == SEQ_TEXT_ALIGN_Y_BOTTOM) { - y += (wrap.info.lines - 1) * line_height; - } - else if (data->align_y == SEQ_TEXT_ALIGN_Y_CENTER) { - y += (((wrap.info.lines - 1) / 2) * line_height) - (line_height / 2); - } - } - - /* BLF_SHADOW won't work with buffers, instead use cheap shadow trick */ - if (data->flag & SEQ_TEXT_SHADOW) { - int fontx, fonty; - fontx = BLF_width_max(font); - fonty = line_height; - BLF_position(font, x + max_ii(fontx / 25, 1), y + max_ii(fonty / 25, 1), 0.0f); - BLF_buffer_col(font, data->shadow_color); - BLF_draw_buffer(font, data->text, BLF_DRAW_STR_DUMMY_MAX); - } - - BLF_position(font, x, y, 0.0f); - BLF_buffer_col(font, data->color); - BLF_draw_buffer(font, data->text, BLF_DRAW_STR_DUMMY_MAX); - - BLF_buffer(font, NULL, NULL, 0, 0, 0, NULL); - - BLF_disable(font, BLF_WORD_WRAP); - - return out; + TextVars *data = seq->effectdata; + if (data->text[0] == 0 || data->text_size < 1 || + ((data->color[3] == 0.0f) && + (data->shadow_color[3] == 0.0f || (data->flag & SEQ_TEXT_SHADOW) == 0))) { + return EARLY_USE_INPUT_1; + } + return EARLY_NO_INPUT; +} + +static ImBuf *do_text_effect(const SeqRenderData *context, + Sequence *seq, + float UNUSED(cfra), + float UNUSED(facf0), + float UNUSED(facf1), + ImBuf *ibuf1, + ImBuf *ibuf2, + ImBuf *ibuf3) +{ + ImBuf *out = prepare_effect_imbufs(context, ibuf1, ibuf2, ibuf3); + TextVars *data = seq->effectdata; + int width = out->x; + int height = out->y; + struct ColorManagedDisplay *display; + const char *display_device; + int font = blf_mono_font_render; + int line_height; + int y_ofs, x, y; + float proxy_size_comp; + + if (data->text_blf_id == SEQ_FONT_NOT_LOADED) { + data->text_blf_id = -1; + + if (data->text_font) { + data->text_blf_id = BLF_load(data->text_font->name); + } + } + + if (data->text_blf_id >= 0) { + font = data->text_blf_id; + } + + display_device = context->scene->display_settings.display_device; + display = IMB_colormanagement_display_get_named(display_device); + + /* Compensate text size for preview render size. */ + if (ELEM( + context->preview_render_size, SEQ_PROXY_RENDER_SIZE_SCENE, SEQ_PROXY_RENDER_SIZE_FULL)) { + proxy_size_comp = context->scene->r.size / 100.0f; + } + else if (context->preview_render_size == SEQ_PROXY_RENDER_SIZE_100) { + proxy_size_comp = 1.0f; + } + else { + proxy_size_comp = context->preview_render_size / 100.0f; + } + + /* set before return */ + BLF_size(font, proxy_size_comp * data->text_size, 72); + + BLF_enable(font, BLF_WORD_WRAP); + + /* use max width to enable newlines only */ + BLF_wordwrap(font, (data->wrap_width != 0.0f) ? data->wrap_width * width : -1); + + BLF_buffer( + font, out->rect_float, (unsigned char *)out->rect, width, height, out->channels, display); + + line_height = BLF_height_max(font); + + y_ofs = -BLF_descender(font); + + x = (data->loc[0] * width); + y = (data->loc[1] * height) + y_ofs; + + if ((data->align == SEQ_TEXT_ALIGN_X_LEFT) && (data->align_y == SEQ_TEXT_ALIGN_Y_TOP)) { + y -= line_height; + } + else { + /* vars for calculating wordwrap */ + struct { + struct ResultBLF info; + rctf rect; + } wrap; + + BLF_boundbox_ex(font, data->text, sizeof(data->text), &wrap.rect, &wrap.info); + + if (data->align == SEQ_TEXT_ALIGN_X_RIGHT) { + x -= BLI_rctf_size_x(&wrap.rect); + } + else if (data->align == SEQ_TEXT_ALIGN_X_CENTER) { + x -= BLI_rctf_size_x(&wrap.rect) / 2; + } + + if (data->align_y == SEQ_TEXT_ALIGN_Y_TOP) { + y -= line_height; + } + else if (data->align_y == SEQ_TEXT_ALIGN_Y_BOTTOM) { + y += (wrap.info.lines - 1) * line_height; + } + else if (data->align_y == SEQ_TEXT_ALIGN_Y_CENTER) { + y += (((wrap.info.lines - 1) / 2) * line_height) - (line_height / 2); + } + } + + /* BLF_SHADOW won't work with buffers, instead use cheap shadow trick */ + if (data->flag & SEQ_TEXT_SHADOW) { + int fontx, fonty; + fontx = BLF_width_max(font); + fonty = line_height; + BLF_position(font, x + max_ii(fontx / 25, 1), y + max_ii(fonty / 25, 1), 0.0f); + BLF_buffer_col(font, data->shadow_color); + BLF_draw_buffer(font, data->text, BLF_DRAW_STR_DUMMY_MAX); + } + + BLF_position(font, x, y, 0.0f); + BLF_buffer_col(font, data->color); + BLF_draw_buffer(font, data->text, BLF_DRAW_STR_DUMMY_MAX); + + BLF_buffer(font, NULL, NULL, 0, 0, 0, NULL); + + BLF_disable(font, BLF_WORD_WRAP); + + return out; } /*********************** sequence effect factory *************************/ static void init_noop(Sequence *UNUSED(seq)) { - } static void load_noop(Sequence *UNUSED(seq)) { - } static void free_noop(Sequence *UNUSED(seq), const bool UNUSED(do_id_user)) { - } static int num_inputs_default(void) { - return 2; + return 2; } static void copy_effect_default(Sequence *dst, Sequence *src, const int UNUSED(flag)) { - dst->effectdata = MEM_dupallocN(src->effectdata); + dst->effectdata = MEM_dupallocN(src->effectdata); } static void free_effect_default(Sequence *seq, const bool UNUSED(do_id_user)) { - if (seq->effectdata) - MEM_freeN(seq->effectdata); + if (seq->effectdata) + MEM_freeN(seq->effectdata); - seq->effectdata = NULL; + seq->effectdata = NULL; } static int early_out_noop(Sequence *UNUSED(seq), float UNUSED(facf0), float UNUSED(facf1)) { - return EARLY_DO_EFFECT; + return EARLY_DO_EFFECT; } static int early_out_fade(Sequence *UNUSED(seq), float facf0, float facf1) { - if (facf0 == 0.0f && facf1 == 0.0f) { - return EARLY_USE_INPUT_1; - } - else if (facf0 == 1.0f && facf1 == 1.0f) { - return EARLY_USE_INPUT_2; - } - return EARLY_DO_EFFECT; + if (facf0 == 0.0f && facf1 == 0.0f) { + return EARLY_USE_INPUT_1; + } + else if (facf0 == 1.0f && facf1 == 1.0f) { + return EARLY_USE_INPUT_2; + } + return EARLY_DO_EFFECT; } static int early_out_mul_input2(Sequence *UNUSED(seq), float facf0, float facf1) { - if (facf0 == 0.0f && facf1 == 0.0f) { - return EARLY_USE_INPUT_1; - } - return EARLY_DO_EFFECT; + if (facf0 == 0.0f && facf1 == 0.0f) { + return EARLY_USE_INPUT_1; + } + return EARLY_DO_EFFECT; } -static void store_icu_yrange_noop(Sequence *UNUSED(seq), short UNUSED(adrcode), float *UNUSED(ymin), float *UNUSED(ymax)) +static void store_icu_yrange_noop(Sequence *UNUSED(seq), + short UNUSED(adrcode), + float *UNUSED(ymin), + float *UNUSED(ymax)) { - /* defaults are fine */ + /* defaults are fine */ } -static void get_default_fac_noop(Sequence *UNUSED(seq), float UNUSED(cfra), float *facf0, float *facf1) +static void get_default_fac_noop(Sequence *UNUSED(seq), + float UNUSED(cfra), + float *facf0, + float *facf1) { - *facf0 = *facf1 = 1.0; + *facf0 = *facf1 = 1.0; } static void get_default_fac_fade(Sequence *seq, float cfra, float *facf0, float *facf1) { - *facf0 = (float)(cfra - seq->startdisp); - *facf1 = (float)(*facf0 + 0.5f); - *facf0 /= seq->len; - *facf1 /= seq->len; + *facf0 = (float)(cfra - seq->startdisp); + *facf1 = (float)(*facf0 + 0.5f); + *facf0 /= seq->len; + *facf1 /= seq->len; } -static struct ImBuf *init_execution(const SeqRenderData *context, ImBuf *ibuf1, ImBuf *ibuf2, ImBuf *ibuf3) +static struct ImBuf *init_execution(const SeqRenderData *context, + ImBuf *ibuf1, + ImBuf *ibuf2, + ImBuf *ibuf3) { - ImBuf *out = prepare_effect_imbufs(context, ibuf1, ibuf2, ibuf3); + ImBuf *out = prepare_effect_imbufs(context, ibuf1, ibuf2, ibuf3); - return out; + return out; } static struct SeqEffectHandle get_sequence_effect_impl(int seq_type) { - struct SeqEffectHandle rval; - int sequence_type = seq_type; - - rval.multithreaded = false; - rval.supports_mask = false; - 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.store_icu_yrange = store_icu_yrange_noop; - rval.execute = NULL; - rval.init_execution = init_execution; - rval.execute_slice = NULL; - rval.copy = NULL; - - switch (sequence_type) { - case SEQ_TYPE_CROSS: - rval.multithreaded = true; - rval.execute_slice = do_cross_effect; - rval.early_out = early_out_fade; - rval.get_default_fac = get_default_fac_fade; - break; - case SEQ_TYPE_GAMCROSS: - rval.multithreaded = true; - rval.init = init_gammacross; - rval.load = load_gammacross; - rval.free = free_gammacross; - rval.early_out = early_out_fade; - rval.get_default_fac = get_default_fac_fade; - rval.init_execution = gammacross_init_execution; - rval.execute_slice = do_gammacross_effect; - break; - case SEQ_TYPE_ADD: - rval.multithreaded = true; - rval.execute_slice = do_add_effect; - rval.early_out = early_out_mul_input2; - break; - case SEQ_TYPE_SUB: - rval.multithreaded = true; - rval.execute_slice = do_sub_effect; - rval.early_out = early_out_mul_input2; - break; - case SEQ_TYPE_MUL: - rval.multithreaded = true; - rval.execute_slice = do_mul_effect; - rval.early_out = early_out_mul_input2; - break; - case SEQ_TYPE_SCREEN: - case SEQ_TYPE_OVERLAY: - case SEQ_TYPE_BURN: - case SEQ_TYPE_LINEAR_BURN: - case SEQ_TYPE_DARKEN: - case SEQ_TYPE_LIGHTEN: - case SEQ_TYPE_DODGE: - case SEQ_TYPE_SOFT_LIGHT: - case SEQ_TYPE_HARD_LIGHT: - case SEQ_TYPE_PIN_LIGHT: - case SEQ_TYPE_LIN_LIGHT: - case SEQ_TYPE_VIVID_LIGHT: - case SEQ_TYPE_BLEND_COLOR: - case SEQ_TYPE_HUE: - case SEQ_TYPE_SATURATION: - case SEQ_TYPE_VALUE: - case SEQ_TYPE_DIFFERENCE: - case SEQ_TYPE_EXCLUSION: - rval.multithreaded = true; - rval.execute_slice = do_blend_mode_effect; - rval.early_out = early_out_mul_input2; - break; - case SEQ_TYPE_COLORMIX: - rval.multithreaded = true; - rval.init = init_colormix_effect; - rval.free = free_effect_default; - rval.copy = copy_effect_default; - rval.execute_slice = do_colormix_effect; - rval.early_out = early_out_mul_input2; - break; - case SEQ_TYPE_ALPHAOVER: - rval.multithreaded = true; - rval.init = init_alpha_over_or_under; - rval.execute_slice = do_alphaover_effect; - break; - case SEQ_TYPE_OVERDROP: - rval.multithreaded = true; - rval.execute_slice = do_overdrop_effect; - break; - case SEQ_TYPE_ALPHAUNDER: - rval.multithreaded = true; - rval.init = init_alpha_over_or_under; - rval.execute_slice = do_alphaunder_effect; - break; - case SEQ_TYPE_WIPE: - rval.init = init_wipe_effect; - rval.num_inputs = num_inputs_wipe; - rval.free = free_wipe_effect; - rval.copy = copy_wipe_effect; - rval.early_out = early_out_fade; - rval.get_default_fac = get_default_fac_fade; - rval.execute = do_wipe_effect; - break; - case SEQ_TYPE_GLOW: - rval.init = init_glow_effect; - rval.num_inputs = num_inputs_glow; - rval.free = free_glow_effect; - rval.copy = copy_glow_effect; - rval.execute = do_glow_effect; - break; - case SEQ_TYPE_TRANSFORM: - rval.init = init_transform_effect; - rval.num_inputs = num_inputs_transform; - rval.free = free_transform_effect; - rval.copy = copy_transform_effect; - rval.execute = do_transform_effect; - break; - case SEQ_TYPE_SPEED: - rval.init = init_speed_effect; - rval.num_inputs = num_inputs_speed; - rval.load = load_speed_effect; - rval.free = free_speed_effect; - rval.copy = copy_speed_effect; - rval.execute = do_speed_effect; - rval.early_out = early_out_speed; - rval.store_icu_yrange = store_icu_yrange_speed; - break; - case SEQ_TYPE_COLOR: - rval.init = init_solid_color; - rval.num_inputs = num_inputs_color; - rval.early_out = early_out_color; - rval.free = free_solid_color; - rval.copy = copy_solid_color; - rval.execute = do_solid_color; - break; - case SEQ_TYPE_MULTICAM: - rval.num_inputs = num_inputs_multicam; - rval.early_out = early_out_multicam; - rval.execute = do_multicam; - break; - case SEQ_TYPE_ADJUSTMENT: - rval.supports_mask = true; - rval.num_inputs = num_inputs_adjustment; - rval.early_out = early_out_adjustment; - rval.execute = do_adjustment; - break; - case SEQ_TYPE_GAUSSIAN_BLUR: - rval.init = init_gaussian_blur_effect; - rval.num_inputs = num_inputs_gaussian_blur; - rval.free = free_gaussian_blur_effect; - rval.copy = copy_gaussian_blur_effect; - rval.early_out = early_out_gaussian_blur; - rval.execute = do_gaussian_blur_effect; - break; - case SEQ_TYPE_TEXT: - rval.num_inputs = num_inputs_text; - rval.init = init_text_effect; - rval.free = free_text_effect; - rval.load = load_text_effect; - rval.copy = copy_text_effect; - rval.early_out = early_out_text; - rval.execute = do_text_effect; - break; - } - - return rval; + struct SeqEffectHandle rval; + int sequence_type = seq_type; + + rval.multithreaded = false; + rval.supports_mask = false; + 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.store_icu_yrange = store_icu_yrange_noop; + rval.execute = NULL; + rval.init_execution = init_execution; + rval.execute_slice = NULL; + rval.copy = NULL; + + switch (sequence_type) { + case SEQ_TYPE_CROSS: + rval.multithreaded = true; + rval.execute_slice = do_cross_effect; + rval.early_out = early_out_fade; + rval.get_default_fac = get_default_fac_fade; + break; + case SEQ_TYPE_GAMCROSS: + rval.multithreaded = true; + rval.init = init_gammacross; + rval.load = load_gammacross; + rval.free = free_gammacross; + rval.early_out = early_out_fade; + rval.get_default_fac = get_default_fac_fade; + rval.init_execution = gammacross_init_execution; + rval.execute_slice = do_gammacross_effect; + break; + case SEQ_TYPE_ADD: + rval.multithreaded = true; + rval.execute_slice = do_add_effect; + rval.early_out = early_out_mul_input2; + break; + case SEQ_TYPE_SUB: + rval.multithreaded = true; + rval.execute_slice = do_sub_effect; + rval.early_out = early_out_mul_input2; + break; + case SEQ_TYPE_MUL: + rval.multithreaded = true; + rval.execute_slice = do_mul_effect; + rval.early_out = early_out_mul_input2; + break; + case SEQ_TYPE_SCREEN: + case SEQ_TYPE_OVERLAY: + case SEQ_TYPE_BURN: + case SEQ_TYPE_LINEAR_BURN: + case SEQ_TYPE_DARKEN: + case SEQ_TYPE_LIGHTEN: + case SEQ_TYPE_DODGE: + case SEQ_TYPE_SOFT_LIGHT: + case SEQ_TYPE_HARD_LIGHT: + case SEQ_TYPE_PIN_LIGHT: + case SEQ_TYPE_LIN_LIGHT: + case SEQ_TYPE_VIVID_LIGHT: + case SEQ_TYPE_BLEND_COLOR: + case SEQ_TYPE_HUE: + case SEQ_TYPE_SATURATION: + case SEQ_TYPE_VALUE: + case SEQ_TYPE_DIFFERENCE: + case SEQ_TYPE_EXCLUSION: + rval.multithreaded = true; + rval.execute_slice = do_blend_mode_effect; + rval.early_out = early_out_mul_input2; + break; + case SEQ_TYPE_COLORMIX: + rval.multithreaded = true; + rval.init = init_colormix_effect; + rval.free = free_effect_default; + rval.copy = copy_effect_default; + rval.execute_slice = do_colormix_effect; + rval.early_out = early_out_mul_input2; + break; + case SEQ_TYPE_ALPHAOVER: + rval.multithreaded = true; + rval.init = init_alpha_over_or_under; + rval.execute_slice = do_alphaover_effect; + break; + case SEQ_TYPE_OVERDROP: + rval.multithreaded = true; + rval.execute_slice = do_overdrop_effect; + break; + case SEQ_TYPE_ALPHAUNDER: + rval.multithreaded = true; + rval.init = init_alpha_over_or_under; + rval.execute_slice = do_alphaunder_effect; + break; + case SEQ_TYPE_WIPE: + rval.init = init_wipe_effect; + rval.num_inputs = num_inputs_wipe; + rval.free = free_wipe_effect; + rval.copy = copy_wipe_effect; + rval.early_out = early_out_fade; + rval.get_default_fac = get_default_fac_fade; + rval.execute = do_wipe_effect; + break; + case SEQ_TYPE_GLOW: + rval.init = init_glow_effect; + rval.num_inputs = num_inputs_glow; + rval.free = free_glow_effect; + rval.copy = copy_glow_effect; + rval.execute = do_glow_effect; + break; + case SEQ_TYPE_TRANSFORM: + rval.init = init_transform_effect; + rval.num_inputs = num_inputs_transform; + rval.free = free_transform_effect; + rval.copy = copy_transform_effect; + rval.execute = do_transform_effect; + break; + case SEQ_TYPE_SPEED: + rval.init = init_speed_effect; + rval.num_inputs = num_inputs_speed; + rval.load = load_speed_effect; + rval.free = free_speed_effect; + rval.copy = copy_speed_effect; + rval.execute = do_speed_effect; + rval.early_out = early_out_speed; + rval.store_icu_yrange = store_icu_yrange_speed; + break; + case SEQ_TYPE_COLOR: + rval.init = init_solid_color; + rval.num_inputs = num_inputs_color; + rval.early_out = early_out_color; + rval.free = free_solid_color; + rval.copy = copy_solid_color; + rval.execute = do_solid_color; + break; + case SEQ_TYPE_MULTICAM: + rval.num_inputs = num_inputs_multicam; + rval.early_out = early_out_multicam; + rval.execute = do_multicam; + break; + case SEQ_TYPE_ADJUSTMENT: + rval.supports_mask = true; + rval.num_inputs = num_inputs_adjustment; + rval.early_out = early_out_adjustment; + rval.execute = do_adjustment; + break; + case SEQ_TYPE_GAUSSIAN_BLUR: + rval.init = init_gaussian_blur_effect; + rval.num_inputs = num_inputs_gaussian_blur; + rval.free = free_gaussian_blur_effect; + rval.copy = copy_gaussian_blur_effect; + rval.early_out = early_out_gaussian_blur; + rval.execute = do_gaussian_blur_effect; + break; + case SEQ_TYPE_TEXT: + rval.num_inputs = num_inputs_text; + rval.init = init_text_effect; + rval.free = free_text_effect; + rval.load = load_text_effect; + rval.copy = copy_text_effect; + rval.early_out = early_out_text; + rval.execute = do_text_effect; + break; + } + + return rval; } struct SeqEffectHandle BKE_sequence_get_effect(Sequence *seq) { - struct SeqEffectHandle rval = {false, false, NULL}; + struct SeqEffectHandle rval = {false, false, NULL}; - if (seq->type & SEQ_TYPE_EFFECT) { - rval = get_sequence_effect_impl(seq->type); - if ((seq->flag & SEQ_EFFECT_NOT_LOADED) != 0) { - rval.load(seq); - seq->flag &= ~SEQ_EFFECT_NOT_LOADED; - } - } + if (seq->type & SEQ_TYPE_EFFECT) { + rval = get_sequence_effect_impl(seq->type); + if ((seq->flag & SEQ_EFFECT_NOT_LOADED) != 0) { + rval.load(seq); + seq->flag &= ~SEQ_EFFECT_NOT_LOADED; + } + } - return rval; + return rval; } struct SeqEffectHandle BKE_sequence_get_blend(Sequence *seq) { - struct SeqEffectHandle rval = {false, false, NULL}; + struct SeqEffectHandle rval = {false, false, NULL}; - if (seq->blend_mode != 0) { - if ((seq->flag & SEQ_EFFECT_NOT_LOADED) != 0) { - /* load the effect first */ - rval = get_sequence_effect_impl(seq->type); - rval.load(seq); - } + if (seq->blend_mode != 0) { + if ((seq->flag & SEQ_EFFECT_NOT_LOADED) != 0) { + /* load the effect first */ + rval = get_sequence_effect_impl(seq->type); + rval.load(seq); + } - rval = get_sequence_effect_impl(seq->blend_mode); - if ((seq->flag & SEQ_EFFECT_NOT_LOADED) != 0) { - /* now load the blend and unset unloaded flag */ - rval.load(seq); - seq->flag &= ~SEQ_EFFECT_NOT_LOADED; - } - } + rval = get_sequence_effect_impl(seq->blend_mode); + if ((seq->flag & SEQ_EFFECT_NOT_LOADED) != 0) { + /* now load the blend and unset unloaded flag */ + rval.load(seq); + seq->flag &= ~SEQ_EFFECT_NOT_LOADED; + } + } - return rval; + return rval; } int BKE_sequence_effect_get_num_inputs(int seq_type) { - struct SeqEffectHandle rval = get_sequence_effect_impl(seq_type); + struct SeqEffectHandle rval = get_sequence_effect_impl(seq_type); - int cnt = rval.num_inputs(); - if (rval.execute || (rval.execute_slice && rval.init_execution)) { - return cnt; - } - return 0; + int cnt = rval.num_inputs(); + if (rval.execute || (rval.execute_slice && rval.init_execution)) { + return cnt; + } + return 0; } int BKE_sequence_effect_get_supports_mask(int seq_type) { - struct SeqEffectHandle rval = get_sequence_effect_impl(seq_type); + struct SeqEffectHandle rval = get_sequence_effect_impl(seq_type); - return rval.supports_mask; + return rval.supports_mask; } |