2 * ***** BEGIN GPL LICENSE BLOCK *****
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software Foundation,
16 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
19 * All rights reserved.
22 * - Blender Foundation, 2003-2009
23 * - Peter Schlaile <peter [at] schlaile [dot] de> 2005/2006
25 * ***** END GPL LICENSE BLOCK *****
28 /** \file blender/blenkernel/intern/seqeffects.c
37 #include "MEM_guardedalloc.h"
38 #include "BLI_dynlib.h"
40 #include "BLI_math.h" /* windows needs for M_PI */
41 #include "BLI_utildefines.h"
42 #include "BLI_string.h"
44 #include "DNA_scene_types.h"
45 #include "DNA_sequence_types.h"
46 #include "DNA_anim_types.h"
48 #include "BKE_fcurve.h"
50 #include "BKE_sequencer.h"
51 #include "BKE_texture.h"
52 #include "BKE_utildefines.h"
54 #include "IMB_imbuf_types.h"
55 #include "IMB_imbuf.h"
57 #include "RNA_access.h"
59 static void slize_get_byte_buffers(const SeqRenderData *context, const ImBuf *ibuf1, const ImBuf *ibuf2,
60 const ImBuf *ibuf3, const ImBuf *out, int start_line, unsigned char **rect1,
61 unsigned char **rect2, unsigned char **rect3, unsigned char **rect_out)
63 int offset = 4 * start_line * context->rectx;
65 *rect1 = (unsigned char*) ibuf1->rect + offset;
66 *rect_out = (unsigned char*) out->rect + offset;
69 *rect2 = (unsigned char*) ibuf2->rect + offset;
72 *rect3 = (unsigned char*) ibuf3->rect + offset;
75 static void slize_get_float_buffers(const SeqRenderData *context, const ImBuf *ibuf1, const ImBuf *ibuf2,
76 const ImBuf *ibuf3, const ImBuf *out, int start_line,
77 float **rect1, float **rect2, float **rect3, float **rect_out)
79 int offset = 4 * start_line * context->rectx;
81 *rect1 = ibuf1->rect_float + offset;
82 *rect_out = out->rect_float + offset;
85 *rect2 = ibuf2->rect_float + offset;
88 *rect3 = ibuf3->rect_float + offset;
91 /*********************** Glow effect *************************/
100 static ImBuf *prepare_effect_imbufs(SeqRenderData context, ImBuf *ibuf1, ImBuf *ibuf2, ImBuf *ibuf3)
103 int x = context.rectx;
104 int y = context.recty;
106 if (!ibuf1 && !ibuf2 && !ibuf3) {
107 /* hmmm, global float option ? */
108 out = IMB_allocImBuf(x, y, 32, IB_rect);
110 else if ((ibuf1 && ibuf1->rect_float) ||
111 (ibuf2 && ibuf2->rect_float) ||
112 (ibuf3 && ibuf3->rect_float))
114 /* if any inputs are rectfloat, output is float too */
116 out = IMB_allocImBuf(x, y, 32, IB_rectfloat);
119 out = IMB_allocImBuf(x, y, 32, IB_rect);
122 if (ibuf1 && !ibuf1->rect_float && out->rect_float) {
123 IMB_float_from_rect_simple(ibuf1);
125 if (ibuf2 && !ibuf2->rect_float && out->rect_float) {
126 IMB_float_from_rect_simple(ibuf2);
128 if (ibuf3 && !ibuf3->rect_float && out->rect_float) {
129 IMB_float_from_rect_simple(ibuf3);
132 if (ibuf1 && !ibuf1->rect && !out->rect_float) {
133 IMB_rect_from_float(ibuf1);
135 if (ibuf2 && !ibuf2->rect && !out->rect_float) {
136 IMB_rect_from_float(ibuf2);
138 if (ibuf3 && !ibuf3->rect && !out->rect_float) {
139 IMB_rect_from_float(ibuf3);
145 /*********************** Alpha Over *************************/
147 static void init_alpha_over_or_under(Sequence *seq)
149 Sequence *seq1 = seq->seq1;
150 Sequence *seq2 = seq->seq2;
156 static void do_alphaover_effect_byte(float facf0, float facf1, int x, int y, char *rect1, char *rect2, char *out)
158 int fac2, mfac, fac, fac4;
160 char *rt1, *rt2, *rt;
163 rt1 = (char *) rect1;
164 rt2 = (char *) rect2;
167 fac2 = (int) (256.0f * facf0);
168 fac4 = (int) (256.0f * facf1);
174 /* rt = rt1 over rt2 (alpha from rt1) */
177 mfac = 256 - ( (fac2 * rt1[3]) >> 8);
179 if (fac == 0) *( (unsigned int *) rt) = *( (unsigned int *) rt2);
180 else if (mfac == 0) *( (unsigned int *) rt) = *( (unsigned int *) rt1);
182 tempc = (fac * rt1[0] + mfac * rt2[0]) >> 8;
183 if (tempc > 255) rt[0] = 255; else rt[0] = tempc;
184 tempc = (fac * rt1[1] + mfac * rt2[1]) >> 8;
185 if (tempc > 255) rt[1] = 255; else rt[1] = tempc;
186 tempc = (fac * rt1[2] + mfac * rt2[2]) >> 8;
187 if (tempc > 255) rt[2] = 255; else rt[2] = tempc;
188 tempc = (fac * rt1[3] + mfac * rt2[3]) >> 8;
189 if (tempc > 255) rt[3] = 255; else rt[3] = tempc;
191 rt1 += 4; rt2 += 4; rt += 4;
200 mfac = 256 - ( (fac4 * rt1[3]) >> 8);
202 if (fac == 0) *( (unsigned int *) rt) = *( (unsigned int *) rt2);
203 else if (mfac == 0) *( (unsigned int *) rt) = *( (unsigned int *) rt1);
205 tempc = (fac * rt1[0] + mfac * rt2[0]) >> 8;
206 if (tempc > 255) rt[0] = 255; else rt[0] = tempc;
207 tempc = (fac * rt1[1] + mfac * rt2[1]) >> 8;
208 if (tempc > 255) rt[1] = 255; else rt[1] = tempc;
209 tempc = (fac * rt1[2] + mfac * rt2[2]) >> 8;
210 if (tempc > 255) rt[2] = 255; else rt[2] = tempc;
211 tempc = (fac * rt1[3] + mfac * rt2[3]) >> 8;
212 if (tempc > 255) rt[3] = 255; else rt[3] = tempc;
214 rt1 += 4; rt2 += 4; rt += 4;
219 static void do_alphaover_effect_float(float facf0, float facf1, int x, int y, float *rect1, float *rect2, float *out)
221 float fac2, mfac, fac, fac4;
223 float *rt1, *rt2, *rt;
236 /* rt = rt1 over rt2 (alpha from rt1) */
239 mfac = 1.0f - (fac2 * rt1[3]);
242 memcpy(rt, rt2, 4 * sizeof(float));
244 else if (mfac <= 0) {
245 memcpy(rt, rt1, 4 * sizeof(float));
248 rt[0] = fac * rt1[0] + mfac * rt2[0];
249 rt[1] = fac * rt1[1] + mfac * rt2[1];
250 rt[2] = fac * rt1[2] + mfac * rt2[2];
251 rt[3] = fac * rt1[3] + mfac * rt2[3];
253 rt1 += 4; rt2 += 4; rt += 4;
263 mfac = 1.0f - (fac4 * rt1[3]);
266 memcpy(rt, rt2, 4 * sizeof(float));
268 else if (mfac <= 0.0f) {
269 memcpy(rt, rt1, 4 * sizeof(float));
272 rt[0] = fac * rt1[0] + mfac * rt2[0];
273 rt[1] = fac * rt1[1] + mfac * rt2[1];
274 rt[2] = fac * rt1[2] + mfac * rt2[2];
275 rt[3] = fac * rt1[3] + mfac * rt2[3];
277 rt1 += 4; rt2 += 4; rt += 4;
282 static void do_alphaover_effect(SeqRenderData context, Sequence *UNUSED(seq), float UNUSED(cfra), float facf0,
283 float facf1, ImBuf *ibuf1, ImBuf *ibuf2, ImBuf *UNUSED(ibuf3),
284 int start_line, int total_lines, ImBuf *out)
286 if (out->rect_float) {
287 float *rect1, *rect2, *rect_out;
289 slize_get_float_buffers(&context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
291 do_alphaover_effect_float(facf0, facf1, context.rectx, total_lines, rect1, rect2, rect_out);
294 unsigned char *rect1, *rect2, *rect_out;
296 slize_get_byte_buffers(&context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
298 do_alphaover_effect_byte(facf0, facf1, context.rectx, total_lines, (char *) rect1, (char *) rect2, (char *) rect_out);
302 /*********************** Alpha Under *************************/
304 static void do_alphaunder_effect_byte(float facf0, float facf1, int x, int y, char *rect1, char *rect2, char *out)
306 int fac2, mfac, fac, fac4;
308 char *rt1, *rt2, *rt;
315 fac2 = (int)(256.0f * facf0);
316 fac4 = (int)(256.0f * facf1);
321 /* rt = rt1 under rt2 (alpha from rt2) */
323 /* this complex optimization is because the
324 * 'skybuf' can be crossed in
326 if (rt2[3] == 0 && fac2 == 256) *( (unsigned int *) rt) = *( (unsigned int *) rt1);
327 else if (rt2[3] == 255) *( (unsigned int *) rt) = *( (unsigned int *) rt2);
330 fac = (fac2 * (256 - mfac)) >> 8;
332 if (fac == 0) *( (unsigned int *) rt) = *( (unsigned int *) rt2);
334 rt[0] = (fac * rt1[0] + mfac * rt2[0]) >> 8;
335 rt[1] = (fac * rt1[1] + mfac * rt2[1]) >> 8;
336 rt[2] = (fac * rt1[2] + mfac * rt2[2]) >> 8;
337 rt[3] = (fac * rt1[3] + mfac * rt2[3]) >> 8;
340 rt1 += 4; rt2 += 4; rt += 4;
349 if (rt2[3] == 0 && fac4 == 256) *( (unsigned int *) rt) = *( (unsigned int *) rt1);
350 else if (rt2[3] == 255) *( (unsigned int *) rt) = *( (unsigned int *) rt2);
353 fac = (fac4 * (256 - mfac)) >> 8;
355 if (fac == 0) *( (unsigned int *)rt) = *( (unsigned int *)rt2);
357 rt[0] = (fac * rt1[0] + mfac * rt2[0]) >> 8;
358 rt[1] = (fac * rt1[1] + mfac * rt2[1]) >> 8;
359 rt[2] = (fac * rt1[2] + mfac * rt2[2]) >> 8;
360 rt[3] = (fac * rt1[3] + mfac * rt2[3]) >> 8;
363 rt1 += 4; rt2 += 4; rt += 4;
368 static void do_alphaunder_effect_float(float facf0, float facf1, int x, int y, float *rect1, float *rect2, float *out)
370 float fac2, mfac, fac, fac4;
372 float *rt1, *rt2, *rt;
385 /* rt = rt1 under rt2 (alpha from rt2) */
387 /* this complex optimization is because the
388 * 'skybuf' can be crossed in
390 if (rt2[3] <= 0 && fac2 >= 1.0f) {
391 memcpy(rt, rt1, 4 * sizeof(float));
393 else if (rt2[3] >= 1.0f) {
394 memcpy(rt, rt2, 4 * sizeof(float));
398 fac = fac2 * (1.0f - mfac);
401 memcpy(rt, rt2, 4 * sizeof(float));
404 rt[0] = fac * rt1[0] + mfac * rt2[0];
405 rt[1] = fac * rt1[1] + mfac * rt2[1];
406 rt[2] = fac * rt1[2] + mfac * rt2[2];
407 rt[3] = fac * rt1[3] + mfac * rt2[3];
410 rt1 += 4; rt2 += 4; rt += 4;
419 if (rt2[3] <= 0 && fac4 >= 1.0f) {
420 memcpy(rt, rt1, 4 * sizeof(float));
422 else if (rt2[3] >= 1.0f) {
423 memcpy(rt, rt2, 4 * sizeof(float));
427 fac = fac4 * (1.0f - mfac);
430 memcpy(rt, rt2, 4 * sizeof(float));
433 rt[0] = fac * rt1[0] + mfac * rt2[0];
434 rt[1] = fac * rt1[1] + mfac * rt2[1];
435 rt[2] = fac * rt1[2] + mfac * rt2[2];
436 rt[3] = fac * rt1[3] + mfac * rt2[3];
439 rt1 += 4; rt2 += 4; rt += 4;
444 static void do_alphaunder_effect(SeqRenderData context, Sequence *UNUSED(seq), float UNUSED(cfra),
445 float facf0, float facf1, ImBuf *ibuf1, ImBuf *ibuf2, ImBuf *UNUSED(ibuf3),
446 int start_line, int total_lines, ImBuf *out)
448 if (out->rect_float) {
449 float *rect1, *rect2, *rect_out;
451 slize_get_float_buffers(&context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
453 do_alphaunder_effect_float(facf0, facf1, context.rectx, total_lines, rect1, rect2, rect_out);
456 unsigned char *rect1, *rect2, *rect_out;
458 slize_get_byte_buffers(&context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
460 do_alphaunder_effect_byte(facf0, facf1, context.rectx, total_lines, (char *) rect1, (char *) rect2, (char *) rect_out);
464 /*********************** Cross *************************/
466 static void do_cross_effect_byte(float facf0, float facf1, int x, int y, char *rect1, char *rect2, char *out)
468 int fac1, fac2, fac3, fac4;
470 char *rt1, *rt2, *rt;
477 fac2 = (int) (256.0f * facf0);
479 fac4 = (int) (256.0f * facf1);
485 rt[0] = (fac1 * rt1[0] + fac2 * rt2[0]) >> 8;
486 rt[1] = (fac1 * rt1[1] + fac2 * rt2[1]) >> 8;
487 rt[2] = (fac1 * rt1[2] + fac2 * rt2[2]) >> 8;
488 rt[3] = (fac1 * rt1[3] + fac2 * rt2[3]) >> 8;
490 rt1 += 4; rt2 += 4; rt += 4;
499 rt[0] = (fac3 * rt1[0] + fac4 * rt2[0]) >> 8;
500 rt[1] = (fac3 * rt1[1] + fac4 * rt2[1]) >> 8;
501 rt[2] = (fac3 * rt1[2] + fac4 * rt2[2]) >> 8;
502 rt[3] = (fac3 * rt1[3] + fac4 * rt2[3]) >> 8;
504 rt1 += 4; rt2 += 4; rt += 4;
510 static void do_cross_effect_float(float facf0, float facf1, int x, int y, float *rect1, float *rect2, float *out)
512 float fac1, fac2, fac3, fac4;
514 float *rt1, *rt2, *rt;
529 rt[0] = fac1 * rt1[0] + fac2 * rt2[0];
530 rt[1] = fac1 * rt1[1] + fac2 * rt2[1];
531 rt[2] = fac1 * rt1[2] + fac2 * rt2[2];
532 rt[3] = fac1 * rt1[3] + fac2 * rt2[3];
534 rt1 += 4; rt2 += 4; rt += 4;
543 rt[0] = fac3 * rt1[0] + fac4 * rt2[0];
544 rt[1] = fac3 * rt1[1] + fac4 * rt2[1];
545 rt[2] = fac3 * rt1[2] + fac4 * rt2[2];
546 rt[3] = fac3 * rt1[3] + fac4 * rt2[3];
548 rt1 += 4; rt2 += 4; rt += 4;
554 static void do_cross_effect(SeqRenderData context, Sequence *UNUSED(seq), float UNUSED(cfra),
555 float facf0, float facf1, ImBuf *ibuf1, ImBuf *ibuf2, ImBuf *UNUSED(ibuf3),
556 int start_line, int total_lines, ImBuf *out)
558 if (out->rect_float) {
559 float *rect1, *rect2, *rect_out;
561 slize_get_float_buffers(&context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
563 do_cross_effect_float(facf0, facf1, context.rectx, total_lines, rect1, rect2, rect_out);
566 unsigned char *rect1, *rect2, *rect_out;
568 slize_get_byte_buffers(&context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
570 do_cross_effect_byte(facf0, facf1, context.rectx, total_lines, (char *) rect1, (char *) rect2, (char *) rect_out);
574 /*********************** Gamma Cross *************************/
576 /* copied code from initrender.c */
577 static unsigned short gamtab[65536];
578 static unsigned short igamtab1[256];
579 static int gamma_tabs_init = FALSE;
581 #define RE_GAMMA_TABLE_SIZE 400
583 static float gamma_range_table[RE_GAMMA_TABLE_SIZE + 1];
584 static float gamfactor_table[RE_GAMMA_TABLE_SIZE];
585 static float inv_gamma_range_table[RE_GAMMA_TABLE_SIZE + 1];
586 static float inv_gamfactor_table[RE_GAMMA_TABLE_SIZE];
587 static float color_domain_table[RE_GAMMA_TABLE_SIZE + 1];
588 static float color_step;
589 static float inv_color_step;
590 static float valid_gamma;
591 static float valid_inv_gamma;
593 static void makeGammaTables(float gamma)
595 /* we need two tables: one forward, one backward */
599 valid_inv_gamma = 1.0f / gamma;
600 color_step = 1.0f / RE_GAMMA_TABLE_SIZE;
601 inv_color_step = (float) RE_GAMMA_TABLE_SIZE;
603 /* We could squeeze out the two range tables to gain some memory */
604 for (i = 0; i < RE_GAMMA_TABLE_SIZE; i++) {
605 color_domain_table[i] = i * color_step;
606 gamma_range_table[i] = pow(color_domain_table[i], valid_gamma);
607 inv_gamma_range_table[i] = pow(color_domain_table[i], valid_inv_gamma);
610 /* The end of the table should match 1.0 carefully. In order to avoid
611 * rounding errors, we just set this explicitly. The last segment may
612 * have a different length than the other segments, but our
613 * interpolation is insensitive to that
615 color_domain_table[RE_GAMMA_TABLE_SIZE] = 1.0;
616 gamma_range_table[RE_GAMMA_TABLE_SIZE] = 1.0;
617 inv_gamma_range_table[RE_GAMMA_TABLE_SIZE] = 1.0;
619 /* To speed up calculations, we make these calc factor tables. They are
620 * multiplication factors used in scaling the interpolation
622 for (i = 0; i < RE_GAMMA_TABLE_SIZE; i++) {
623 gamfactor_table[i] = inv_color_step * (gamma_range_table[i + 1] - gamma_range_table[i]);
624 inv_gamfactor_table[i] = inv_color_step * (inv_gamma_range_table[i + 1] - inv_gamma_range_table[i]);
629 static float gammaCorrect(float c)
634 i = floor(c * inv_color_step);
635 /* Clip to range [0, 1]: outside, just do the complete calculation.
636 * We may have some performance problems here. Stretching up the LUT
637 * may help solve that, by exchanging LUT size for the interpolation.
638 * Negative colors are explicitly handled.
640 if (i < 0) res = -pow(abs(c), valid_gamma);
641 else if (i >= RE_GAMMA_TABLE_SIZE) res = pow(c, valid_gamma);
642 else res = gamma_range_table[i] + ( (c - color_domain_table[i]) * gamfactor_table[i]);
647 /* ------------------------------------------------------------------------- */
649 static float invGammaCorrect(float col)
654 i = floor(col * inv_color_step);
655 /* Negative colors are explicitly handled */
656 if (i < 0) res = -pow(abs(col), valid_inv_gamma);
657 else if (i >= RE_GAMMA_TABLE_SIZE) res = pow(col, valid_inv_gamma);
658 else res = inv_gamma_range_table[i] + ( (col - color_domain_table[i]) * inv_gamfactor_table[i]);
663 static void gamtabs(float gamma)
665 float val, igamma = 1.0f / gamma;
668 /* gamtab: in short, out short */
669 for (a = 0; a < 65536; a++) {
673 if (gamma == 2.0f) val = sqrt(val);
674 else if (gamma != 1.0f) val = pow(val, igamma);
676 gamtab[a] = (65535.99f * val);
678 /* inverse gamtab1 : in byte, out short */
679 for (a = 1; a <= 256; a++) {
680 if (gamma == 2.0f) igamtab1[a - 1] = a * a - 1;
681 else if (gamma == 1.0f) igamtab1[a - 1] = 256 * a - 1;
684 igamtab1[a - 1] = (65535.0 * pow(val, gamma)) - 1;
689 static void build_gammatabs(void)
691 if (gamma_tabs_init == FALSE) {
693 makeGammaTables(2.0f);
694 gamma_tabs_init = TRUE;
698 static void init_gammacross(Sequence *UNUSED(seq))
702 static void load_gammacross(Sequence *UNUSED(seq))
706 static void free_gammacross(Sequence *UNUSED(seq))
710 static void do_gammacross_effect_byte(float facf0, float UNUSED(facf1), int x, int y, unsigned char *rect1,
711 unsigned char *rect2, unsigned char *out)
715 unsigned char *rt1, *rt2, *rt;
718 rt1 = (unsigned char *) rect1;
719 rt2 = (unsigned char *) rect2;
720 rt = (unsigned char *) out;
722 fac2 = (int)(256.0f * facf0);
728 col = (fac1 * igamtab1[rt1[0]] + fac2 * igamtab1[rt2[0]]) >> 8;
729 if (col > 65535) rt[0] = 255; else rt[0] = ( (char *)(gamtab + col))[MOST_SIG_BYTE];
730 col = (fac1 * igamtab1[rt1[1]] + fac2 * igamtab1[rt2[1]]) >> 8;
731 if (col > 65535) rt[1] = 255; else rt[1] = ( (char *)(gamtab + col))[MOST_SIG_BYTE];
732 col = (fac1 * igamtab1[rt1[2]] + fac2 * igamtab1[rt2[2]]) >> 8;
733 if (col > 65535) rt[2] = 255; else rt[2] = ( (char *)(gamtab + col))[MOST_SIG_BYTE];
734 col = (fac1 * igamtab1[rt1[3]] + fac2 * igamtab1[rt2[3]]) >> 8;
735 if (col > 65535) rt[3] = 255; else rt[3] = ( (char *)(gamtab + col))[MOST_SIG_BYTE];
737 rt1 += 4; rt2 += 4; rt += 4;
746 col = (fac1 * igamtab1[rt1[0]] + fac2 * igamtab1[rt2[0]]) >> 8;
747 if (col > 65535) rt[0] = 255; else rt[0] = ( (char *)(gamtab + col))[MOST_SIG_BYTE];
748 col = (fac1 * igamtab1[rt1[1]] + fac2 * igamtab1[rt2[1]]) >> 8;
749 if (col > 65535) rt[1] = 255; else rt[1] = ( (char *)(gamtab + col))[MOST_SIG_BYTE];
750 col = (fac1 * igamtab1[rt1[2]] + fac2 * igamtab1[rt2[2]]) >> 8;
751 if (col > 65535) rt[2] = 255; else rt[2] = ( (char *)(gamtab + col))[MOST_SIG_BYTE];
752 col = (fac1 * igamtab1[rt1[3]] + fac2 * igamtab1[rt2[3]]) >> 8;
753 if (col > 65535) rt[3] = 255; else rt[3] = ( (char *)(gamtab + col))[MOST_SIG_BYTE];
755 rt1 += 4; rt2 += 4; rt += 4;
760 static void do_gammacross_effect_float(float facf0, float UNUSED(facf1), int x, int y, float *rect1,
761 float *rect2, float *out)
765 float *rt1, *rt2, *rt;
778 *rt = gammaCorrect(fac1 * invGammaCorrect(*rt1) + fac2 * invGammaCorrect(*rt2));
788 *rt = gammaCorrect(fac1 * invGammaCorrect(*rt1) + fac2 * invGammaCorrect(*rt2));
795 static struct ImBuf *gammacross_init_execution(SeqRenderData context, ImBuf *ibuf1, ImBuf *ibuf2, ImBuf *ibuf3)
797 ImBuf *out = prepare_effect_imbufs(context, ibuf1, ibuf2, ibuf3);
803 static void do_gammacross_effect(SeqRenderData context, Sequence *UNUSED(seq), float UNUSED(cfra),
804 float facf0, float facf1, ImBuf *ibuf1, ImBuf *ibuf2, ImBuf *UNUSED(ibuf3),
805 int start_line, int total_lines, ImBuf *out)
807 if (out->rect_float) {
808 float *rect1, *rect2, *rect_out;
810 slize_get_float_buffers(&context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
812 do_gammacross_effect_float(facf0, facf1, context.rectx, total_lines, rect1, rect2, rect_out);
815 unsigned char *rect1, *rect2, *rect_out;
817 slize_get_byte_buffers(&context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
819 do_gammacross_effect_byte(facf0, facf1, context.rectx, total_lines, rect1, rect2, rect_out);
823 /*********************** Add *************************/
825 static void do_add_effect_byte(float facf0, float facf1, int x, int y, unsigned char *rect1, unsigned char *rect2,
828 int col, xo, fac1, fac3;
829 char *rt1, *rt2, *rt;
836 fac1 = (int)(256.0f * facf0);
837 fac3 = (int)(256.0f * facf1);
843 col = rt1[0] + ((fac1 * rt2[0]) >> 8);
844 if (col > 255) rt[0] = 255; else rt[0] = col;
845 col = rt1[1] + ((fac1 * rt2[1]) >> 8);
846 if (col > 255) rt[1] = 255; else rt[1] = col;
847 col = rt1[2] + ((fac1 * rt2[2]) >> 8);
848 if (col > 255) rt[2] = 255; else rt[2] = col;
849 col = rt1[3] + ((fac1 * rt2[3]) >> 8);
850 if (col > 255) rt[3] = 255; else rt[3] = col;
852 rt1 += 4; rt2 += 4; rt += 4;
861 col = rt1[0] + ((fac3 * rt2[0]) >> 8);
862 if (col > 255) rt[0] = 255; else rt[0] = col;
863 col = rt1[1] + ((fac3 * rt2[1]) >> 8);
864 if (col > 255) rt[1] = 255; else rt[1] = col;
865 col = rt1[2] + ((fac3 * rt2[2]) >> 8);
866 if (col > 255) rt[2] = 255; else rt[2] = col;
867 col = rt1[3] + ((fac3 * rt2[3]) >> 8);
868 if (col > 255) rt[3] = 255; else rt[3] = col;
870 rt1 += 4; rt2 += 4; rt += 4;
875 static void do_add_effect_float(float facf0, float facf1, int x, int y, float *rect1, float *rect2, float *out)
879 float *rt1, *rt2, *rt;
892 *rt = *rt1 + fac1 * (*rt2);
903 *rt = *rt1 + fac3 * (*rt2);
910 static void do_add_effect(SeqRenderData context, Sequence *UNUSED(seq), float UNUSED(cfra), float facf0, float facf1,
911 ImBuf *ibuf1, ImBuf *ibuf2, ImBuf *UNUSED(ibuf3), int start_line, int total_lines, ImBuf *out)
913 if (out->rect_float) {
914 float *rect1, *rect2, *rect_out;
916 slize_get_float_buffers(&context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
918 do_add_effect_float(facf0, facf1, context.rectx, total_lines, rect1, rect2, rect_out);
921 unsigned char *rect1, *rect2, *rect_out;
923 slize_get_byte_buffers(&context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
925 do_add_effect_byte(facf0, facf1, context.rectx, total_lines, rect1, rect2, rect_out);
929 /*********************** Sub *************************/
931 static void do_sub_effect_byte(float facf0, float facf1, int x, int y, char *rect1, char *rect2, char *out)
933 int col, xo, fac1, fac3;
934 char *rt1, *rt2, *rt;
937 rt1 = (char *) rect1;
938 rt2 = (char *) rect2;
941 fac1 = (int) (256.0f * facf0);
942 fac3 = (int) (256.0f * facf1);
947 col = rt1[0] - ((fac1 * rt2[0]) >> 8);
948 if (col < 0) rt[0] = 0; else rt[0] = col;
949 col = rt1[1] - ((fac1 * rt2[1]) >> 8);
950 if (col < 0) rt[1] = 0; else rt[1] = col;
951 col = rt1[2] - ((fac1 * rt2[2]) >> 8);
952 if (col < 0) rt[2] = 0; else rt[2] = col;
953 col = rt1[3] - ((fac1 * rt2[3]) >> 8);
954 if (col < 0) rt[3] = 0; else rt[3] = col;
956 rt1 += 4; rt2 += 4; rt += 4;
965 col = rt1[0] - ((fac3 * rt2[0]) >> 8);
966 if (col < 0) rt[0] = 0; else rt[0] = col;
967 col = rt1[1] - ((fac3 * rt2[1]) >> 8);
968 if (col < 0) rt[1] = 0; else rt[1] = col;
969 col = rt1[2] - ((fac3 * rt2[2]) >> 8);
970 if (col < 0) rt[2] = 0; else rt[2] = col;
971 col = rt1[3] - ((fac3 * rt2[3]) >> 8);
972 if (col < 0) rt[3] = 0; else rt[3] = col;
974 rt1 += 4; rt2 += 4; rt += 4;
979 static void do_sub_effect_float(float facf0, float facf1, int x, int y, float *rect1, float *rect2, float *out)
983 float *rt1, *rt2, *rt;
996 *rt = *rt1 - fac1 * (*rt2);
1007 *rt = *rt1 - fac3 * (*rt2);
1014 static void do_sub_effect(SeqRenderData context, Sequence *UNUSED(seq), float UNUSED(cfra), float facf0, float facf1,
1015 ImBuf *ibuf1, ImBuf *ibuf2, ImBuf *UNUSED(ibuf3), int start_line, int total_lines, ImBuf *out)
1017 if (out->rect_float) {
1018 float *rect1, *rect2, *rect_out;
1020 slize_get_float_buffers(&context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
1022 do_sub_effect_float(facf0, facf1, context.rectx, total_lines, rect1, rect2, rect_out);
1025 unsigned char *rect1, *rect2, *rect_out;
1027 slize_get_byte_buffers(&context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
1029 do_sub_effect_byte(facf0, facf1, context.rectx, total_lines, (char *) rect1, (char *) rect2, (char *) rect_out);
1033 /*********************** Drop *************************/
1035 /* Must be > 0 or add precopy, etc to the function */
1039 static void do_drop_effect_byte(float facf0, float facf1, int x, int y, char *rect2i, char *rect1i, char *outi)
1041 int height, width, temp, fac, fac1, fac2;
1042 char *rt1, *rt2, *out;
1048 fac1 = (int) (70.0f * facf0);
1049 fac2 = (int) (70.0f * facf1);
1051 rt2 = (char *) (rect2i + YOFF * width);
1052 rt1 = (char *) rect1i;
1053 out = (char *) outi;
1054 for (y = 0; y < height - YOFF; y++) {
1055 if (field) fac = fac1;
1059 memcpy(out, rt1, sizeof(int) * XOFF);
1063 for (x = XOFF; x < width; x++) {
1064 temp = ((fac * rt2[3]) >> 8);
1066 *(out++) = MAX2(0, *rt1 - temp); rt1++;
1067 *(out++) = MAX2(0, *rt1 - temp); rt1++;
1068 *(out++) = MAX2(0, *rt1 - temp); rt1++;
1069 *(out++) = MAX2(0, *rt1 - temp); rt1++;
1074 memcpy(out, rt1, sizeof(int) * YOFF * width);
1077 static void do_drop_effect_float(float facf0, float facf1, int x, int y, float *rect2i, float *rect1i, float *outi)
1080 float temp, fac, fac1, fac2;
1081 float *rt1, *rt2, *out;
1087 fac1 = 70.0f * facf0;
1088 fac2 = 70.0f * facf1;
1090 rt2 = (rect2i + YOFF * width);
1093 for (y = 0; y < height - YOFF; y++) {
1094 if (field) fac = fac1;
1098 memcpy(out, rt1, 4 * sizeof(float) * XOFF);
1102 for (x = XOFF; x < width; x++) {
1103 temp = fac * rt2[3];
1105 *(out++) = MAX2(0.0f, *rt1 - temp); rt1++;
1106 *(out++) = MAX2(0.0f, *rt1 - temp); rt1++;
1107 *(out++) = MAX2(0.0f, *rt1 - temp); rt1++;
1108 *(out++) = MAX2(0.0f, *rt1 - temp); rt1++;
1113 memcpy(out, rt1, 4 * sizeof(float) * YOFF * width);
1116 /*********************** Mul *************************/
1118 static void do_mul_effect_byte(float facf0, float facf1, int x, int y, unsigned char *rect1, unsigned char *rect2,
1122 char *rt1, *rt2, *rt;
1125 rt1 = (char *)rect1;
1126 rt2 = (char *)rect2;
1129 fac1 = (int)(256.0f * facf0);
1130 fac3 = (int)(256.0f * facf1);
1133 * fac * (a * b) + (1-fac)*a => fac * a * (b - 1) + axaux = c * px + py * s; //+centx
1134 * yaux = -s * px + c * py; //+centy
1142 rt[0] = rt1[0] + ((fac1 * rt1[0] * (rt2[0] - 256)) >> 16);
1143 rt[1] = rt1[1] + ((fac1 * rt1[1] * (rt2[1] - 256)) >> 16);
1144 rt[2] = rt1[2] + ((fac1 * rt1[2] * (rt2[2] - 256)) >> 16);
1145 rt[3] = rt1[3] + ((fac1 * rt1[3] * (rt2[3] - 256)) >> 16);
1147 rt1 += 4; rt2 += 4; rt += 4;
1156 rt[0] = rt1[0] + ((fac3 * rt1[0] * (rt2[0] - 256)) >> 16);
1157 rt[1] = rt1[1] + ((fac3 * rt1[1] * (rt2[1] - 256)) >> 16);
1158 rt[2] = rt1[2] + ((fac3 * rt1[2] * (rt2[2] - 256)) >> 16);
1159 rt[3] = rt1[3] + ((fac3 * rt1[3] * (rt2[3] - 256)) >> 16);
1161 rt1 += 4; rt2 += 4; rt += 4;
1166 static void do_mul_effect_float(float facf0, float facf1, int x, int y, float *rect1, float *rect2, float *out)
1170 float *rt1, *rt2, *rt;
1181 * fac*(a*b) + (1-fac)*a => fac*a*(b-1)+a
1187 rt[0] = rt1[0] + fac1 * rt1[0] * (rt2[0] - 1.0f);
1188 rt[1] = rt1[1] + fac1 * rt1[1] * (rt2[1] - 1.0f);
1189 rt[2] = rt1[2] + fac1 * rt1[2] * (rt2[2] - 1.0f);
1190 rt[3] = rt1[3] + fac1 * rt1[3] * (rt2[3] - 1.0f);
1192 rt1 += 4; rt2 += 4; rt += 4;
1201 rt[0] = rt1[0] + fac3 * rt1[0] * (rt2[0] - 1.0f);
1202 rt[1] = rt1[1] + fac3 * rt1[1] * (rt2[1] - 1.0f);
1203 rt[2] = rt1[2] + fac3 * rt1[2] * (rt2[2] - 1.0f);
1204 rt[3] = rt1[3] + fac3 * rt1[3] * (rt2[3] - 1.0f);
1206 rt1 += 4; rt2 += 4; rt += 4;
1211 static void do_mul_effect(SeqRenderData context, Sequence *UNUSED(seq), float UNUSED(cfra), float facf0, float facf1,
1212 ImBuf *ibuf1, ImBuf *ibuf2, ImBuf *UNUSED(ibuf3), int start_line, int total_lines, ImBuf *out)
1214 if (out->rect_float) {
1215 float *rect1, *rect2, *rect_out;
1217 slize_get_float_buffers(&context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
1219 do_mul_effect_float(facf0, facf1, context.rectx, total_lines, rect1, rect2, rect_out);
1222 unsigned char *rect1, *rect2, *rect_out;
1224 slize_get_byte_buffers(&context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
1226 do_mul_effect_byte(facf0, facf1, context.rectx, total_lines, rect1, rect2, rect_out);
1230 /*********************** Wipe *************************/
1232 typedef struct WipeZone {
1240 static void precalc_wipe_zone(WipeZone *wipezone, WipeVars *wipe, int xo, int yo)
1242 wipezone->flip = (wipe->angle < 0);
1243 wipezone->angle = tanf(DEG2RADF(fabsf(wipe->angle)));
1246 wipezone->width = (int)(wipe->edgeWidth * ((xo + yo) / 2.0f));
1247 wipezone->pythangle = 1.0f / sqrtf(wipezone->angle * wipezone->angle + 1.0f);
1250 /* This function calculates the blur band for the wipe effects */
1251 static float in_band(float width, float dist, int side, int dir)
1262 alpha = (dist + 0.5f * width) / (width);
1264 alpha = (0.5f * width - dist) / (width);
1272 static float check_zone(WipeZone *wipezone, int x, int y, Sequence *seq, float facf0)
1274 float posx, posy, hyp, hyp2, angle, hwidth, b1, b2, b3, pointdist;
1275 /* some future stuff */
1276 /* float hyp3, hyp4, b4, b5 */
1277 float temp1, temp2, temp3, temp4; /* some placeholder variables */
1278 int xo = wipezone->xo;
1279 int yo = wipezone->yo;
1280 float halfx = xo * 0.5f;
1281 float halfy = yo * 0.5f;
1282 float widthf, output = 0;
1283 WipeVars *wipe = (WipeVars *)seq->effectdata;
1286 if (wipezone->flip) x = xo - x;
1287 angle = wipezone->angle;
1289 if (wipe->forward) {
1294 posx = xo - facf0 * xo;
1295 posy = yo - facf0 * yo;
1298 switch (wipe->wipetype) {
1299 case DO_SINGLE_WIPE:
1300 width = wipezone->width;
1302 if (angle == 0.0f) {
1305 hyp = fabs(y - posy);
1308 b1 = posy - (-angle) * posx;
1309 b2 = y - (-angle) * x;
1310 hyp = fabsf(angle * x + y + (-posy - angle * posx)) * wipezone->pythangle;
1319 if (wipe->forward) {
1321 output = in_band(width, hyp, 1, 1);
1323 output = in_band(width, hyp, 0, 1);
1327 output = in_band(width, hyp, 0, 1);
1329 output = in_band(width, hyp, 1, 1);
1333 case DO_DOUBLE_WIPE:
1335 facf0 = 1.0f - facf0; /* Go the other direction */
1337 width = wipezone->width; /* calculate the blur width */
1338 hwidth = width * 0.5f;
1341 b3 = yo - posy * 0.5f;
1344 hyp = abs(y - posy * 0.5f);
1345 hyp2 = abs(y - (yo - posy * 0.5f));
1348 b1 = posy * 0.5f - (-angle) * posx * 0.5f;
1349 b3 = (yo - posy * 0.5f) - (-angle) * (xo - posx * 0.5f);
1350 b2 = y - (-angle) * x;
1352 hyp = fabsf(angle * x + y + (-posy * 0.5f - angle * posx * 0.5f)) * wipezone->pythangle;
1353 hyp2 = fabsf(angle * x + y + (-(yo - posy * 0.5f) - angle * (xo - posx * 0.5f))) * wipezone->pythangle;
1356 hwidth = minf(hwidth, fabsf(b3 - b1) / 2.0f);
1358 if (b2 < b1 && b2 < b3) {
1359 output = in_band(hwidth, hyp, 0, 1);
1361 else if (b2 > b1 && b2 > b3) {
1362 output = in_band(hwidth, hyp2, 0, 1);
1365 if (hyp < hwidth && hyp2 > hwidth)
1366 output = in_band(hwidth, hyp, 1, 1);
1367 else if (hyp > hwidth && hyp2 < hwidth)
1368 output = in_band(hwidth, hyp2, 1, 1);
1370 output = in_band(hwidth, hyp2, 1, 1) * in_band(hwidth, hyp, 1, 1);
1372 if (!wipe->forward) output = 1 - output;
1376 * temp1: angle of effect center in rads
1377 * temp2: angle of line through (halfx, halfy) and (x, y) in rads
1378 * temp3: angle of low side of blur
1379 * temp4: angle of high side of blur
1381 output = 1.0f - facf0;
1382 widthf = wipe->edgeWidth * 2.0f * (float)M_PI;
1383 temp1 = 2.0f * (float)M_PI * facf0;
1385 if (wipe->forward) {
1386 temp1 = 2.0f * (float)M_PI - temp1;
1392 temp2 = asin(abs(y) / sqrt(x * x + y * y));
1393 if (x <= 0 && y >= 0) temp2 = (float)M_PI - temp2;
1394 else if (x <= 0 && y <= 0) temp2 += (float)M_PI;
1395 else if (x >= 0 && y <= 0) temp2 = 2.0f * (float)M_PI - temp2;
1397 if (wipe->forward) {
1398 temp3 = temp1 - (widthf * 0.5f) * facf0;
1399 temp4 = temp1 + (widthf * 0.5f) * (1 - facf0);
1402 temp3 = temp1 - (widthf * 0.5f) * (1 - facf0);
1403 temp4 = temp1 + (widthf * 0.5f) * facf0;
1405 if (temp3 < 0) temp3 = 0;
1406 if (temp4 > 2.0f * (float)M_PI) temp4 = 2.0f * (float)M_PI;
1409 if (temp2 < temp3) output = 0;
1410 else if (temp2 > temp4) output = 1;
1411 else output = (temp2 - temp3) / (temp4 - temp3);
1412 if (x == 0 && y == 0) output = 1;
1413 if (output != output) output = 1;
1414 if (wipe->forward) output = 1 - output;
1416 /* BOX WIPE IS NOT WORKING YET */
1417 /* case DO_CROSS_WIPE: */
1418 /* BOX WIPE IS NOT WORKING YET */
1421 if (invert) facf0 = 1 - facf0;
1423 width = (int)(wipe->edgeWidth * ((xo + yo) / 2.0));
1424 hwidth = (float)width / 2.0;
1425 if (angle == 0) angle = 0.000001;
1426 b1 = posy / 2 - (-angle) * posx / 2;
1427 b3 = (yo - posy / 2) - (-angle) * (xo - posx / 2);
1428 b2 = y - (-angle) * x;
1430 hyp = abs(angle * x + y + (-posy / 2 - angle * posx / 2)) * wipezone->pythangle;
1431 hyp2 = abs(angle * x + y + (-(yo - posy / 2) - angle * (xo - posx / 2))) * wipezone->pythangle;
1433 temp1 = xo * (1 - facf0 / 2) - xo * facf0 / 2;
1434 temp2 = yo * (1 - facf0 / 2) - yo * facf0 / 2;
1435 pointdist = sqrt(temp1 * temp1 + temp2 * temp2);
1437 if (b2 < b1 && b2 < b3) {
1438 if (hwidth < pointdist)
1439 output = in_band(wipezone, hwidth, hyp, facf0, 0, 1);
1441 else if (b2 > b1 && b2 > b3) {
1442 if (hwidth < pointdist)
1443 output = in_band(wipezone, hwidth, hyp2, facf0, 0, 1);
1446 if (hyp < hwidth && hyp2 > hwidth)
1447 output = in_band(wipezone, hwidth, hyp, facf0, 1, 1);
1448 else if (hyp > hwidth && hyp2 < hwidth)
1449 output = in_band(wipezone, hwidth, hyp2, facf0, 1, 1);
1451 output = in_band(wipezone, hwidth, hyp2, facf0, 1, 1) * in_band(wipezone, hwidth, hyp, facf0, 1, 1);
1454 if (invert) facf0 = 1 - facf0;
1456 b1 = posy / 2 - (-angle) * posx / 2;
1457 b3 = (yo - posy / 2) - (-angle) * (xo - posx / 2);
1458 b2 = y - (-angle) * x;
1460 hyp = abs(angle * x + y + (-posy / 2 - angle * posx / 2)) * wipezone->pythangle;
1461 hyp2 = abs(angle * x + y + (-(yo - posy / 2) - angle * (xo - posx / 2))) * wipezone->pythangle;
1463 if (b2 < b1 && b2 < b3) {
1464 if (hwidth < pointdist)
1465 output *= in_band(wipezone, hwidth, hyp, facf0, 0, 1);
1467 else if (b2 > b1 && b2 > b3) {
1468 if (hwidth < pointdist)
1469 output *= in_band(wipezone, hwidth, hyp2, facf0, 0, 1);
1472 if (hyp < hwidth && hyp2 > hwidth)
1473 output *= in_band(wipezone, hwidth, hyp, facf0, 1, 1);
1474 else if (hyp > hwidth && hyp2 < hwidth)
1475 output *= in_band(wipezone, hwidth, hyp2, facf0, 1, 1);
1477 output *= in_band(wipezone, hwidth, hyp2, facf0, 1, 1) * in_band(wipezone, hwidth, hyp, facf0, 1, 1);
1483 if (xo > yo) yo = xo;
1486 if (!wipe->forward) facf0 = 1 - facf0;
1488 width = wipezone->width;
1489 hwidth = width * 0.5f;
1491 temp1 = (halfx - (halfx) * facf0);
1492 pointdist = sqrt(temp1 * temp1 + temp1 * temp1);
1494 temp2 = sqrt((halfx - x) * (halfx - x) + (halfy - y) * (halfy - y));
1495 if (temp2 > pointdist) output = in_band(hwidth, fabs(temp2 - pointdist), 0, 1);
1496 else output = in_band(hwidth, fabs(temp2 - pointdist), 1, 1);
1498 if (!wipe->forward) output = 1 - output;
1502 if (output < 0) output = 0;
1503 else if (output > 1) output = 1;
1507 static void init_wipe_effect(Sequence *seq)
1509 if (seq->effectdata)
1510 MEM_freeN(seq->effectdata);
1512 seq->effectdata = MEM_callocN(sizeof(WipeVars), "wipevars");
1515 static int num_inputs_wipe(void)
1520 static void free_wipe_effect(Sequence *seq)
1522 if (seq->effectdata)
1523 MEM_freeN(seq->effectdata);
1525 seq->effectdata = NULL;
1528 static void copy_wipe_effect(Sequence *dst, Sequence *src)
1530 dst->effectdata = MEM_dupallocN(src->effectdata);
1533 static void do_wipe_effect_byte(Sequence *seq, float facf0, float UNUSED(facf1), int x, int y, unsigned char *rect1,
1534 unsigned char *rect2, unsigned char *out)
1537 WipeVars *wipe = (WipeVars *)seq->effectdata;
1539 char *rt1, *rt2, *rt;
1541 precalc_wipe_zone(&wipezone, wipe, x, y);
1543 rt1 = (char *)rect1;
1544 rt2 = (char *)rect2;
1549 for (y = 0; y < yo; y++) {
1550 for (x = 0; x < xo; x++) {
1551 float check = check_zone(&wipezone, x, y, seq, facf0);
1554 rt[0] = (int)(rt1[0] * check) + (int)(rt2[0] * (1 - check));
1555 rt[1] = (int)(rt1[1] * check) + (int)(rt2[1] * (1 - check));
1556 rt[2] = (int)(rt1[2] * check) + (int)(rt2[2] * (1 - check));
1557 rt[3] = (int)(rt1[3] * check) + (int)(rt2[3] * (1 - check));
1592 static void do_wipe_effect_float(Sequence *seq, float facf0, float UNUSED(facf1), int x, int y, float *rect1,
1593 float *rect2, float *out)
1596 WipeVars *wipe = (WipeVars *)seq->effectdata;
1598 float *rt1, *rt2, *rt;
1600 precalc_wipe_zone(&wipezone, wipe, x, y);
1608 for (y = 0; y < yo; y++) {
1609 for (x = 0; x < xo; x++) {
1610 float check = check_zone(&wipezone, x, y, seq, facf0);
1613 rt[0] = rt1[0] * check + rt2[0] * (1 - check);
1614 rt[1] = rt1[1] * check + rt2[1] * (1 - check);
1615 rt[2] = rt1[2] * check + rt2[2] * (1 - check);
1616 rt[3] = rt1[3] * check + rt2[3] * (1 - check);
1651 static ImBuf *do_wipe_effect(SeqRenderData context, Sequence *seq, float UNUSED(cfra), float facf0, float facf1,
1652 ImBuf *ibuf1, ImBuf *ibuf2, ImBuf *ibuf3)
1654 ImBuf *out = prepare_effect_imbufs(context, ibuf1, ibuf2, ibuf3);
1656 if (out->rect_float) {
1657 do_wipe_effect_float(seq, facf0, facf1, context.rectx, context.recty, ibuf1->rect_float,
1658 ibuf2->rect_float, out->rect_float);
1661 do_wipe_effect_byte(seq, facf0, facf1, context.rectx, context.recty, (unsigned char *) ibuf1->rect,
1662 (unsigned char *) ibuf2->rect, (unsigned char *) out->rect);
1668 /*********************** Transform *************************/
1670 static void init_transform_effect(Sequence *seq)
1672 TransformVars *transform;
1674 if (seq->effectdata)
1675 MEM_freeN(seq->effectdata);
1677 seq->effectdata = MEM_callocN(sizeof(TransformVars), "transformvars");
1679 transform = (TransformVars *) seq->effectdata;
1681 transform->ScalexIni = 1.0f;
1682 transform->ScaleyIni = 1.0f;
1684 transform->xIni = 0.0f;
1685 transform->yIni = 0.0f;
1687 transform->rotIni = 0.0f;
1689 transform->interpolation = 1;
1690 transform->percent = 1;
1691 transform->uniform_scale = 0;
1694 static int num_inputs_transform(void)
1699 static void free_transform_effect(Sequence *seq)
1701 if (seq->effectdata) MEM_freeN(seq->effectdata);
1702 seq->effectdata = NULL;
1705 static void copy_transform_effect(Sequence *dst, Sequence *src)
1707 dst->effectdata = MEM_dupallocN(src->effectdata);
1710 static void transform_image(int x, int y, ImBuf *ibuf1, ImBuf *out, float scale_x, float scale_y,
1711 float translate_x, float translate_y, float rotate, int interpolation)
1714 float xt, yt, xr, yr;
1724 for (yi = 0; yi < yo; yi++) {
1725 for (xi = 0; xi < xo; xi++) {
1726 /* translate point */
1727 xt = xi - translate_x;
1728 yt = yi - translate_y;
1730 /* rotate point with center ref */
1731 xr = c * xt + s * yt;
1732 yr = -s * xt + c * yt;
1734 /* scale point with center ref */
1738 /* undo reference center point */
1743 switch (interpolation) {
1745 neareast_interpolation(ibuf1, out, xt, yt, xi, yi);
1748 bilinear_interpolation(ibuf1, out, xt, yt, xi, yi);
1751 bicubic_interpolation(ibuf1, out, xt, yt, xi, yi);
1758 static void do_transform(Scene *scene, Sequence *seq, float UNUSED(facf0), int x, int y, ImBuf *ibuf1, ImBuf *out)
1760 TransformVars *transform = (TransformVars *) seq->effectdata;
1761 float scale_x, scale_y, translate_x, translate_y, rotate_radians;
1764 if (transform->uniform_scale) {
1765 scale_x = scale_y = transform->ScalexIni;
1768 scale_x = transform->ScalexIni;
1769 scale_y = transform->ScaleyIni;
1773 if (!transform->percent) {
1774 float rd_s = (scene->r.size / 100.0f);
1776 translate_x = transform->xIni * rd_s + (x / 2.0f);
1777 translate_y = transform->yIni * rd_s + (y / 2.0f);
1780 translate_x = x * (transform->xIni / 100.0f) + (x / 2.0f);
1781 translate_y = y * (transform->yIni / 100.0f) + (y / 2.0f);
1785 rotate_radians = DEG2RADF(transform->rotIni);
1787 transform_image(x, y, ibuf1, out, scale_x, scale_y, translate_x, translate_y, rotate_radians, transform->interpolation);
1791 static ImBuf *do_transform_effect(SeqRenderData context, Sequence *seq, float UNUSED(cfra), float facf0,
1792 float UNUSED(facf1), ImBuf *ibuf1, ImBuf *ibuf2, ImBuf *ibuf3)
1794 ImBuf *out = prepare_effect_imbufs(context, ibuf1, ibuf2, ibuf3);
1796 do_transform(context.scene, seq, facf0, context.rectx, context.recty, ibuf1, out);
1801 /*********************** Glow *************************/
1803 static void RVBlurBitmap2_byte(unsigned char *map, int width, int height, float blur, int quality)
1804 /* MUUUCCH better than the previous blur. */
1805 /* We do the blurring in two passes which is a whole lot faster. */
1806 /* I changed the math arount to implement an actual Gaussian */
1809 /* Watch out though, it tends to misbehaven with large blur values on */
1810 /* a small bitmap. Avoid avoid avoid. */
1811 /*=============================== */
1813 unsigned char *temp = NULL, *swap;
1814 float *filter = NULL;
1815 int x, y, i, fx, fy;
1816 int index, ix, halfWidth;
1817 float fval, k, curColor[3], curColor2[3], weight = 0;
1819 /* If we're not really blurring, bail out */
1823 /*Allocate memory for the tempmap and the blur filter matrix */
1824 temp = MEM_mallocN((width * height * 4), "blurbitmaptemp");
1828 /*Allocate memory for the filter elements */
1829 halfWidth = ((quality + 1) * blur);
1830 filter = (float *)MEM_mallocN(sizeof(float) * halfWidth * 2, "blurbitmapfilter");
1836 /* Apparently we're calculating a bell curve based on the standard deviation (or radius)
1837 * This code is based on an example posted to comp.graphics.algorithms by
1838 * Blancmange (bmange@airdmhor.gen.nz)
1841 k = -1.0f / (2.0f * (float)M_PI * blur * blur);
1842 for (ix = 0; ix < halfWidth; ix++) {
1843 weight = (float)exp(k * (ix * ix));
1844 filter[halfWidth - ix] = weight;
1845 filter[halfWidth + ix] = weight;
1849 /* Normalize the array */
1851 for (ix = 0; ix < halfWidth * 2; ix++)
1854 for (ix = 0; ix < halfWidth * 2; ix++)
1858 for (y = 0; y < height; y++) {
1859 /* Do the left & right strips */
1860 for (x = 0; x < halfWidth; x++) {
1861 index = (x + y * width) * 4;
1866 for (i = x - halfWidth; i < x + halfWidth; i++) {
1867 if ((i >= 0) && (i < width)) {
1868 curColor[0] += map[(i + y * width) * 4 + GlowR] * filter[fx];
1869 curColor[1] += map[(i + y * width) * 4 + GlowG] * filter[fx];
1870 curColor[2] += map[(i + y * width) * 4 + GlowB] * filter[fx];
1872 curColor2[0] += map[(width - 1 - i + y * width) * 4 + GlowR] * filter[fx];
1873 curColor2[1] += map[(width - 1 - i + y * width) * 4 + GlowG] * filter[fx];
1874 curColor2[2] += map[(width - 1 - i + y * width) * 4 + GlowB] * filter[fx];
1878 temp[index + GlowR] = curColor[0];
1879 temp[index + GlowG] = curColor[1];
1880 temp[index + GlowB] = curColor[2];
1882 temp[((width - 1 - x + y * width) * 4) + GlowR] = curColor2[0];
1883 temp[((width - 1 - x + y * width) * 4) + GlowG] = curColor2[1];
1884 temp[((width - 1 - x + y * width) * 4) + GlowB] = curColor2[2];
1888 /* Do the main body */
1889 for (x = halfWidth; x < width - halfWidth; x++) {
1890 index = (x + y * width) * 4;
1893 for (i = x - halfWidth; i < x + halfWidth; i++) {
1894 curColor[0] += map[(i + y * width) * 4 + GlowR] * filter[fx];
1895 curColor[1] += map[(i + y * width) * 4 + GlowG] * filter[fx];
1896 curColor[2] += map[(i + y * width) * 4 + GlowB] * filter[fx];
1899 temp[index + GlowR] = curColor[0];
1900 temp[index + GlowG] = curColor[1];
1901 temp[index + GlowB] = curColor[2];
1906 swap = temp; temp = map; map = swap;
1908 /* Blur the columns */
1909 for (x = 0; x < width; x++) {
1910 /* Do the top & bottom strips */
1911 for (y = 0; y < halfWidth; y++) {
1912 index = (x + y * width) * 4;
1916 for (i = y - halfWidth; i < y + halfWidth; i++) {
1917 if ((i >= 0) && (i < height)) {
1919 curColor[0] += map[(x + i * width) * 4 + GlowR] * filter[fy];
1920 curColor[1] += map[(x + i * width) * 4 + GlowG] * filter[fy];
1921 curColor[2] += map[(x + i * width) * 4 + GlowB] * filter[fy];
1924 curColor2[0] += map[(x + (height - 1 - i) * width) * 4 + GlowR] * filter[fy];
1925 curColor2[1] += map[(x + (height - 1 - i) * width) * 4 + GlowG] * filter[fy];
1926 curColor2[2] += map[(x + (height - 1 - i) * width) * 4 + GlowB] * filter[fy];
1930 temp[index + GlowR] = curColor[0];
1931 temp[index + GlowG] = curColor[1];
1932 temp[index + GlowB] = curColor[2];
1933 temp[((x + (height - 1 - y) * width) * 4) + GlowR] = curColor2[0];
1934 temp[((x + (height - 1 - y) * width) * 4) + GlowG] = curColor2[1];
1935 temp[((x + (height - 1 - y) * width) * 4) + GlowB] = curColor2[2];
1938 /* Do the main body */
1939 for (y = halfWidth; y < height - halfWidth; y++) {
1940 index = (x + y * width) * 4;
1943 for (i = y - halfWidth; i < y + halfWidth; i++) {
1944 curColor[0] += map[(x + i * width) * 4 + GlowR] * filter[fy];
1945 curColor[1] += map[(x + i * width) * 4 + GlowG] * filter[fy];
1946 curColor[2] += map[(x + i * width) * 4 + GlowB] * filter[fy];
1949 temp[index + GlowR] = curColor[0];
1950 temp[index + GlowG] = curColor[1];
1951 temp[index + GlowB] = curColor[2];
1956 swap = temp; temp = map; /* map = swap; */ /* UNUSED */
1963 static void RVBlurBitmap2_float(float *map, int width, int height, float blur, int quality)
1964 /* MUUUCCH better than the previous blur. */
1965 /* We do the blurring in two passes which is a whole lot faster. */
1966 /* I changed the math arount to implement an actual Gaussian */
1969 /* Watch out though, it tends to misbehaven with large blur values on */
1970 /* a small bitmap. Avoid avoid avoid. */
1971 /*=============================== */
1973 float *temp = NULL, *swap;
1974 float *filter = NULL;
1975 int x, y, i, fx, fy;
1976 int index, ix, halfWidth;
1977 float fval, k, curColor[3], curColor2[3], weight = 0;
1979 /* If we're not really blurring, bail out */
1983 /* Allocate memory for the tempmap and the blur filter matrix */
1984 temp = MEM_mallocN((width * height * 4 * sizeof(float)), "blurbitmaptemp");
1988 /* Allocate memory for the filter elements */
1989 halfWidth = ((quality + 1) * blur);
1990 filter = (float *)MEM_mallocN(sizeof(float) * halfWidth * 2, "blurbitmapfilter");
1996 /* Apparently we're calculating a bell curve based on the standard deviation (or radius)
1997 * This code is based on an example posted to comp.graphics.algorithms by
1998 * Blancmange (bmange@airdmhor.gen.nz)
2001 k = -1.0f / (2.0f * (float)M_PI * blur * blur);
2003 for (ix = 0; ix < halfWidth; ix++) {
2004 weight = (float)exp(k * (ix * ix));
2005 filter[halfWidth - ix] = weight;
2006 filter[halfWidth + ix] = weight;
2010 /* Normalize the array */
2012 for (ix = 0; ix < halfWidth * 2; ix++)
2015 for (ix = 0; ix < halfWidth * 2; ix++)
2019 for (y = 0; y < height; y++) {
2020 /* Do the left & right strips */
2021 for (x = 0; x < halfWidth; x++) {
2022 index = (x + y * width) * 4;
2024 curColor[0] = curColor[1] = curColor[2] = 0.0f;
2025 curColor2[0] = curColor2[1] = curColor2[2] = 0.0f;
2027 for (i = x - halfWidth; i < x + halfWidth; i++) {
2028 if ((i >= 0) && (i < width)) {
2029 curColor[0] += map[(i + y * width) * 4 + GlowR] * filter[fx];
2030 curColor[1] += map[(i + y * width) * 4 + GlowG] * filter[fx];
2031 curColor[2] += map[(i + y * width) * 4 + GlowB] * filter[fx];
2033 curColor2[0] += map[(width - 1 - i + y * width) * 4 + GlowR] * filter[fx];
2034 curColor2[1] += map[(width - 1 - i + y * width) * 4 + GlowG] * filter[fx];
2035 curColor2[2] += map[(width - 1 - i + y * width) * 4 + GlowB] * filter[fx];
2039 temp[index + GlowR] = curColor[0];
2040 temp[index + GlowG] = curColor[1];
2041 temp[index + GlowB] = curColor[2];
2043 temp[((width - 1 - x + y * width) * 4) + GlowR] = curColor2[0];
2044 temp[((width - 1 - x + y * width) * 4) + GlowG] = curColor2[1];
2045 temp[((width - 1 - x + y * width) * 4) + GlowB] = curColor2[2];
2049 /* Do the main body */
2050 for (x = halfWidth; x < width - halfWidth; x++) {
2051 index = (x + y * width) * 4;
2054 for (i = x - halfWidth; i < x + halfWidth; i++) {
2055 curColor[0] += map[(i + y * width) * 4 + GlowR] * filter[fx];
2056 curColor[1] += map[(i + y * width) * 4 + GlowG] * filter[fx];
2057 curColor[2] += map[(i + y * width) * 4 + GlowB] * filter[fx];
2060 temp[index + GlowR] = curColor[0];
2061 temp[index + GlowG] = curColor[1];
2062 temp[index + GlowB] = curColor[2];
2067 swap = temp; temp = map; map = swap;
2069 /* Blur the columns */
2070 for (x = 0; x < width; x++) {
2071 /* Do the top & bottom strips */
2072 for (y = 0; y < halfWidth; y++) {
2073 index = (x + y * width) * 4;
2077 for (i = y - halfWidth; i < y + halfWidth; i++) {
2078 if ((i >= 0) && (i < height)) {
2080 curColor[0] += map[(x + i * width) * 4 + GlowR] * filter[fy];
2081 curColor[1] += map[(x + i * width) * 4 + GlowG] * filter[fy];
2082 curColor[2] += map[(x + i * width) * 4 + GlowB] * filter[fy];
2085 curColor2[0] += map[(x + (height - 1 - i) * width) * 4 + GlowR] * filter[fy];
2086 curColor2[1] += map[(x + (height - 1 - i) * width) * 4 + GlowG] * filter[fy];
2087 curColor2[2] += map[(x + (height - 1 - i) * width) * 4 + GlowB] * filter[fy];
2091 temp[index + GlowR] = curColor[0];
2092 temp[index + GlowG] = curColor[1];
2093 temp[index + GlowB] = curColor[2];
2094 temp[((x + (height - 1 - y) * width) * 4) + GlowR] = curColor2[0];
2095 temp[((x + (height - 1 - y) * width) * 4) + GlowG] = curColor2[1];
2096 temp[((x + (height - 1 - y) * width) * 4) + GlowB] = curColor2[2];
2099 /* Do the main body */
2100 for (y = halfWidth; y < height - halfWidth; y++) {
2101 index = (x + y * width) * 4;
2104 for (i = y - halfWidth; i < y + halfWidth; i++) {
2105 curColor[0] += map[(x + i * width) * 4 + GlowR] * filter[fy];
2106 curColor[1] += map[(x + i * width) * 4 + GlowG] * filter[fy];
2107 curColor[2] += map[(x + i * width) * 4 + GlowB] * filter[fy];
2110 temp[index + GlowR] = curColor[0];
2111 temp[index + GlowG] = curColor[1];
2112 temp[index + GlowB] = curColor[2];
2117 swap = temp; temp = map; /* map = swap; */ /* UNUSED */
2125 /* Adds two bitmaps and puts the results into a third map. */
2126 /* C must have been previously allocated but it may be A or B. */
2127 /* We clamp values to 255 to prevent weirdness */
2128 /*=============================== */
2129 static void RVAddBitmaps_byte(unsigned char *a, unsigned char *b, unsigned char *c, int width, int height)
2133 for (y = 0; y < height; y++) {
2134 for (x = 0; x < width; x++) {
2135 index = (x + y * width) * 4;
2136 c[index + GlowR] = MIN2(255, a[index + GlowR] + b[index + GlowR]);
2137 c[index + GlowG] = MIN2(255, a[index + GlowG] + b[index + GlowG]);
2138 c[index + GlowB] = MIN2(255, a[index + GlowB] + b[index + GlowB]);
2139 c[index + GlowA] = MIN2(255, a[index + GlowA] + b[index + GlowA]);
2144 static void RVAddBitmaps_float(float *a, float *b, float *c, int width, int height)
2148 for (y = 0; y < height; y++) {
2149 for (x = 0; x < width; x++) {
2150 index = (x + y * width) * 4;
2151 c[index + GlowR] = MIN2(1.0f, a[index + GlowR] + b[index + GlowR]);
2152 c[index + GlowG] = MIN2(1.0f, a[index + GlowG] + b[index + GlowG]);
2153 c[index + GlowB] = MIN2(1.0f, a[index + GlowB] + b[index + GlowB]);
2154 c[index + GlowA] = MIN2(1.0f, a[index + GlowA] + b[index + GlowA]);
2159 /* For each pixel whose total luminance exceeds the threshold,
2160 * Multiply it's value by BOOST and add it to the output map
2162 static void RVIsolateHighlights_byte(unsigned char *in, unsigned char *out, int width, int height, int threshold,
2163 float boost, float clamp)
2168 for (y = 0; y < height; y++) {
2169 for (x = 0; x < width; x++) {
2170 index = (x + y * width) * 4;
2172 /* Isolate the intensity */
2173 intensity = (in[index + GlowR] + in[index + GlowG] + in[index + GlowB] - threshold);
2174 if (intensity > 0) {
2175 out[index + GlowR] = MIN2(255 * clamp, (in[index + GlowR] * boost * intensity) / 255);
2176 out[index + GlowG] = MIN2(255 * clamp, (in[index + GlowG] * boost * intensity) / 255);
2177 out[index + GlowB] = MIN2(255 * clamp, (in[index + GlowB] * boost * intensity) / 255);
2178 out[index + GlowA] = MIN2(255 * clamp, (in[index + GlowA] * boost * intensity) / 255);
2181 out[index + GlowR] = 0;
2182 out[index + GlowG] = 0;
2183 out[index + GlowB] = 0;
2184 out[index + GlowA] = 0;
2190 static void RVIsolateHighlights_float(float *in, float *out, int width, int height, float threshold, float boost, float clamp)
2195 for (y = 0; y < height; y++) {
2196 for (x = 0; x < width; x++) {
2197 index = (x + y * width) * 4;
2199 /* Isolate the intensity */
2200 intensity = (in[index + GlowR] + in[index + GlowG] + in[index + GlowB] - threshold);
2201 if (intensity > 0) {
2202 out[index + GlowR] = MIN2(clamp, (in[index + GlowR] * boost * intensity));
2203 out[index + GlowG] = MIN2(clamp, (in[index + GlowG] * boost * intensity));
2204 out[index + GlowB] = MIN2(clamp, (in[index + GlowB] * boost * intensity));
2205 out[index + GlowA] = MIN2(clamp, (in[index + GlowA] * boost * intensity));
2208 out[index + GlowR] = 0;
2209 out[index + GlowG] = 0;
2210 out[index + GlowB] = 0;
2211 out[index + GlowA] = 0;
2217 static void init_glow_effect(Sequence *seq)
2221 if (seq->effectdata)
2222 MEM_freeN(seq->effectdata);
2224 seq->effectdata = MEM_callocN(sizeof(GlowVars), "glowvars");
2226 glow = (GlowVars *)seq->effectdata;
2235 static int num_inputs_glow(void)
2240 static void free_glow_effect(Sequence *seq)
2242 if (seq->effectdata)
2243 MEM_freeN(seq->effectdata);
2245 seq->effectdata = NULL;
2248 static void copy_glow_effect(Sequence *dst, Sequence *src)
2250 dst->effectdata = MEM_dupallocN(src->effectdata);
2253 static void do_glow_effect_byte(Sequence *seq, int render_size, float facf0, float UNUSED(facf1), int x, int y,
2254 char *rect1, char *UNUSED(rect2), char *out)
2256 unsigned char *outbuf = (unsigned char *)out;
2257 unsigned char *inbuf = (unsigned char *)rect1;
2258 GlowVars *glow = (GlowVars *)seq->effectdata;
2260 RVIsolateHighlights_byte(inbuf, outbuf, x, y, glow->fMini * 765, glow->fBoost * facf0, glow->fClamp);
2261 RVBlurBitmap2_byte(outbuf, x, y, glow->dDist * (render_size / 100.0f), glow->dQuality);
2263 RVAddBitmaps_byte(inbuf, outbuf, outbuf, x, y);
2266 static void do_glow_effect_float(Sequence *seq, int render_size, float facf0, float UNUSED(facf1), int x, int y,
2267 float *rect1, float *UNUSED(rect2), float *out)
2269 float *outbuf = out;
2270 float *inbuf = rect1;
2271 GlowVars *glow = (GlowVars *)seq->effectdata;
2273 RVIsolateHighlights_float(inbuf, outbuf, x, y, glow->fMini * 3.0f, glow->fBoost * facf0, glow->fClamp);
2274 RVBlurBitmap2_float(outbuf, x, y, glow->dDist * (render_size / 100.0f), glow->dQuality);
2276 RVAddBitmaps_float(inbuf, outbuf, outbuf, x, y);
2279 static ImBuf *do_glow_effect(SeqRenderData context, Sequence *seq, float UNUSED(cfra), float facf0, float facf1,
2280 ImBuf *ibuf1, ImBuf *ibuf2, ImBuf *ibuf3)
2282 ImBuf *out = prepare_effect_imbufs(context, ibuf1, ibuf2, ibuf3);
2284 int render_size = 100 * context.rectx / context.scene->r.xsch;
2286 if (out->rect_float) {
2287 do_glow_effect_float(seq, render_size, facf0, facf1, context.rectx, context.recty,
2288 ibuf1->rect_float, ibuf2->rect_float, out->rect_float);
2291 do_glow_effect_byte(seq, render_size, facf0, facf1, context.rectx, context.recty,
2292 (char *) ibuf1->rect, (char *) ibuf2->rect, (char *) out->rect);
2298 /*********************** Solid color *************************/
2300 static void init_solid_color(Sequence *seq)
2304 if (seq->effectdata)
2305 MEM_freeN(seq->effectdata);
2307 seq->effectdata = MEM_callocN(sizeof(SolidColorVars), "solidcolor");
2309 cv = (SolidColorVars *)seq->effectdata;
2310 cv->col[0] = cv->col[1] = cv->col[2] = 0.5;
2313 static int num_inputs_color(void)
2318 static void free_solid_color(Sequence *seq)
2320 if (seq->effectdata)
2321 MEM_freeN(seq->effectdata);
2323 seq->effectdata = NULL;
2326 static void copy_solid_color(Sequence *dst, Sequence *src)
2328 dst->effectdata = MEM_dupallocN(src->effectdata);
2331 static int early_out_color(Sequence *UNUSED(seq), float UNUSED(facf0), float UNUSED(facf1))
2333 return EARLY_NO_INPUT;
2336 static ImBuf *do_solid_color(SeqRenderData context, Sequence *seq, float UNUSED(cfra), float facf0, float facf1,
2337 ImBuf *ibuf1, ImBuf *ibuf2, ImBuf *ibuf3)
2339 ImBuf *out = prepare_effect_imbufs(context, ibuf1, ibuf2, ibuf3);
2341 SolidColorVars *cv = (SolidColorVars *)seq->effectdata;
2343 unsigned char *rect;
2345 int x; /*= context.rectx;*/ /*UNUSED*/
2346 int y; /*= context.recty;*/ /*UNUSED*/
2349 unsigned char col0[3];
2350 unsigned char col1[3];
2352 col0[0] = facf0 * cv->col[0] * 255;
2353 col0[1] = facf0 * cv->col[1] * 255;
2354 col0[2] = facf0 * cv->col[2] * 255;
2356 col1[0] = facf1 * cv->col[0] * 255;
2357 col1[1] = facf1 * cv->col[1] * 255;
2358 col1[2] = facf1 * cv->col[2] * 255;
2360 rect = (unsigned char *)out->rect;
2362 for (y = 0; y < out->y; y++) {
2363 for (x = 0; x < out->x; x++, rect += 4) {
2371 for (x = 0; x < out->x; x++, rect += 4) {
2381 else if (out->rect_float) {
2385 col0[0] = facf0 * cv->col[0];
2386 col0[1] = facf0 * cv->col[1];
2387 col0[2] = facf0 * cv->col[2];
2389 col1[0] = facf1 * cv->col[0];
2390 col1[1] = facf1 * cv->col[1];
2391 col1[2] = facf1 * cv->col[2];
2393 rect_float = out->rect_float;
2395 for (y = 0; y < out->y; y++) {
2396 for (x = 0; x < out->x; x++, rect_float += 4) {
2397 rect_float[0] = col0[0];
2398 rect_float[1] = col0[1];
2399 rect_float[2] = col0[2];
2400 rect_float[3] = 1.0;
2404 for (x = 0; x < out->x; x++, rect_float += 4) {
2405 rect_float[0] = col1[0];
2406 rect_float[1] = col1[1];
2407 rect_float[2] = col1[2];
2408 rect_float[3] = 1.0;
2416 /*********************** Mulitcam *************************/
2418 /* no effect inputs for multicam, we use give_ibuf_seq */
2419 static int num_inputs_multicam(void)
2424 static int early_out_multicam(Sequence *UNUSED(seq), float UNUSED(facf0), float UNUSED(facf1))
2426 return EARLY_NO_INPUT;
2429 static ImBuf *do_multicam(SeqRenderData context, Sequence *seq, float cfra, float UNUSED(facf0), float UNUSED(facf1),
2430 ImBuf *UNUSED(ibuf1), ImBuf *UNUSED(ibuf2), ImBuf *UNUSED(ibuf3))
2437 if (seq->multicam_source == 0 || seq->multicam_source >= seq->machine) {
2441 ed = context.scene->ed;
2445 seqbasep = BKE_sequence_seqbase(&ed->seqbase, seq);
2450 i = BKE_sequencer_give_ibuf_seqbase(context, cfra, seq->multicam_source, seqbasep);
2455 if (BKE_sequencer_input_have_to_preprocess(context, seq, cfra)) {
2456 out = IMB_dupImBuf(i);
2466 /*********************** Adjustment *************************/
2468 /* no effect inputs for adjustment, we use give_ibuf_seq */
2469 static int num_inputs_adjustment(void)
2474 static int early_out_adjustment(Sequence *UNUSED(seq), float UNUSED(facf0), float UNUSED(facf1))
2476 return EARLY_NO_INPUT;
2479 static ImBuf *do_adjustment_impl(SeqRenderData context, Sequence *seq, float cfra)
2485 ed = context.scene->ed;
2487 seqbasep = BKE_sequence_seqbase(&ed->seqbase, seq);
2489 if (seq->machine > 1) {
2490 i = BKE_sequencer_give_ibuf_seqbase(context, cfra, seq->machine - 1, seqbasep);
2493 /* found nothing? so let's work the way up the metastrip stack, so
2494 * that it is possible to group a bunch of adjustment strips into
2495 * a metastrip and have that work on everything below the metastrip
2501 meta = BKE_sequence_metastrip(&ed->seqbase, NULL, seq);
2504 i = do_adjustment_impl(context, meta, cfra);
2511 static ImBuf *do_adjustment(SeqRenderData context, Sequence *seq, float cfra, float UNUSED(facf0), float UNUSED(facf1),
2512 ImBuf *UNUSED(ibuf1), ImBuf *UNUSED(ibuf2), ImBuf *UNUSED(ibuf3))
2518 ed = context.scene->ed;
2524 i = do_adjustment_impl(context, seq, cfra);
2526 if (BKE_sequencer_input_have_to_preprocess(context, seq, cfra)) {
2527 out = IMB_dupImBuf(i);
2537 /*********************** Speed *************************/
2539 static void init_speed_effect(Sequence *seq)
2541 SpeedControlVars *v;
2543 if (seq->effectdata)
2544 MEM_freeN(seq->effectdata);
2546 seq->effectdata = MEM_callocN(sizeof(SpeedControlVars), "speedcontrolvars");
2548 v = (SpeedControlVars *)seq->effectdata;
2549 v->globalSpeed = 1.0;
2551 v->flags |= SEQ_SPEED_INTEGRATE; /* should be default behavior */
2555 static void load_speed_effect(Sequence *seq)
2557 SpeedControlVars *v = (SpeedControlVars *)seq->effectdata;
2563 static int num_inputs_speed(void)
2568 static void free_speed_effect(Sequence *seq)
2570 SpeedControlVars *v = (SpeedControlVars *)seq->effectdata;
2572 MEM_freeN(v->frameMap);
2573 if (seq->effectdata)
2574 MEM_freeN(seq->effectdata);
2575 seq->effectdata = NULL;
2578 static void copy_speed_effect(Sequence *dst, Sequence *src)
2580 SpeedControlVars *v;
2581 dst->effectdata = MEM_dupallocN(src->effectdata);
2582 v = (SpeedControlVars *)dst->effectdata;
2587 static int early_out_speed(Sequence *UNUSED(seq), float UNUSED(facf0), float UNUSED(facf1))
2589 return EARLY_USE_INPUT_1;
2592 static void store_icu_yrange_speed(Sequence *seq, short UNUSED(adrcode), float *ymin, float *ymax)
2594 SpeedControlVars *v = (SpeedControlVars *)seq->effectdata;
2596 /* if not already done, load / initialize data */
2597 BKE_sequence_get_effect(seq);
2599 if ((v->flags & SEQ_SPEED_INTEGRATE) != 0) {
2604 if (v->flags & SEQ_SPEED_COMPRESS_IPO_Y) {
2615 void BKE_sequence_effect_speed_rebuild_map(Scene *scene, Sequence *seq, int force)
2618 float fallback_fac = 1.0f;
2619 SpeedControlVars *v = (SpeedControlVars *) seq->effectdata;
2621 int flags = v->flags;
2623 /* if not already done, load / initialize data */
2624 BKE_sequence_get_effect(seq);
2626 if ((force == FALSE) &&
2627 (seq->len == v->length) &&
2628 (v->frameMap != NULL))
2632 if ((seq->seq1 == NULL) || (seq->len < 1)) {
2633 /* make coverity happy and check for (CID 598) input strip ... */
2637 /* XXX - new in 2.5x. should we use the animation system this way?
2638 * The fcurve is needed because many frames need evaluating at once - campbell */
2639 fcu = id_data_find_fcurve(&scene->id, seq, &RNA_Sequence, "speed_factor", 0, NULL);
2642 if (!v->frameMap || v->length != seq->len) {
2643 if (v->frameMap) MEM_freeN(v->frameMap);
2645 v->length = seq->len;
2647 v->frameMap = MEM_callocN(sizeof(float) * v->length, "speedcontrol frameMap");
2652 if (seq->flag & SEQ_USE_EFFECT_DEFAULT_FADE) {
2653 if ((seq->seq1->enddisp != seq->seq1->start) &&
2654 (seq->seq1->len != 0))
2656 fallback_fac = (float) seq->seq1->len / (float) (seq->seq1->enddisp - seq->seq1->start);
2657 flags = SEQ_SPEED_INTEGRATE;
2662 /* if there is no fcurve, use value as simple multiplier */
2664 fallback_fac = seq->speed_fader; /* same as speed_factor in rna*/
2668 if (flags & SEQ_SPEED_INTEGRATE) {
2673 v->lastValidFrame = 0;
2675 for (cfra = 1; cfra < v->length; cfra++) {
2677 facf = evaluate_fcurve(fcu, seq->startdisp + cfra);
2680 facf = fallback_fac;
2682 facf *= v->globalSpeed;
2686 if (cursor >= seq->seq1->len) {
2687 v->frameMap[cfra] = seq->seq1->len - 1;
2690 v->frameMap[cfra] = cursor;
2691 v->lastValidFrame = cfra;
2698 v->lastValidFrame = 0;
2699 for (cfra = 0; cfra < v->length; cfra++) {
2702 facf = evaluate_fcurve(fcu, seq->startdisp + cfra);
2705 facf = fallback_fac;
2708 if (flags & SEQ_SPEED_COMPRESS_IPO_Y) {
2709 facf *= seq->seq1->len;
2711 facf *= v->globalSpeed;
2713 if (facf >= seq->seq1->len) {
2714 facf = seq->seq1->len - 1;
2717 v->lastValidFrame = cfra;
2719 v->frameMap[cfra] = facf;
2724 static ImBuf *do_speed_effect(SeqRenderData context, Sequence *UNUSED(seq), float UNUSED(cfra),
2725 float facf0, float facf1, ImBuf *ibuf1, ImBuf *ibuf2, ImBuf *ibuf3)
2727 ImBuf *out = prepare_effect_imbufs(context, ibuf1, ibuf2, ibuf3);
2729 if (out->rect_float) {
2730 do_cross_effect_float(facf0, facf1, context.rectx, context.recty,
2731 ibuf1->rect_float, ibuf2->rect_float, out->rect_float);
2734 do_cross_effect_byte(facf0, facf1, context.rectx, context.recty,
2735 (char *) ibuf1->rect, (char *) ibuf2->rect, (char *) out->rect);
2740 /*********************** overdrop *************************/
2742 static void do_overdrop_effect(SeqRenderData context, Sequence *UNUSED(seq), float UNUSED(cfra), float facf0, float facf1,
2743 ImBuf *ibuf1, ImBuf *ibuf2, ImBuf *UNUSED(ibuf3), int start_line, int total_lines, ImBuf *out)
2745 int x = context.rectx;
2746 int y = total_lines;
2748 if (out->rect_float) {
2749 float *rect1, *rect2, *rect_out;
2751 slize_get_float_buffers(&context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
2753 do_drop_effect_float(facf0, facf1, x, y, rect1, rect2, rect_out);
2754 do_alphaover_effect_float(facf0, facf1, x, y, rect1, rect2, rect_out);
2757 unsigned char *rect1, *rect2, *rect_out;
2759 slize_get_byte_buffers(&context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
2761 do_drop_effect_byte(facf0, facf1, x, y, (char *) rect1, (char *) rect2, (char *) rect_out);
2762 do_alphaover_effect_byte(facf0, facf1, x, y, (char *) rect1, (char *) rect2, (char *) rect_out);
2766 /*********************** sequence effect factory *************************/
2768 static void init_noop(Sequence *UNUSED(seq))
2773 static void load_noop(Sequence *UNUSED(seq))
2778 static void free_noop(Sequence *UNUSED(seq))
2783 static int num_inputs_default(void)
2788 static int early_out_noop(Sequence *UNUSED(seq), float UNUSED(facf0), float UNUSED(facf1))
2790 return EARLY_DO_EFFECT;
2793 static int early_out_fade(Sequence *UNUSED(seq), float facf0, float facf1)
2795 if (facf0 == 0.0f && facf1 == 0.0f) {
2796 return EARLY_USE_INPUT_1;
2798 else if (facf0 == 1.0f && facf1 == 1.0f) {
2799 return EARLY_USE_INPUT_2;
2801 return EARLY_DO_EFFECT;
2804 static int early_out_mul_input2(Sequence *UNUSED(seq), float facf0, float facf1)
2806 if (facf0 == 0.0f && facf1 == 0.0f) {
2807 return EARLY_USE_INPUT_1;
2809 return EARLY_DO_EFFECT;
2812 static void store_icu_yrange_noop(Sequence *UNUSED(seq), short UNUSED(adrcode), float *UNUSED(ymin), float *UNUSED(ymax))
2814 /* defaults are fine */
2817 static void get_default_fac_noop(Sequence *UNUSED(seq), float UNUSED(cfra), float *facf0, float *facf1)
2819 *facf0 = *facf1 = 1.0;
2822 static void get_default_fac_fade(Sequence *seq, float cfra, float *facf0, float *facf1)
2824 *facf0 = (float)(cfra - seq->startdisp);
2825 *facf1 = (float)(*facf0 + 0.5f);
2830 static struct ImBuf *init_execution(SeqRenderData context, ImBuf *ibuf1, ImBuf *ibuf2, ImBuf *ibuf3)
2832 ImBuf *out = prepare_effect_imbufs(context, ibuf1, ibuf2, ibuf3);
2837 static struct SeqEffectHandle get_sequence_effect_impl(int seq_type)
2839 struct SeqEffectHandle rval;
2840 int sequence_type = seq_type;
2842 rval.multithreaded = FALSE;
2843 rval.init = init_noop;
2844 rval.num_inputs = num_inputs_default;
2845 rval.load = load_noop;
2846 rval.free = free_noop;
2847 rval.early_out = early_out_noop;
2848 rval.get_default_fac = get_default_fac_noop;
2849 rval.store_icu_yrange = store_icu_yrange_noop;
2850 rval.execute = NULL;
2851 rval.init_execution = init_execution;
2852 rval.execute_slice = NULL;
2855 switch (sequence_type) {
2856 case SEQ_TYPE_CROSS:
2857 rval.multithreaded = TRUE;
2858 rval.execute_slice = do_cross_effect;
2859 rval.early_out = early_out_fade;
2860 rval.get_default_fac = get_default_fac_fade;
2862 case SEQ_TYPE_GAMCROSS:
2863 rval.multithreaded = TRUE;
2864 rval.init = init_gammacross;
2865 rval.load = load_gammacross;
2866 rval.free = free_gammacross;
2867 rval.early_out = early_out_fade;
2868 rval.get_default_fac = get_default_fac_fade;
2869 rval.init_execution = gammacross_init_execution;
2870 rval.execute_slice = do_gammacross_effect;
2873 rval.multithreaded = TRUE;
2874 rval.execute_slice = do_add_effect;
2875 rval.early_out = early_out_mul_input2;
2878 rval.multithreaded = TRUE;
2879 rval.execute_slice = do_sub_effect;
2880 rval.early_out = early_out_mul_input2;
2883 rval.multithreaded = TRUE;
2884 rval.execute_slice = do_mul_effect;
2885 rval.early_out = early_out_mul_input2;
2887 case SEQ_TYPE_ALPHAOVER:
2888 rval.multithreaded = TRUE;
2889 rval.init = init_alpha_over_or_under;
2890 rval.execute_slice = do_alphaover_effect;
2892 case SEQ_TYPE_OVERDROP:
2893 rval.multithreaded = TRUE;
2894 rval.execute_slice = do_overdrop_effect;
2896 case SEQ_TYPE_ALPHAUNDER:
2897 rval.multithreaded = TRUE;
2898 rval.init = init_alpha_over_or_under;
2899 rval.execute_slice = do_alphaunder_effect;
2902 rval.init = init_wipe_effect;
2903 rval.num_inputs = num_inputs_wipe;
2904 rval.free = free_wipe_effect;
2905 rval.copy = copy_wipe_effect;
2906 rval.early_out = early_out_fade;
2907 rval.get_default_fac = get_default_fac_fade;
2908 rval.execute = do_wipe_effect;
2911 rval.init = init_glow_effect;
2912 rval.num_inputs = num_inputs_glow;
2913 rval.free = free_glow_effect;
2914 rval.copy = copy_glow_effect;
2915 rval.execute = do_glow_effect;
2917 case SEQ_TYPE_TRANSFORM:
2918 rval.init = init_transform_effect;
2919 rval.num_inputs = num_inputs_transform;
2920 rval.free = free_transform_effect;
2921 rval.copy = copy_transform_effect;
2922 rval.execute = do_transform_effect;
2924 case SEQ_TYPE_SPEED:
2925 rval.init = init_speed_effect;
2926 rval.num_inputs = num_inputs_speed;
2927 rval.load = load_speed_effect;
2928 rval.free = free_speed_effect;
2929 rval.copy = copy_speed_effect;
2930 rval.execute = do_speed_effect;
2931 rval.early_out = early_out_speed;
2932 rval.store_icu_yrange = store_icu_yrange_speed;
2934 case SEQ_TYPE_COLOR:
2935 rval.init = init_solid_color;
2936 rval.num_inputs = num_inputs_color;
2937 rval.early_out = early_out_color;
2938 rval.free = free_solid_color;
2939 rval.copy = copy_solid_color;
2940 rval.execute = do_solid_color;
2942 case SEQ_TYPE_MULTICAM:
2943 rval.num_inputs = num_inputs_multicam;
2944 rval.early_out = early_out_multicam;
2945 rval.execute = do_multicam;
2947 case SEQ_TYPE_ADJUSTMENT:
2948 rval.num_inputs = num_inputs_adjustment;
2949 rval.early_out = early_out_adjustment;
2950 rval.execute = do_adjustment;
2957 struct SeqEffectHandle BKE_sequence_get_effect(Sequence *seq)
2959 struct SeqEffectHandle rval = {FALSE, NULL};
2961 if (seq->type & SEQ_TYPE_EFFECT) {
2962 rval = get_sequence_effect_impl(seq->type);
2963 if ((seq->flag & SEQ_EFFECT_NOT_LOADED) != 0) {
2965 seq->flag &= ~SEQ_EFFECT_NOT_LOADED;
2972 struct SeqEffectHandle BKE_sequence_get_blend(Sequence *seq)
2974 struct SeqEffectHandle rval = {FALSE, NULL};
2976 if (seq->blend_mode != 0) {
2977 rval = get_sequence_effect_impl(seq->blend_mode);
2978 if ((seq->flag & SEQ_EFFECT_NOT_LOADED) != 0) {
2980 seq->flag &= ~SEQ_EFFECT_NOT_LOADED;
2987 int BKE_sequence_effect_get_num_inputs(int seq_type)
2989 struct SeqEffectHandle rval = get_sequence_effect_impl(seq_type);
2991 int cnt = rval.num_inputs();
2992 if (rval.execute || (rval.execute_slice && rval.init_execution)) {