4 * ***** BEGIN GPL LICENSE BLOCK *****
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software Foundation,
18 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
21 * All rights reserved.
24 * - Blender Foundation, 2003-2009
25 * - Peter Schlaile <peter [at] schlaile [dot] de> 2005/2006
27 * ***** END GPL LICENSE BLOCK *****
34 #include "MEM_guardedalloc.h"
35 #include "PIL_dynlib.h"
37 #include "DNA_scene_types.h"
38 #include "DNA_sequence_types.h"
39 #include "DNA_anim_types.h"
41 #include "BLI_blenlib.h"
44 #include "BKE_global.h"
45 #include "BKE_fcurve.h"
46 #include "BKE_plugin_types.h"
47 #include "BKE_sequence.h"
48 #include "BKE_texture.h"
49 #include "BKE_utildefines.h"
51 #include "IMB_imbuf_types.h"
52 #include "IMB_imbuf.h"
54 #include "RNA_access.h"
57 static void error() {}
73 /* **********************************************************************
75 ********************************************************************** */
77 static void open_plugin_seq(PluginSeq *pis, const char *seqname)
80 void* (*alloc_private)();
83 /* to be sure: (is tested for) */
89 pis->instance_private_data = 0;
91 /* clear the error list */
92 PIL_dynlib_get_error_as_string(NULL);
94 /* if(pis->handle) PIL_dynlib_close(pis->handle); */
97 /* open the needed object */
98 pis->handle= PIL_dynlib_open(pis->name);
99 if(test_dlerr(pis->name, pis->name)) return;
101 if (pis->handle != 0) {
102 /* find the address of the version function */
103 version= (int (*)())PIL_dynlib_find_symbol(pis->handle, "plugin_seq_getversion");
104 if (test_dlerr(pis->name, "plugin_seq_getversion")) return;
107 pis->version= version();
108 if (pis->version >= 2 && pis->version <= 6) {
109 int (*info_func)(PluginInfo *);
110 PluginInfo *info= (PluginInfo*) MEM_mallocN(sizeof(PluginInfo), "plugin_info");
112 info_func= (int (*)(PluginInfo *))PIL_dynlib_find_symbol(pis->handle, "plugin_getinfo");
114 if(info_func == NULL) error("No info func");
118 pis->pname= info->name;
119 pis->vars= info->nvars;
120 pis->cfra= info->cfra;
122 pis->varstr= info->varstr;
124 pis->doit= (void(*)(void))info->seq_doit;
130 cp= PIL_dynlib_find_symbol(pis->handle, "seqname");
131 if(cp) strncpy(cp, seqname, 21);
133 printf ("Plugin returned unrecognized version number\n");
137 alloc_private = (void* (*)())PIL_dynlib_find_symbol(
138 pis->handle, "plugin_seq_alloc_private_data");
140 pis->instance_private_data = alloc_private();
143 pis->current_private_data = (void**)
144 PIL_dynlib_find_symbol(
145 pis->handle, "plugin_private_data");
149 static PluginSeq *add_plugin_seq(const char *str, const char *seqname)
155 pis= MEM_callocN(sizeof(PluginSeq), "PluginSeq");
157 strncpy(pis->name, str, FILE_MAXDIR+FILE_MAXFILE);
158 open_plugin_seq(pis, seqname);
161 if(pis->handle==0) error("no plugin: %s", str);
162 else error("in plugin: %s", str);
169 for(a=0; a<pis->vars; a++, varstr++) {
170 if( (varstr->type & FLO)==FLO)
171 pis->data[a]= varstr->def;
172 else if( (varstr->type & INT)==INT)
173 *((int *)(pis->data+a))= (int) varstr->def;
179 static void free_plugin_seq(PluginSeq *pis)
183 /* no PIL_dynlib_close: same plugin can be opened multiple times with 1 handle */
185 if (pis->instance_private_data) {
186 void (*free_private)(void *);
188 free_private = (void (*)(void *))PIL_dynlib_find_symbol(
189 pis->handle, "plugin_seq_free_private_data");
191 free_private(pis->instance_private_data);
198 static void init_plugin(Sequence * seq, const char * fname)
200 seq->plugin= (PluginSeq *)add_plugin_seq(fname, seq->name+2);
204 * FIXME: should query plugin! Could be generator, that needs zero inputs...
206 static int num_inputs_plugin()
211 static void load_plugin(Sequence * seq)
214 open_plugin_seq(seq->plugin, seq->name+2);
218 static void copy_plugin(Sequence * dst, Sequence * src)
221 dst->plugin= MEM_dupallocN(src->plugin);
222 open_plugin_seq(dst->plugin, dst->name+2);
226 static ImBuf * IMB_cast_away_list(ImBuf * i)
231 return (ImBuf*) (((void**) i) + 2);
234 static void do_plugin_effect(Sequence * seq,int cfra,
235 float facf0, float facf1, int x, int y,
236 struct ImBuf *ibuf1, struct ImBuf *ibuf2,
237 struct ImBuf *ibuf3, struct ImBuf *out)
241 int use_temp_bufs = 0; /* Are needed since blur.c (and maybe some other
242 old plugins) do very bad stuff
243 with imbuf-internals */
245 if(seq->plugin && seq->plugin->doit) {
247 if(seq->plugin->cfra)
248 *(seq->plugin->cfra)= cfra;
250 cp = PIL_dynlib_find_symbol(
251 seq->plugin->handle, "seqname");
253 if(cp) strncpy(cp, seq->name+2, 22);
255 if (seq->plugin->current_private_data) {
256 *seq->plugin->current_private_data
257 = seq->plugin->instance_private_data;
260 float_rendering = (out->rect_float != NULL);
262 if (seq->plugin->version<=3 && float_rendering) {
266 ibuf1 = IMB_dupImBuf(ibuf1);
267 IMB_rect_from_float(ibuf1);
268 imb_freerectfloatImBuf(ibuf1);
269 ibuf1->flags &= ~IB_rectfloat;
272 ibuf2 = IMB_dupImBuf(ibuf2);
273 IMB_rect_from_float(ibuf2);
274 imb_freerectfloatImBuf(ibuf2);
275 ibuf2->flags &= ~IB_rectfloat;
278 ibuf3 = IMB_dupImBuf(ibuf3);
279 IMB_rect_from_float(ibuf3);
280 imb_freerectfloatImBuf(ibuf3);
281 ibuf3->flags &= ~IB_rectfloat;
283 if (!out->rect) imb_addrectImBuf(out);
284 imb_freerectfloatImBuf(out);
285 out->flags &= ~IB_rectfloat;
288 if (seq->plugin->version<=2) {
289 if(ibuf1) IMB_convert_rgba_to_abgr(ibuf1);
290 if(ibuf2) IMB_convert_rgba_to_abgr(ibuf2);
291 if(ibuf3) IMB_convert_rgba_to_abgr(ibuf3);
294 if (seq->plugin->version<=4) {
295 ((SeqDoit)seq->plugin->doit)(
296 seq->plugin->data, facf0, facf1, x, y,
297 IMB_cast_away_list(ibuf1),
298 IMB_cast_away_list(ibuf2),
299 IMB_cast_away_list(out),
300 IMB_cast_away_list(ibuf3));
302 ((SeqDoit)seq->plugin->doit)(
303 seq->plugin->data, facf0, facf1, x, y,
304 ibuf1, ibuf2, out, ibuf3);
307 if (seq->plugin->version<=2) {
308 if (!use_temp_bufs) {
309 if(ibuf1) IMB_convert_rgba_to_abgr(ibuf1);
310 if(ibuf2) IMB_convert_rgba_to_abgr(ibuf2);
311 if(ibuf3) IMB_convert_rgba_to_abgr(ibuf3);
313 IMB_convert_rgba_to_abgr(out);
315 if (seq->plugin->version<=3 && float_rendering) {
316 IMB_float_from_rect(out);
320 if (ibuf1) IMB_freeImBuf(ibuf1);
321 if (ibuf2) IMB_freeImBuf(ibuf2);
322 if (ibuf3) IMB_freeImBuf(ibuf3);
327 static int do_plugin_early_out(struct Sequence *seq,
328 float facf0, float facf1)
333 static void free_plugin(struct Sequence * seq)
335 free_plugin_seq(seq->plugin);
339 /* **********************************************************************
341 ********************************************************************** */
343 static void init_alpha_over_or_under(Sequence * seq)
345 Sequence * seq1 = seq->seq1;
346 Sequence * seq2 = seq->seq2;
352 static void do_alphaover_effect_byte(float facf0, float facf1, int x, int y,
353 char * rect1, char *rect2, char *out)
355 int fac2, mfac, fac, fac4;
357 char *rt1, *rt2, *rt;
364 fac2= (int)(256.0*facf0);
365 fac4= (int)(256.0*facf1);
372 /* rt = rt1 over rt2 (alpha from rt1) */
375 mfac= 256 - ( (fac2*rt1[3])>>8 );
377 if(fac==0) *( (unsigned int *)rt) = *( (unsigned int *)rt2);
378 else if(mfac==0) *( (unsigned int *)rt) = *( (unsigned int *)rt1);
380 tempc= ( fac*rt1[0] + mfac*rt2[0])>>8;
381 if(tempc>255) rt[0]= 255; else rt[0]= tempc;
382 tempc= ( fac*rt1[1] + mfac*rt2[1])>>8;
383 if(tempc>255) rt[1]= 255; else rt[1]= tempc;
384 tempc= ( fac*rt1[2] + mfac*rt2[2])>>8;
385 if(tempc>255) rt[2]= 255; else rt[2]= tempc;
386 tempc= ( fac*rt1[3] + mfac*rt2[3])>>8;
387 if(tempc>255) rt[3]= 255; else rt[3]= tempc;
389 rt1+= 4; rt2+= 4; rt+= 4;
399 mfac= 256 - ( (fac4*rt1[3])>>8 );
401 if(fac==0) *( (unsigned int *)rt) = *( (unsigned int *)rt2);
402 else if(mfac==0) *( (unsigned int *)rt) = *( (unsigned int *)rt1);
404 tempc= ( fac*rt1[0] + mfac*rt2[0])>>8;
405 if(tempc>255) rt[0]= 255; else rt[0]= tempc;
406 tempc= ( fac*rt1[1] + mfac*rt2[1])>>8;
407 if(tempc>255) rt[1]= 255; else rt[1]= tempc;
408 tempc= ( fac*rt1[2] + mfac*rt2[2])>>8;
409 if(tempc>255) rt[2]= 255; else rt[2]= tempc;
410 tempc= ( fac*rt1[3] + mfac*rt2[3])>>8;
411 if(tempc>255) rt[3]= 255; else rt[3]= tempc;
413 rt1+= 4; rt2+= 4; rt+= 4;
418 static void do_alphaover_effect_float(float facf0, float facf1, int x, int y,
419 float * rect1, float *rect2, float *out)
421 float fac2, mfac, fac, fac4;
423 float *rt1, *rt2, *rt;
438 /* rt = rt1 over rt2 (alpha from rt1) */
441 mfac= 1.0 - (fac2*rt1[3]) ;
444 memcpy(rt, rt2, 4 * sizeof(float));
445 } else if(mfac <=0) {
446 memcpy(rt, rt1, 4 * sizeof(float));
448 rt[0] = fac*rt1[0] + mfac*rt2[0];
449 rt[1] = fac*rt1[1] + mfac*rt2[1];
450 rt[2] = fac*rt1[2] + mfac*rt2[2];
451 rt[3] = fac*rt1[3] + mfac*rt2[3];
453 rt1+= 4; rt2+= 4; rt+= 4;
463 mfac= 1.0 - (fac4*rt1[3]);
466 memcpy(rt, rt2, 4 * sizeof(float));
467 } else if(mfac <= 0.0) {
468 memcpy(rt, rt1, 4 * sizeof(float));
470 rt[0] = fac*rt1[0] + mfac*rt2[0];
471 rt[1] = fac*rt1[1] + mfac*rt2[1];
472 rt[2] = fac*rt1[2] + mfac*rt2[2];
473 rt[3] = fac*rt1[3] + mfac*rt2[3];
475 rt1+= 4; rt2+= 4; rt+= 4;
480 static void do_alphaover_effect(Sequence * seq,int cfra,
481 float facf0, float facf1, int x, int y,
482 struct ImBuf *ibuf1, struct ImBuf *ibuf2,
483 struct ImBuf *ibuf3, struct ImBuf *out)
485 if (out->rect_float) {
486 do_alphaover_effect_float(
488 ibuf1->rect_float, ibuf2->rect_float,
491 do_alphaover_effect_byte(
493 (char*) ibuf1->rect, (char*) ibuf2->rect,
499 /* **********************************************************************
501 ********************************************************************** */
503 void do_alphaunder_effect_byte(
504 float facf0, float facf1, int x, int y, char *rect1,
505 char *rect2, char *out)
507 int fac2, mfac, fac, fac4;
509 char *rt1, *rt2, *rt;
516 fac2= (int)(256.0*facf0);
517 fac4= (int)(256.0*facf1);
524 /* rt = rt1 under rt2 (alpha from rt2) */
526 /* this complex optimalisation is because the
527 * 'skybuf' can be crossed in
529 if(rt2[3]==0 && fac2==256) *( (unsigned int *)rt) = *( (unsigned int *)rt1);
530 else if(rt2[3]==255) *( (unsigned int *)rt) = *( (unsigned int *)rt2);
533 fac= (fac2*(256-mfac))>>8;
535 if(fac==0) *( (unsigned int *)rt) = *( (unsigned int *)rt2);
537 rt[0]= ( fac*rt1[0] + mfac*rt2[0])>>8;
538 rt[1]= ( fac*rt1[1] + mfac*rt2[1])>>8;
539 rt[2]= ( fac*rt1[2] + mfac*rt2[2])>>8;
540 rt[3]= ( fac*rt1[3] + mfac*rt2[3])>>8;
543 rt1+= 4; rt2+= 4; rt+= 4;
552 if(rt2[3]==0 && fac4==256) *( (unsigned int *)rt) = *( (unsigned int *)rt1);
553 else if(rt2[3]==255) *( (unsigned int *)rt) = *( (unsigned int *)rt2);
556 fac= (fac4*(256-mfac))>>8;
558 if(fac==0) *( (unsigned int *)rt) = *( (unsigned int *)rt2);
560 rt[0]= ( fac*rt1[0] + mfac*rt2[0])>>8;
561 rt[1]= ( fac*rt1[1] + mfac*rt2[1])>>8;
562 rt[2]= ( fac*rt1[2] + mfac*rt2[2])>>8;
563 rt[3]= ( fac*rt1[3] + mfac*rt2[3])>>8;
566 rt1+= 4; rt2+= 4; rt+= 4;
572 static void do_alphaunder_effect_float(float facf0, float facf1, int x, int y,
573 float *rect1, float *rect2,
576 float fac2, mfac, fac, fac4;
578 float *rt1, *rt2, *rt;
593 /* rt = rt1 under rt2 (alpha from rt2) */
595 /* this complex optimalisation is because the
596 * 'skybuf' can be crossed in
598 if( rt2[3]<=0 && fac2>=1.0) {
599 memcpy(rt, rt1, 4 * sizeof(float));
600 } else if(rt2[3]>=1.0) {
601 memcpy(rt, rt2, 4 * sizeof(float));
604 fac = fac2 * (1.0 - mfac);
607 memcpy(rt, rt2, 4 * sizeof(float));
609 rt[0]= fac*rt1[0] + mfac*rt2[0];
610 rt[1]= fac*rt1[1] + mfac*rt2[1];
611 rt[2]= fac*rt1[2] + mfac*rt2[2];
612 rt[3]= fac*rt1[3] + mfac*rt2[3];
615 rt1+= 4; rt2+= 4; rt+= 4;
624 if(rt2[3]<=0 && fac4 >= 1.0) {
625 memcpy(rt, rt1, 4 * sizeof(float));
627 } else if(rt2[3]>=1.0) {
628 memcpy(rt, rt2, 4 * sizeof(float));
631 fac= fac4*(1.0-mfac);
634 memcpy(rt, rt2, 4 * sizeof(float));
636 rt[0]= fac * rt1[0] + mfac * rt2[0];
637 rt[1]= fac * rt1[1] + mfac * rt2[1];
638 rt[2]= fac * rt1[2] + mfac * rt2[2];
639 rt[3]= fac * rt1[3] + mfac * rt2[3];
642 rt1+= 4; rt2+= 4; rt+= 4;
647 static void do_alphaunder_effect(Sequence * seq,int cfra,
648 float facf0, float facf1, int x, int y,
649 struct ImBuf *ibuf1, struct ImBuf *ibuf2,
650 struct ImBuf *ibuf3, struct ImBuf *out)
652 if (out->rect_float) {
653 do_alphaunder_effect_float(
655 ibuf1->rect_float, ibuf2->rect_float,
658 do_alphaunder_effect_byte(
660 (char*) ibuf1->rect, (char*) ibuf2->rect,
666 /* **********************************************************************
668 ********************************************************************** */
670 void do_cross_effect_byte(float facf0, float facf1, int x, int y,
671 char *rect1, char *rect2,
674 int fac1, fac2, fac3, fac4;
676 char *rt1, *rt2, *rt;
683 fac2= (int)(256.0*facf0);
685 fac4= (int)(256.0*facf1);
693 rt[0]= (fac1*rt1[0] + fac2*rt2[0])>>8;
694 rt[1]= (fac1*rt1[1] + fac2*rt2[1])>>8;
695 rt[2]= (fac1*rt1[2] + fac2*rt2[2])>>8;
696 rt[3]= (fac1*rt1[3] + fac2*rt2[3])>>8;
698 rt1+= 4; rt2+= 4; rt+= 4;
707 rt[0]= (fac3*rt1[0] + fac4*rt2[0])>>8;
708 rt[1]= (fac3*rt1[1] + fac4*rt2[1])>>8;
709 rt[2]= (fac3*rt1[2] + fac4*rt2[2])>>8;
710 rt[3]= (fac3*rt1[3] + fac4*rt2[3])>>8;
712 rt1+= 4; rt2+= 4; rt+= 4;
718 void do_cross_effect_float(float facf0, float facf1, int x, int y,
719 float *rect1, float *rect2, float *out)
721 float fac1, fac2, fac3, fac4;
723 float *rt1, *rt2, *rt;
740 rt[0]= fac1*rt1[0] + fac2*rt2[0];
741 rt[1]= fac1*rt1[1] + fac2*rt2[1];
742 rt[2]= fac1*rt1[2] + fac2*rt2[2];
743 rt[3]= fac1*rt1[3] + fac2*rt2[3];
745 rt1+= 4; rt2+= 4; rt+= 4;
754 rt[0]= fac3*rt1[0] + fac4*rt2[0];
755 rt[1]= fac3*rt1[1] + fac4*rt2[1];
756 rt[2]= fac3*rt1[2] + fac4*rt2[2];
757 rt[3]= fac3*rt1[3] + fac4*rt2[3];
759 rt1+= 4; rt2+= 4; rt+= 4;
765 /* carefull: also used by speed effect! */
767 static void do_cross_effect(Sequence * seq,int cfra,
768 float facf0, float facf1, int x, int y,
769 struct ImBuf *ibuf1, struct ImBuf *ibuf2,
770 struct ImBuf *ibuf3, struct ImBuf *out)
772 if (out->rect_float) {
773 do_cross_effect_float(
775 ibuf1->rect_float, ibuf2->rect_float,
778 do_cross_effect_byte(
780 (char*) ibuf1->rect, (char*) ibuf2->rect,
786 /* **********************************************************************
788 ********************************************************************** */
790 /* copied code from initrender.c */
791 static unsigned short gamtab[65536];
792 static unsigned short igamtab1[256];
793 static int gamma_tabs_init = FALSE;
795 #define RE_GAMMA_TABLE_SIZE 400
797 static float gamma_range_table[RE_GAMMA_TABLE_SIZE + 1];
798 static float gamfactor_table[RE_GAMMA_TABLE_SIZE];
799 static float inv_gamma_range_table[RE_GAMMA_TABLE_SIZE + 1];
800 static float inv_gamfactor_table[RE_GAMMA_TABLE_SIZE];
801 static float color_domain_table[RE_GAMMA_TABLE_SIZE + 1];
802 static float color_step;
803 static float inv_color_step;
804 static float valid_gamma;
805 static float valid_inv_gamma;
807 static void makeGammaTables(float gamma)
809 /* we need two tables: one forward, one backward */
813 valid_inv_gamma = 1.0 / gamma;
814 color_step = 1.0 / RE_GAMMA_TABLE_SIZE;
815 inv_color_step = (float) RE_GAMMA_TABLE_SIZE;
817 /* We could squeeze out the two range tables to gain some memory. */
818 for (i = 0; i < RE_GAMMA_TABLE_SIZE; i++) {
819 color_domain_table[i] = i * color_step;
820 gamma_range_table[i] = pow(color_domain_table[i],
822 inv_gamma_range_table[i] = pow(color_domain_table[i],
826 /* The end of the table should match 1.0 carefully. In order to avoid */
827 /* rounding errors, we just set this explicitly. The last segment may */
828 /* have a different lenght than the other segments, but our */
829 /* interpolation is insensitive to that. */
830 color_domain_table[RE_GAMMA_TABLE_SIZE] = 1.0;
831 gamma_range_table[RE_GAMMA_TABLE_SIZE] = 1.0;
832 inv_gamma_range_table[RE_GAMMA_TABLE_SIZE] = 1.0;
834 /* To speed up calculations, we make these calc factor tables. They are */
835 /* multiplication factors used in scaling the interpolation. */
836 for (i = 0; i < RE_GAMMA_TABLE_SIZE; i++ ) {
837 gamfactor_table[i] = inv_color_step
838 * (gamma_range_table[i + 1] - gamma_range_table[i]) ;
839 inv_gamfactor_table[i] = inv_color_step
840 * (inv_gamma_range_table[i + 1] - inv_gamma_range_table[i]) ;
843 } /* end of void makeGammaTables(float gamma) */
846 static float gammaCorrect(float c)
851 i = floor(c * inv_color_step);
852 /* Clip to range [0,1]: outside, just do the complete calculation. */
853 /* We may have some performance problems here. Stretching up the LUT */
854 /* may help solve that, by exchanging LUT size for the interpolation. */
855 /* Negative colors are explicitly handled. */
856 if (i < 0) res = -pow(abs(c), valid_gamma);
857 else if (i >= RE_GAMMA_TABLE_SIZE ) res = pow(c, valid_gamma);
858 else res = gamma_range_table[i] +
859 ( (c - color_domain_table[i]) * gamfactor_table[i]);
862 } /* end of float gammaCorrect(float col) */
864 /* ------------------------------------------------------------------------- */
866 static float invGammaCorrect(float col)
871 i = floor(col*inv_color_step);
872 /* Negative colors are explicitly handled. */
873 if (i < 0) res = -pow(abs(col), valid_inv_gamma);
874 else if (i >= RE_GAMMA_TABLE_SIZE) res = pow(col, valid_inv_gamma);
875 else res = inv_gamma_range_table[i] +
876 ( (col - color_domain_table[i]) * inv_gamfactor_table[i]);
879 } /* end of float invGammaCorrect(float col) */
882 static void gamtabs(float gamma)
884 float val, igamma= 1.0f/gamma;
887 /* gamtab: in short, out short */
888 for(a=0; a<65536; a++) {
892 if(gamma==2.0) val= sqrt(val);
893 else if(gamma!=1.0) val= pow(val, igamma);
895 gamtab[a]= (65535.99*val);
897 /* inverse gamtab1 : in byte, out short */
898 for(a=1; a<=256; a++) {
899 if(gamma==2.0) igamtab1[a-1]= a*a-1;
900 else if(gamma==1.0) igamtab1[a-1]= 256*a-1;
903 igamtab1[a-1]= (65535.0*pow(val, gamma)) -1 ;
909 static void build_gammatabs()
911 if (gamma_tabs_init == FALSE) {
913 makeGammaTables(2.0f);
914 gamma_tabs_init = TRUE;
918 static void init_gammacross(Sequence * seq)
922 static void load_gammacross(Sequence * seq)
926 static void free_gammacross(Sequence * seq)
930 static void do_gammacross_effect_byte(float facf0, float facf1,
932 unsigned char *rect1,
933 unsigned char *rect2,
938 unsigned char *rt1, *rt2, *rt;
941 rt1= (unsigned char *)rect1;
942 rt2= (unsigned char *)rect2;
943 rt= (unsigned char *)out;
945 fac2= (int)(256.0*facf0);
953 col= (fac1*igamtab1[rt1[0]] + fac2*igamtab1[rt2[0]])>>8;
954 if(col>65535) rt[0]= 255; else rt[0]= ( (char *)(gamtab+col))[MOST_SIG_BYTE];
955 col=(fac1*igamtab1[rt1[1]] + fac2*igamtab1[rt2[1]])>>8;
956 if(col>65535) rt[1]= 255; else rt[1]= ( (char *)(gamtab+col))[MOST_SIG_BYTE];
957 col= (fac1*igamtab1[rt1[2]] + fac2*igamtab1[rt2[2]])>>8;
958 if(col>65535) rt[2]= 255; else rt[2]= ( (char *)(gamtab+col))[MOST_SIG_BYTE];
959 col= (fac1*igamtab1[rt1[3]] + fac2*igamtab1[rt2[3]])>>8;
960 if(col>65535) rt[3]= 255; else rt[3]= ( (char *)(gamtab+col))[MOST_SIG_BYTE];
962 rt1+= 4; rt2+= 4; rt+= 4;
971 col= (fac1*igamtab1[rt1[0]] + fac2*igamtab1[rt2[0]])>>8;
972 if(col>65535) rt[0]= 255; else rt[0]= ( (char *)(gamtab+col))[MOST_SIG_BYTE];
973 col= (fac1*igamtab1[rt1[1]] + fac2*igamtab1[rt2[1]])>>8;
974 if(col>65535) rt[1]= 255; else rt[1]= ( (char *)(gamtab+col))[MOST_SIG_BYTE];
975 col= (fac1*igamtab1[rt1[2]] + fac2*igamtab1[rt2[2]])>>8;
976 if(col>65535) rt[2]= 255; else rt[2]= ( (char *)(gamtab+col))[MOST_SIG_BYTE];
977 col= (fac1*igamtab1[rt1[3]] + fac2*igamtab1[rt2[3]])>>8;
978 if(col>65535) rt[3]= 255; else rt[3]= ( (char *)(gamtab+col))[MOST_SIG_BYTE];
980 rt1+= 4; rt2+= 4; rt+= 4;
986 static void do_gammacross_effect_float(float facf0, float facf1,
988 float *rect1, float *rect2,
993 float *rt1, *rt2, *rt;
1009 fac1 * invGammaCorrect(*rt1)
1010 + fac2 * invGammaCorrect(*rt2));
1021 fac1*invGammaCorrect(*rt1)
1022 + fac2*invGammaCorrect(*rt2));
1029 static void do_gammacross_effect(Sequence * seq,int cfra,
1030 float facf0, float facf1, int x, int y,
1031 struct ImBuf *ibuf1, struct ImBuf *ibuf2,
1032 struct ImBuf *ibuf3, struct ImBuf *out)
1036 if (out->rect_float) {
1037 do_gammacross_effect_float(
1039 ibuf1->rect_float, ibuf2->rect_float,
1042 do_gammacross_effect_byte(
1044 (unsigned char*) ibuf1->rect, (unsigned char*) ibuf2->rect,
1045 (unsigned char*) out->rect);
1050 /* **********************************************************************
1052 ********************************************************************** */
1054 static void do_add_effect_byte(float facf0, float facf1, int x, int y,
1055 unsigned char *rect1, unsigned char *rect2,
1058 int col, xo, fac1, fac3;
1059 char *rt1, *rt2, *rt;
1066 fac1= (int)(256.0*facf0);
1067 fac3= (int)(256.0*facf1);
1074 col= rt1[0]+ ((fac1*rt2[0])>>8);
1075 if(col>255) rt[0]= 255; else rt[0]= col;
1076 col= rt1[1]+ ((fac1*rt2[1])>>8);
1077 if(col>255) rt[1]= 255; else rt[1]= col;
1078 col= rt1[2]+ ((fac1*rt2[2])>>8);
1079 if(col>255) rt[2]= 255; else rt[2]= col;
1080 col= rt1[3]+ ((fac1*rt2[3])>>8);
1081 if(col>255) rt[3]= 255; else rt[3]= col;
1083 rt1+= 4; rt2+= 4; rt+= 4;
1092 col= rt1[0]+ ((fac3*rt2[0])>>8);
1093 if(col>255) rt[0]= 255; else rt[0]= col;
1094 col= rt1[1]+ ((fac3*rt2[1])>>8);
1095 if(col>255) rt[1]= 255; else rt[1]= col;
1096 col= rt1[2]+ ((fac3*rt2[2])>>8);
1097 if(col>255) rt[2]= 255; else rt[2]= col;
1098 col= rt1[3]+ ((fac3*rt2[3])>>8);
1099 if(col>255) rt[3]= 255; else rt[3]= col;
1101 rt1+= 4; rt2+= 4; rt+= 4;
1106 static void do_add_effect_float(float facf0, float facf1, int x, int y,
1107 float *rect1, float *rect2,
1112 float *rt1, *rt2, *rt;
1126 *rt = *rt1 + fac1 * (*rt2);
1136 *rt = *rt1 + fac3 * (*rt2);
1143 static void do_add_effect(Sequence * seq,int cfra,
1144 float facf0, float facf1, int x, int y,
1145 struct ImBuf *ibuf1, struct ImBuf *ibuf2,
1146 struct ImBuf *ibuf3, struct ImBuf *out)
1148 if (out->rect_float) {
1149 do_add_effect_float(
1151 ibuf1->rect_float, ibuf2->rect_float,
1156 (unsigned char*) ibuf1->rect, (unsigned char*) ibuf2->rect,
1157 (unsigned char*) out->rect);
1162 /* **********************************************************************
1164 ********************************************************************** */
1166 static void do_sub_effect_byte(float facf0, float facf1,
1168 char *rect1, char *rect2, char *out)
1170 int col, xo, fac1, fac3;
1171 char *rt1, *rt2, *rt;
1178 fac1= (int)(256.0*facf0);
1179 fac3= (int)(256.0*facf1);
1186 col= rt1[0]- ((fac1*rt2[0])>>8);
1187 if(col<0) rt[0]= 0; else rt[0]= col;
1188 col= rt1[1]- ((fac1*rt2[1])>>8);
1189 if(col<0) rt[1]= 0; else rt[1]= col;
1190 col= rt1[2]- ((fac1*rt2[2])>>8);
1191 if(col<0) rt[2]= 0; else rt[2]= col;
1192 col= rt1[3]- ((fac1*rt2[3])>>8);
1193 if(col<0) rt[3]= 0; else rt[3]= col;
1195 rt1+= 4; rt2+= 4; rt+= 4;
1204 col= rt1[0]- ((fac3*rt2[0])>>8);
1205 if(col<0) rt[0]= 0; else rt[0]= col;
1206 col= rt1[1]- ((fac3*rt2[1])>>8);
1207 if(col<0) rt[1]= 0; else rt[1]= col;
1208 col= rt1[2]- ((fac3*rt2[2])>>8);
1209 if(col<0) rt[2]= 0; else rt[2]= col;
1210 col= rt1[3]- ((fac3*rt2[3])>>8);
1211 if(col<0) rt[3]= 0; else rt[3]= col;
1213 rt1+= 4; rt2+= 4; rt+= 4;
1218 static void do_sub_effect_float(float facf0, float facf1, int x, int y,
1219 float *rect1, float *rect2,
1224 float *rt1, *rt2, *rt;
1238 *rt = *rt1 - fac1 * (*rt2);
1248 *rt = *rt1 - fac3 * (*rt2);
1255 static void do_sub_effect(Sequence * seq,int cfra,
1256 float facf0, float facf1, int x, int y,
1257 struct ImBuf *ibuf1, struct ImBuf *ibuf2,
1258 struct ImBuf *ibuf3, struct ImBuf *out)
1260 if (out->rect_float) {
1261 do_sub_effect_float(
1263 ibuf1->rect_float, ibuf2->rect_float,
1268 (char*) ibuf1->rect, (char*) ibuf2->rect,
1273 /* **********************************************************************
1275 ********************************************************************** */
1277 /* Must be > 0 or add precopy, etc to the function */
1281 static void do_drop_effect_byte(float facf0, float facf1, int x, int y,
1282 unsigned char *rect2i, unsigned char *rect1i,
1283 unsigned char *outi)
1285 int height, width, temp, fac, fac1, fac2;
1286 char *rt1, *rt2, *out;
1292 fac1= (int)(70.0*facf0);
1293 fac2= (int)(70.0*facf1);
1295 rt2= (char*) (rect2i + YOFF*width);
1296 rt1= (char*) rect1i;
1298 for (y=0; y<height-YOFF; y++) {
1299 if(field) fac= fac1;
1303 memcpy(out, rt1, sizeof(int)*XOFF);
1307 for (x=XOFF; x<width; x++) {
1308 temp= ((fac*rt2[3])>>8);
1310 *(out++)= MAX2(0, *rt1 - temp); rt1++;
1311 *(out++)= MAX2(0, *rt1 - temp); rt1++;
1312 *(out++)= MAX2(0, *rt1 - temp); rt1++;
1313 *(out++)= MAX2(0, *rt1 - temp); rt1++;
1318 memcpy(out, rt1, sizeof(int)*YOFF*width);
1321 static void do_drop_effect_float(float facf0, float facf1, int x, int y,
1322 float *rect2i, float *rect1i,
1326 float temp, fac, fac1, fac2;
1327 float *rt1, *rt2, *out;
1336 rt2= (rect2i + YOFF*width);
1339 for (y=0; y<height-YOFF; y++) {
1340 if(field) fac= fac1;
1344 memcpy(out, rt1, 4 * sizeof(float)*XOFF);
1348 for (x=XOFF; x<width; x++) {
1351 *(out++)= MAX2(0.0, *rt1 - temp); rt1++;
1352 *(out++)= MAX2(0.0, *rt1 - temp); rt1++;
1353 *(out++)= MAX2(0.0, *rt1 - temp); rt1++;
1354 *(out++)= MAX2(0.0, *rt1 - temp); rt1++;
1359 memcpy(out, rt1, 4 * sizeof(float)*YOFF*width);
1363 static void do_drop_effect(Sequence * seq,int cfra,
1364 float facf0, float facf1, int x, int y,
1365 struct ImBuf *ibuf1, struct ImBuf *ibuf2,
1366 struct ImBuf * ibuf3,
1369 if (out->rect_float) {
1370 do_drop_effect_float(
1372 ibuf1->rect_float, ibuf2->rect_float,
1375 do_drop_effect_byte(
1377 (unsigned char*) ibuf1->rect, (unsigned char*) ibuf2->rect,
1378 (unsigned char*) out->rect);
1382 /* **********************************************************************
1384 ********************************************************************** */
1386 static void do_mul_effect_byte(float facf0, float facf1, int x, int y,
1387 unsigned char *rect1, unsigned char *rect2,
1391 char *rt1, *rt2, *rt;
1398 fac1= (int)(256.0*facf0);
1399 fac3= (int)(256.0*facf1);
1402 * fac*(a*b) + (1-fac)*a => fac*a*(b-1)+axaux= c*px + py*s ;//+centx
1403 yaux= -s*px + c*py;//+centy
1411 rt[0]= rt1[0] + ((fac1*rt1[0]*(rt2[0]-256))>>16);
1412 rt[1]= rt1[1] + ((fac1*rt1[1]*(rt2[1]-256))>>16);
1413 rt[2]= rt1[2] + ((fac1*rt1[2]*(rt2[2]-256))>>16);
1414 rt[3]= rt1[3] + ((fac1*rt1[3]*(rt2[3]-256))>>16);
1416 rt1+= 4; rt2+= 4; rt+= 4;
1425 rt[0]= rt1[0] + ((fac3*rt1[0]*(rt2[0]-256))>>16);
1426 rt[1]= rt1[1] + ((fac3*rt1[1]*(rt2[1]-256))>>16);
1427 rt[2]= rt1[2] + ((fac3*rt1[2]*(rt2[2]-256))>>16);
1428 rt[3]= rt1[3] + ((fac3*rt1[3]*(rt2[3]-256))>>16);
1430 rt1+= 4; rt2+= 4; rt+= 4;
1435 static void do_mul_effect_float(float facf0, float facf1, int x, int y,
1436 float *rect1, float *rect2,
1441 float *rt1, *rt2, *rt;
1452 * fac*(a*b) + (1-fac)*a => fac*a*(b-1)+a
1460 rt[0]= rt1[0] + fac1*rt1[0]*(rt2[0]-1.0);
1461 rt[1]= rt1[1] + fac1*rt1[1]*(rt2[1]-1.0);
1462 rt[2]= rt1[2] + fac1*rt1[2]*(rt2[2]-1.0);
1463 rt[3]= rt1[3] + fac1*rt1[3]*(rt2[3]-1.0);
1465 rt1+= 4; rt2+= 4; rt+= 4;
1474 rt[0]= rt1[0] + fac3*rt1[0]*(rt2[0]-1.0);
1475 rt[1]= rt1[1] + fac3*rt1[1]*(rt2[1]-1.0);
1476 rt[2]= rt1[2] + fac3*rt1[2]*(rt2[2]-1.0);
1477 rt[3]= rt1[3] + fac3*rt1[3]*(rt2[3]-1.0);
1479 rt1+= 4; rt2+= 4; rt+= 4;
1484 static void do_mul_effect(Sequence * seq,int cfra,
1485 float facf0, float facf1, int x, int y,
1486 struct ImBuf *ibuf1, struct ImBuf *ibuf2,
1487 struct ImBuf *ibuf3, struct ImBuf *out)
1489 if (out->rect_float) {
1490 do_mul_effect_float(
1492 ibuf1->rect_float, ibuf2->rect_float,
1497 (unsigned char*) ibuf1->rect, (unsigned char*) ibuf2->rect,
1498 (unsigned char*) out->rect);
1502 /* **********************************************************************
1504 ********************************************************************** */
1506 typedef struct WipeZone {
1515 static void precalc_wipe_zone(WipeZone *wipezone, WipeVars *wipe, int xo, int yo)
1517 wipezone->flip = (wipe->angle < 0);
1518 wipezone->angle = pow(fabs(wipe->angle)/45.0f, log(xo)/log(2.0f));
1521 wipezone->width = (int)(wipe->edgeWidth*((xo+yo)/2.0f));
1522 wipezone->pythangle = 1.0f/sqrt(wipe->angle*wipe->angle + 1.0f);
1524 if(wipe->wipetype == DO_SINGLE_WIPE)
1525 wipezone->invwidth = 1.0f/wipezone->width;
1527 wipezone->invwidth = 1.0f/(0.5f*wipezone->width);
1530 // This function calculates the blur band for the wipe effects
1531 static float in_band(WipeZone *wipezone,float width,float dist,float perc,int side,int dir)
1533 float t1,t2,alpha,percwidth;
1539 percwidth = width * perc;
1541 percwidth = width * (1 - perc);
1546 t1 = dist * wipezone->invwidth; //percentange of width that is
1547 t2 = wipezone->invwidth; //amount of alpha per % point
1550 alpha = (t1*t2*100) + (1-perc); // add point's alpha contrib to current position in wipe
1552 alpha = (1-perc) - (t1*t2*100);
1560 static float check_zone(WipeZone *wipezone, int x, int y,
1561 Sequence *seq, float facf0)
1563 float posx, posy,hyp,hyp2,angle,hwidth,b1,b2,b3,pointdist;
1565 float hyp3,hyp4,b4,b5
1567 float temp1,temp2,temp3,temp4; //some placeholder variables
1568 int xo = wipezone->xo;
1569 int yo = wipezone->yo;
1570 float halfx = xo*0.5f;
1571 float halfy = yo*0.5f;
1572 float widthf,output=0;
1573 WipeVars *wipe = (WipeVars *)seq->effectdata;
1576 if(wipezone->flip) x = xo - x;
1577 angle = wipezone->angle;
1585 posx = xo - facf0 * xo;
1586 posy = yo - facf0 * yo;
1589 switch (wipe->wipetype) {
1590 case DO_SINGLE_WIPE:
1591 width = wipezone->width;
1592 hwidth = width*0.5f;
1597 hyp = fabs(y - posy);
1600 b1 = posy - (-angle)*posx;
1601 b2 = y - (-angle)*x;
1602 hyp = fabs(angle*x+y+(-posy-angle*posx))*wipezone->pythangle;
1613 output = in_band(wipezone,width,hyp,facf0,1,1);
1615 output = in_band(wipezone,width,hyp,facf0,0,1);
1619 output = in_band(wipezone,width,hyp,facf0,0,1);
1621 output = in_band(wipezone,width,hyp,facf0,1,1);
1625 case DO_DOUBLE_WIPE:
1627 facf0 = 1.0f-facf0; // Go the other direction
1629 width = wipezone->width; // calculate the blur width
1630 hwidth = width*0.5f;
1636 hyp = abs(y - posy*0.5f);
1637 hyp2 = abs(y - (yo-posy*0.5f));
1640 b1 = posy*0.5f - (-angle)*posx*0.5f;
1641 b3 = (yo-posy*0.5f) - (-angle)*(xo-posx*0.5f);
1642 b2 = y - (-angle)*x;
1644 hyp = abs(angle*x+y+(-posy*0.5f-angle*posx*0.5f))*wipezone->pythangle;
1645 hyp2 = abs(angle*x+y+(-(yo-posy*0.5f)-angle*(xo-posx*0.5f)))*wipezone->pythangle;
1648 temp1 = xo*(1-facf0*0.5f)-xo*facf0*0.5f;
1649 temp2 = yo*(1-facf0*0.5f)-yo*facf0*0.5f;
1650 pointdist = sqrt(temp1*temp1 + temp2*temp2);
1652 if(b2 < b1 && b2 < b3 ){
1653 if(hwidth < pointdist)
1654 output = in_band(wipezone,hwidth,hyp,facf0,0,1);
1655 } else if(b2 > b1 && b2 > b3 ){
1656 if(hwidth < pointdist)
1657 output = in_band(wipezone,hwidth,hyp2,facf0,0,1);
1659 if( hyp < hwidth && hyp2 > hwidth )
1660 output = in_band(wipezone,hwidth,hyp,facf0,1,1);
1661 else if( hyp > hwidth && hyp2 < hwidth )
1662 output = in_band(wipezone,hwidth,hyp2,facf0,1,1);
1664 output = in_band(wipezone,hwidth,hyp2,facf0,1,1) * in_band(wipezone,hwidth,hyp,facf0,1,1);
1666 if(!wipe->forward)output = 1-output;
1670 temp1: angle of effect center in rads
1671 temp2: angle of line through (halfx,halfy) and (x,y) in rads
1672 temp3: angle of low side of blur
1673 temp4: angle of high side of blur
1675 output = 1.0f - facf0;
1676 widthf = wipe->edgeWidth*2.0f*(float)M_PI;
1677 temp1 = 2.0f * (float)M_PI * facf0;
1680 temp1 = 2.0f*(float)M_PI - temp1;
1686 temp2 = asin(abs(y)/sqrt(x*x + y*y));
1687 if(x <= 0 && y >= 0) temp2 = (float)M_PI - temp2;
1688 else if(x<=0 && y <= 0) temp2 += (float)M_PI;
1689 else if(x >= 0 && y <= 0) temp2 = 2.0f*(float)M_PI - temp2;
1692 temp3 = temp1-(widthf*0.5f)*facf0;
1693 temp4 = temp1+(widthf*0.5f)*(1-facf0);
1695 temp3 = temp1-(widthf*0.5f)*(1-facf0);
1696 temp4 = temp1+(widthf*0.5f)*facf0;
1698 if (temp3 < 0) temp3 = 0;
1699 if (temp4 > 2.0f*(float)M_PI) temp4 = 2.0f*(float)M_PI;
1702 if(temp2 < temp3) output = 0;
1703 else if (temp2 > temp4) output = 1;
1704 else output = (temp2-temp3)/(temp4-temp3);
1705 if(x == 0 && y == 0) output = 1;
1706 if(output != output) output = 1;
1707 if(wipe->forward) output = 1 - output;
1709 /* BOX WIPE IS NOT WORKING YET */
1710 /* case DO_CROSS_WIPE: */
1711 /* BOX WIPE IS NOT WORKING YET */
1714 if(invert)facf0 = 1-facf0;
1716 width = (int)(wipe->edgeWidth*((xo+yo)/2.0));
1717 hwidth = (float)width/2.0;
1718 if (angle == 0)angle = 0.000001;
1719 b1 = posy/2 - (-angle)*posx/2;
1720 b3 = (yo-posy/2) - (-angle)*(xo-posx/2);
1721 b2 = y - (-angle)*x;
1723 hyp = abs(angle*x+y+(-posy/2-angle*posx/2))*wipezone->pythangle;
1724 hyp2 = abs(angle*x+y+(-(yo-posy/2)-angle*(xo-posx/2)))*wipezone->pythangle;
1726 temp1 = xo*(1-facf0/2)-xo*facf0/2;
1727 temp2 = yo*(1-facf0/2)-yo*facf0/2;
1728 pointdist = sqrt(temp1*temp1 + temp2*temp2);
1730 if(b2 < b1 && b2 < b3 ){
1731 if(hwidth < pointdist)
1732 output = in_band(wipezone,hwidth,hyp,facf0,0,1);
1733 } else if(b2 > b1 && b2 > b3 ){
1734 if(hwidth < pointdist)
1735 output = in_band(wipezone,hwidth,hyp2,facf0,0,1);
1737 if( hyp < hwidth && hyp2 > hwidth )
1738 output = in_band(wipezone,hwidth,hyp,facf0,1,1);
1739 else if( hyp > hwidth && hyp2 < hwidth )
1740 output = in_band(wipezone,hwidth,hyp2,facf0,1,1);
1742 output = in_band(wipezone,hwidth,hyp2,facf0,1,1) * in_band(wipezone,hwidth,hyp,facf0,1,1);
1745 if(invert)facf0 = 1-facf0;
1747 b1 = posy/2 - (-angle)*posx/2;
1748 b3 = (yo-posy/2) - (-angle)*(xo-posx/2);
1749 b2 = y - (-angle)*x;
1751 hyp = abs(angle*x+y+(-posy/2-angle*posx/2))*wipezone->pythangle;
1752 hyp2 = abs(angle*x+y+(-(yo-posy/2)-angle*(xo-posx/2)))*wipezone->pythangle;
1754 if(b2 < b1 && b2 < b3 ){
1755 if(hwidth < pointdist)
1756 output *= in_band(wipezone,hwidth,hyp,facf0,0,1);
1757 } else if(b2 > b1 && b2 > b3 ){
1758 if(hwidth < pointdist)
1759 output *= in_band(wipezone,hwidth,hyp2,facf0,0,1);
1761 if( hyp < hwidth && hyp2 > hwidth )
1762 output *= in_band(wipezone,hwidth,hyp,facf0,1,1);
1763 else if( hyp > hwidth && hyp2 < hwidth )
1764 output *= in_band(wipezone,hwidth,hyp2,facf0,1,1);
1766 output *= in_band(wipezone,hwidth,hyp2,facf0,1,1) * in_band(wipezone,hwidth,hyp,facf0,1,1);
1772 if(xo > yo) yo = xo;
1775 if(!wipe->forward) facf0 = 1-facf0;
1777 width = wipezone->width;
1778 hwidth = width*0.5f;
1780 temp1 = (halfx-(halfx)*facf0);
1781 pointdist = sqrt(temp1*temp1 + temp1*temp1);
1783 temp2 = sqrt((halfx-x)*(halfx-x) + (halfy-y)*(halfy-y));
1784 if(temp2 > pointdist) output = in_band(wipezone,hwidth,fabs(temp2-pointdist),facf0,0,1);
1785 else output = in_band(wipezone,hwidth,fabs(temp2-pointdist),facf0,1,1);
1787 if(!wipe->forward) output = 1-output;
1791 if (output < 0) output = 0;
1792 else if(output > 1) output = 1;
1796 static void init_wipe_effect(Sequence *seq)
1798 if(seq->effectdata)MEM_freeN(seq->effectdata);
1799 seq->effectdata = MEM_callocN(sizeof(struct WipeVars), "wipevars");
1802 static int num_inputs_wipe()
1807 static void free_wipe_effect(Sequence *seq)
1809 if(seq->effectdata)MEM_freeN(seq->effectdata);
1810 seq->effectdata = 0;
1813 static void copy_wipe_effect(Sequence *dst, Sequence *src)
1815 dst->effectdata = MEM_dupallocN(src->effectdata);
1818 static void do_wipe_effect_byte(Sequence *seq, float facf0, float facf1,
1820 unsigned char *rect1,
1821 unsigned char *rect2, unsigned char *out)
1824 WipeVars *wipe = (WipeVars *)seq->effectdata;
1826 char *rt1, *rt2, *rt;
1828 precalc_wipe_zone(&wipezone, wipe, x, y);
1830 rt1 = (char *)rect1;
1831 rt2 = (char *)rect2;
1838 float check = check_zone(&wipezone,x,y,seq,facf0);
1841 rt[0] = (int)(rt1[0]*check)+ (int)(rt2[0]*(1-check));
1842 rt[1] = (int)(rt1[1]*check)+ (int)(rt2[1]*(1-check));
1843 rt[2] = (int)(rt1[2]*check)+ (int)(rt2[2]*(1-check));
1844 rt[3] = (int)(rt1[3]*check)+ (int)(rt2[3]*(1-check));
1876 static void do_wipe_effect_float(Sequence *seq, float facf0, float facf1,
1879 float *rect2, float *out)
1882 WipeVars *wipe = (WipeVars *)seq->effectdata;
1884 float *rt1, *rt2, *rt;
1886 precalc_wipe_zone(&wipezone, wipe, x, y);
1896 float check = check_zone(&wipezone,x,y,seq,facf0);
1899 rt[0] = rt1[0]*check+ rt2[0]*(1-check);
1900 rt[1] = rt1[1]*check+ rt2[1]*(1-check);
1901 rt[2] = rt1[2]*check+ rt2[2]*(1-check);
1902 rt[3] = rt1[3]*check+ rt2[3]*(1-check);
1934 static void do_wipe_effect(Sequence * seq,int cfra,
1935 float facf0, float facf1, int x, int y,
1936 struct ImBuf *ibuf1, struct ImBuf *ibuf2,
1937 struct ImBuf *ibuf3, struct ImBuf *out)
1939 if (out->rect_float) {
1940 do_wipe_effect_float(seq,
1942 ibuf1->rect_float, ibuf2->rect_float,
1945 do_wipe_effect_byte(seq,
1947 (unsigned char*) ibuf1->rect, (unsigned char*) ibuf2->rect,
1948 (unsigned char*) out->rect);
1951 /* **********************************************************************
1953 ********************************************************************** */
1954 static void init_transform_effect(Sequence *seq)
1956 TransformVars *scale;
1958 if(seq->effectdata)MEM_freeN(seq->effectdata);
1959 seq->effectdata = MEM_callocN(sizeof(struct TransformVars), "transformvars");
1961 scale = (TransformVars *)seq->effectdata;
1962 scale->ScalexIni = 1;
1963 scale->ScaleyIni = 1;
1964 scale->ScalexFin = 1;
1965 scale->ScaleyFin = 1;
1975 scale->interpolation=1;
1979 static int num_inputs_transform()
1984 static void free_transform_effect(Sequence *seq)
1986 if(seq->effectdata)MEM_freeN(seq->effectdata);
1987 seq->effectdata = 0;
1990 static void copy_transform_effect(Sequence *dst, Sequence *src)
1992 dst->effectdata = MEM_dupallocN(src->effectdata);
1995 static void do_transform(Sequence * seq,float facf0, int x, int y,
1996 struct ImBuf *ibuf1,struct ImBuf *out)
1999 float xs,ys,factxScale,factyScale,tx,ty,rad,s,c,xaux,yaux,factRot,px,py;
2000 TransformVars *scale;
2002 // XXX struct RenderData *rd = NULL; // 2.5 global: &G.scene->r;
2005 scale = (TransformVars *)seq->effectdata;
2010 factxScale = scale->ScalexIni + (scale->ScalexFin - scale->ScalexIni) * facf0;
2011 factyScale = scale->ScaleyIni + (scale->ScaleyFin - scale->ScaleyIni) * facf0;
2014 if(!scale->percent){
2015 float rd_s = 0.0f; // XXX 2.5 global: (rd->size / 100.0f);
2017 tx = scale->xIni * rd_s+(xo / 2.0f) + (scale->xFin * rd_s -(xo / 2.0f) - scale->xIni * rd_s +(xo / 2.0f)) * facf0;
2018 ty = scale->yIni * rd_s+(yo / 2.0f) + (scale->yFin * rd_s -(yo / 2.0f) - scale->yIni * rd_s +(yo / 2.0f)) * facf0;
2020 tx = xo*(scale->xIni/100.0f)+(xo / 2.0f) + (xo*(scale->xFin/100.0f)-(xo / 2.0f) - xo*(scale->xIni/100.0f)+(xo / 2.0f)) * facf0;
2021 ty = yo*(scale->yIni/100.0f)+(yo / 2.0f) + (yo*(scale->yFin/100.0f)-(yo / 2.0f) - yo*(scale->yIni/100.0f)+(yo / 2.0f)) * facf0;
2025 factRot = scale->rotIni + (scale->rotFin - scale->rotIni) * facf0;
2026 rad = (M_PI * factRot) / 180.0f;
2031 for (yi = 0; yi < yo; yi++) {
2032 for (xi = 0; xi < xo; xi++) {
2037 //rotate point with center ref
2038 xaux = c*px + py*s ;
2039 yaux = -s*px + c*py;
2041 //scale point with center ref
2042 xs = xaux / factxScale;
2043 ys = yaux / factyScale;
2045 //undo reference center point
2050 switch(scale->interpolation) {
2052 neareast_interpolation(ibuf1,out, xs,ys,xi,yi);
2055 bilinear_interpolation(ibuf1,out, xs,ys,xi,yi);
2058 bicubic_interpolation(ibuf1,out, xs,ys,xi,yi);
2065 static void do_transform_effect(Sequence * seq,int cfra,
2066 float facf0, float facf1, int x, int y,
2067 struct ImBuf *ibuf1, struct ImBuf *ibuf2,
2068 struct ImBuf *ibuf3, struct ImBuf *out)
2070 do_transform(seq, facf0, x, y, ibuf1, out);
2074 /* **********************************************************************
2076 ********************************************************************** */
2078 static void RVBlurBitmap2_byte ( unsigned char* map, int width,int height,
2081 /* MUUUCCH better than the previous blur. */
2082 /* We do the blurring in two passes which is a whole lot faster. */
2083 /* I changed the math arount to implement an actual Gaussian */
2086 /* Watch out though, it tends to misbehaven with large blur values on */
2087 /* a small bitmap. Avoid avoid avoid. */
2088 /*=============================== */
2090 unsigned char* temp=NULL,*swap;
2093 int index, ix, halfWidth;
2094 float fval, k, curColor[3], curColor2[3], weight=0;
2096 /* If we're not really blurring, bail out */
2100 /* Allocate memory for the tempmap and the blur filter matrix */
2101 temp= MEM_mallocN( (width*height*4), "blurbitmaptemp");
2105 /* Allocate memory for the filter elements */
2106 halfWidth = ((quality+1)*blur);
2107 filter = (float *)MEM_mallocN(sizeof(float)*halfWidth*2, "blurbitmapfilter");
2113 /* Apparently we're calculating a bell curve */
2114 /* based on the standard deviation (or radius) */
2115 /* This code is based on an example */
2116 /* posted to comp.graphics.algorithms by */
2117 /* Blancmange (bmange@airdmhor.gen.nz) */
2119 k = -1.0/(2.0*3.14159*blur*blur);
2121 for (ix = 0;ix< halfWidth;ix++){
2122 weight = (float)exp(k*(ix*ix));
2123 filter[halfWidth - ix] = weight;
2124 filter[halfWidth + ix] = weight;
2128 /* Normalize the array */
2130 for (ix = 0;ix< halfWidth*2;ix++)
2133 for (ix = 0;ix< halfWidth*2;ix++)
2137 for (y=0;y<height;y++){
2138 /* Do the left & right strips */
2139 for (x=0;x<halfWidth;x++){
2140 index=(x+y*width)*4;
2142 curColor[0]=curColor[1]=curColor[2]=0;
2143 curColor2[0]=curColor2[1]=curColor2[2]=0;
2145 for (i=x-halfWidth;i<x+halfWidth;i++){
2146 if ((i>=0)&&(i<width)){
2147 curColor[0]+=map[(i+y*width)*4+GlowR]*filter[fx];
2148 curColor[1]+=map[(i+y*width)*4+GlowG]*filter[fx];
2149 curColor[2]+=map[(i+y*width)*4+GlowB]*filter[fx];
2151 curColor2[0]+=map[(width-1-i+y*width)*4+GlowR] *
2153 curColor2[1]+=map[(width-1-i+y*width)*4+GlowG] *
2155 curColor2[2]+=map[(width-1-i+y*width)*4+GlowB] *
2160 temp[index+GlowR]=curColor[0];
2161 temp[index+GlowG]=curColor[1];
2162 temp[index+GlowB]=curColor[2];
2164 temp[((width-1-x+y*width)*4)+GlowR]=curColor2[0];
2165 temp[((width-1-x+y*width)*4)+GlowG]=curColor2[1];
2166 temp[((width-1-x+y*width)*4)+GlowB]=curColor2[2];
2169 /* Do the main body */
2170 for (x=halfWidth;x<width-halfWidth;x++){
2171 index=(x+y*width)*4;
2173 curColor[0]=curColor[1]=curColor[2]=0;
2174 for (i=x-halfWidth;i<x+halfWidth;i++){
2175 curColor[0]+=map[(i+y*width)*4+GlowR]*filter[fx];
2176 curColor[1]+=map[(i+y*width)*4+GlowG]*filter[fx];
2177 curColor[2]+=map[(i+y*width)*4+GlowB]*filter[fx];
2180 temp[index+GlowR]=curColor[0];
2181 temp[index+GlowG]=curColor[1];
2182 temp[index+GlowB]=curColor[2];
2187 swap=temp;temp=map;map=swap;
2190 /* Blur the columns */
2191 for (x=0;x<width;x++){
2192 /* Do the top & bottom strips */
2193 for (y=0;y<halfWidth;y++){
2194 index=(x+y*width)*4;
2196 curColor[0]=curColor[1]=curColor[2]=0;
2197 curColor2[0]=curColor2[1]=curColor2[2]=0;
2198 for (i=y-halfWidth;i<y+halfWidth;i++){
2199 if ((i>=0)&&(i<height)){
2201 curColor[0]+=map[(x+i*width)*4+GlowR]*filter[fy];
2202 curColor[1]+=map[(x+i*width)*4+GlowG]*filter[fy];
2203 curColor[2]+=map[(x+i*width)*4+GlowB]*filter[fy];
2206 curColor2[0]+=map[(x+(height-1-i)*width) *
2207 4+GlowR]*filter[fy];
2208 curColor2[1]+=map[(x+(height-1-i)*width) *
2209 4+GlowG]*filter[fy];
2210 curColor2[2]+=map[(x+(height-1-i)*width) *
2211 4+GlowB]*filter[fy];
2215 temp[index+GlowR]=curColor[0];
2216 temp[index+GlowG]=curColor[1];
2217 temp[index+GlowB]=curColor[2];
2218 temp[((x+(height-1-y)*width)*4)+GlowR]=curColor2[0];
2219 temp[((x+(height-1-y)*width)*4)+GlowG]=curColor2[1];
2220 temp[((x+(height-1-y)*width)*4)+GlowB]=curColor2[2];
2222 /* Do the main body */
2223 for (y=halfWidth;y<height-halfWidth;y++){
2224 index=(x+y*width)*4;
2226 curColor[0]=curColor[1]=curColor[2]=0;
2227 for (i=y-halfWidth;i<y+halfWidth;i++){
2228 curColor[0]+=map[(x+i*width)*4+GlowR]*filter[fy];
2229 curColor[1]+=map[(x+i*width)*4+GlowG]*filter[fy];
2230 curColor[2]+=map[(x+i*width)*4+GlowB]*filter[fy];
2233 temp[index+GlowR]=curColor[0];
2234 temp[index+GlowG]=curColor[1];
2235 temp[index+GlowB]=curColor[2];
2241 swap=temp;temp=map;map=swap;
2248 static void RVBlurBitmap2_float ( float* map, int width,int height,
2251 /* MUUUCCH better than the previous blur. */
2252 /* We do the blurring in two passes which is a whole lot faster. */
2253 /* I changed the math arount to implement an actual Gaussian */
2256 /* Watch out though, it tends to misbehaven with large blur values on */
2257 /* a small bitmap. Avoid avoid avoid. */
2258 /*=============================== */
2260 float* temp=NULL,*swap;
2263 int index, ix, halfWidth;
2264 float fval, k, curColor[3], curColor2[3], weight=0;
2266 /* If we're not really blurring, bail out */
2270 /* Allocate memory for the tempmap and the blur filter matrix */
2271 temp= MEM_mallocN( (width*height*4*sizeof(float)), "blurbitmaptemp");
2275 /* Allocate memory for the filter elements */
2276 halfWidth = ((quality+1)*blur);
2277 filter = (float *)MEM_mallocN(sizeof(float)*halfWidth*2, "blurbitmapfilter");
2283 /* Apparently we're calculating a bell curve */
2284 /* based on the standard deviation (or radius) */
2285 /* This code is based on an example */
2286 /* posted to comp.graphics.algorithms by */
2287 /* Blancmange (bmange@airdmhor.gen.nz) */
2289 k = -1.0/(2.0*3.14159*blur*blur);
2291 for (ix = 0;ix< halfWidth;ix++){
2292 weight = (float)exp(k*(ix*ix));
2293 filter[halfWidth - ix] = weight;
2294 filter[halfWidth + ix] = weight;
2298 /* Normalize the array */
2300 for (ix = 0;ix< halfWidth*2;ix++)
2303 for (ix = 0;ix< halfWidth*2;ix++)
2307 for (y=0;y<height;y++){
2308 /* Do the left & right strips */
2309 for (x=0;x<halfWidth;x++){
2310 index=(x+y*width)*4;
2312 curColor[0]=curColor[1]=curColor[2]=0.0f;
2313 curColor2[0]=curColor2[1]=curColor2[2]=0.0f;
2315 for (i=x-halfWidth;i<x+halfWidth;i++){
2316 if ((i>=0)&&(i<width)){
2317 curColor[0]+=map[(i+y*width)*4+GlowR]*filter[fx];
2318 curColor[1]+=map[(i+y*width)*4+GlowG]*filter[fx];
2319 curColor[2]+=map[(i+y*width)*4+GlowB]*filter[fx];
2321 curColor2[0]+=map[(width-1-i+y*width)*4+GlowR] *
2323 curColor2[1]+=map[(width-1-i+y*width)*4+GlowG] *
2325 curColor2[2]+=map[(width-1-i+y*width)*4+GlowB] *
2330 temp[index+GlowR]=curColor[0];
2331 temp[index+GlowG]=curColor[1];
2332 temp[index+GlowB]=curColor[2];
2334 temp[((width-1-x+y*width)*4)+GlowR]=curColor2[0];
2335 temp[((width-1-x+y*width)*4)+GlowG]=curColor2[1];
2336 temp[((width-1-x+y*width)*4)+GlowB]=curColor2[2];
2339 /* Do the main body */
2340 for (x=halfWidth;x<width-halfWidth;x++){
2341 index=(x+y*width)*4;
2343 curColor[0]=curColor[1]=curColor[2]=0;
2344 for (i=x-halfWidth;i<x+halfWidth;i++){
2345 curColor[0]+=map[(i+y*width)*4+GlowR]*filter[fx];
2346 curColor[1]+=map[(i+y*width)*4+GlowG]*filter[fx];
2347 curColor[2]+=map[(i+y*width)*4+GlowB]*filter[fx];
2350 temp[index+GlowR]=curColor[0];
2351 temp[index+GlowG]=curColor[1];
2352 temp[index+GlowB]=curColor[2];
2357 swap=temp;temp=map;map=swap;
2360 /* Blur the columns */
2361 for (x=0;x<width;x++){
2362 /* Do the top & bottom strips */
2363 for (y=0;y<halfWidth;y++){
2364 index=(x+y*width)*4;
2366 curColor[0]=curColor[1]=curColor[2]=0;
2367 curColor2[0]=curColor2[1]=curColor2[2]=0;
2368 for (i=y-halfWidth;i<y+halfWidth;i++){
2369 if ((i>=0)&&(i<height)){
2371 curColor[0]+=map[(x+i*width)*4+GlowR]*filter[fy];
2372 curColor[1]+=map[(x+i*width)*4+GlowG]*filter[fy];
2373 curColor[2]+=map[(x+i*width)*4+GlowB]*filter[fy];
2376 curColor2[0]+=map[(x+(height-1-i)*width) *
2377 4+GlowR]*filter[fy];
2378 curColor2[1]+=map[(x+(height-1-i)*width) *
2379 4+GlowG]*filter[fy];
2380 curColor2[2]+=map[(x+(height-1-i)*width) *
2381 4+GlowB]*filter[fy];
2385 temp[index+GlowR]=curColor[0];
2386 temp[index+GlowG]=curColor[1];
2387 temp[index+GlowB]=curColor[2];
2388 temp[((x+(height-1-y)*width)*4)+GlowR]=curColor2[0];
2389 temp[((x+(height-1-y)*width)*4)+GlowG]=curColor2[1];
2390 temp[((x+(height-1-y)*width)*4)+GlowB]=curColor2[2];
2392 /* Do the main body */
2393 for (y=halfWidth;y<height-halfWidth;y++){
2394 index=(x+y*width)*4;
2396 curColor[0]=curColor[1]=curColor[2]=0;
2397 for (i=y-halfWidth;i<y+halfWidth;i++){
2398 curColor[0]+=map[(x+i*width)*4+GlowR]*filter[fy];
2399 curColor[1]+=map[(x+i*width)*4+GlowG]*filter[fy];
2400 curColor[2]+=map[(x+i*width)*4+GlowB]*filter[fy];
2403 temp[index+GlowR]=curColor[0];
2404 temp[index+GlowG]=curColor[1];
2405 temp[index+GlowB]=curColor[2];
2411 swap=temp;temp=map;map=swap;
2419 /* Adds two bitmaps and puts the results into a third map. */
2420 /* C must have been previously allocated but it may be A or B. */
2421 /* We clamp values to 255 to prevent weirdness */
2422 /*=============================== */
2423 static void RVAddBitmaps_byte (unsigned char* a, unsigned char* b, unsigned char* c, int width, int height)
2427 for (y=0;y<height;y++){
2428 for (x=0;x<width;x++){
2429 index=(x+y*width)*4;
2430 c[index+GlowR]=MIN2(255,a[index+GlowR]+b[index+GlowR]);
2431 c[index+GlowG]=MIN2(255,a[index+GlowG]+b[index+GlowG]);
2432 c[index+GlowB]=MIN2(255,a[index+GlowB]+b[index+GlowB]);
2433 c[index+GlowA]=MIN2(255,a[index+GlowA]+b[index+GlowA]);
2438 static void RVAddBitmaps_float (float* a, float* b, float* c,
2439 int width, int height)
2443 for (y=0;y<height;y++){
2444 for (x=0;x<width;x++){
2445 index=(x+y*width)*4;
2446 c[index+GlowR]=MIN2(1.0,a[index+GlowR]+b[index+GlowR]);
2447 c[index+GlowG]=MIN2(1.0,a[index+GlowG]+b[index+GlowG]);
2448 c[index+GlowB]=MIN2(1.0,a[index+GlowB]+b[index+GlowB]);
2449 c[index+GlowA]=MIN2(1.0,a[index+GlowA]+b[index+GlowA]);
2454 /* For each pixel whose total luminance exceeds the threshold, */
2455 /* Multiply it's value by BOOST and add it to the output map */
2456 static void RVIsolateHighlights_byte (unsigned char* in, unsigned char* out,
2457 int width, int height, int threshold,
2458 float boost, float clamp)
2464 for(y=0;y< height;y++) {
2465 for (x=0;x< width;x++) {
2466 index= (x+y*width)*4;
2468 /* Isolate the intensity */
2469 intensity=(in[index+GlowR]+in[index+GlowG]+in[index+GlowB]-threshold);
2471 out[index+GlowR]=MIN2(255*clamp, (in[index+GlowR]*boost*intensity)/255);
2472 out[index+GlowG]=MIN2(255*clamp, (in[index+GlowG]*boost*intensity)/255);
2473 out[index+GlowB]=MIN2(255*clamp, (in[index+GlowB]*boost*intensity)/255);
2474 out[index+GlowA]=MIN2(255*clamp, (in[index+GlowA]*boost*intensity)/255);
2485 static void RVIsolateHighlights_float (float* in, float* out,
2486 int width, int height, float threshold,
2487 float boost, float clamp)
2493 for(y=0;y< height;y++) {
2494 for (x=0;x< width;x++) {
2495 index= (x+y*width)*4;
2497 /* Isolate the intensity */
2498 intensity=(in[index+GlowR]+in[index+GlowG]+in[index+GlowB]-threshold);
2500 out[index+GlowR]=MIN2(clamp, (in[index+GlowR]*boost*intensity));
2501 out[index+GlowG]=MIN2(clamp, (in[index+GlowG]*boost*intensity));
2502 out[index+GlowB]=MIN2(clamp, (in[index+GlowB]*boost*intensity));
2503 out[index+GlowA]=MIN2(clamp, (in[index+GlowA]*boost*intensity));
2514 static void init_glow_effect(Sequence *seq)
2518 if(seq->effectdata)MEM_freeN(seq->effectdata);
2519 seq->effectdata = MEM_callocN(sizeof(struct GlowVars), "glowvars");
2521 glow = (GlowVars *)seq->effectdata;
2530 static int num_inputs_glow()
2535 static void free_glow_effect(Sequence *seq)
2537 if(seq->effectdata)MEM_freeN(seq->effectdata);
2538 seq->effectdata = 0;
2541 static void copy_glow_effect(Sequence *dst, Sequence *src)
2543 dst->effectdata = MEM_dupallocN(src->effectdata);
2546 //void do_glow_effect(Cast *cast, float facf0, float facf1, int xo, int yo, ImBuf *ibuf1, ImBuf *ibuf2, ImBuf *outbuf, ImBuf *use)
2547 static void do_glow_effect_byte(Sequence *seq, float facf0, float facf1,
2548 int x, int y, char *rect1,
2549 char *rect2, char *out)
2551 unsigned char *outbuf=(unsigned char *)out;
2552 unsigned char *inbuf=(unsigned char *)rect1;
2553 GlowVars *glow = (GlowVars *)seq->effectdata;
2554 int size= 100; // renderdata XXX
2556 RVIsolateHighlights_byte(inbuf, outbuf , x, y, glow->fMini*765, glow->fBoost * facf0, glow->fClamp);
2557 RVBlurBitmap2_byte (outbuf, x, y, glow->dDist * (size / 100.0f),glow->dQuality);
2559 RVAddBitmaps_byte (inbuf , outbuf, outbuf, x, y);
2562 static void do_glow_effect_float(Sequence *seq, float facf0, float facf1,
2564 float *rect1, float *rect2, float *out)
2566 float *outbuf = out;
2567 float *inbuf = rect1;
2568 GlowVars *glow = (GlowVars *)seq->effectdata;
2569 int size= 100; // renderdata XXX
2571 RVIsolateHighlights_float(inbuf, outbuf , x, y, glow->fMini*3.0f, glow->fBoost * facf0, glow->fClamp);
2572 RVBlurBitmap2_float (outbuf, x, y, glow->dDist * (size / 100.0f),glow->dQuality);
2574 RVAddBitmaps_float (inbuf , outbuf, outbuf, x, y);
2577 static void do_glow_effect(Sequence * seq,int cfra,
2578 float facf0, float facf1, int x, int y,
2579 struct ImBuf *ibuf1, struct ImBuf *ibuf2,
2580 struct ImBuf *ibuf3, struct ImBuf *out)
2582 if (out->rect_float) {
2583 do_glow_effect_float(seq,
2585 ibuf1->rect_float, ibuf2->rect_float,
2588 do_glow_effect_byte(seq,
2590 (char*) ibuf1->rect, (char*) ibuf2->rect,
2595 /* **********************************************************************
2597 ********************************************************************** */
2599 static void init_solid_color(Sequence *seq)
2603 if(seq->effectdata)MEM_freeN(seq->effectdata);
2604 seq->effectdata = MEM_callocN(sizeof(struct SolidColorVars), "solidcolor");
2606 cv = (SolidColorVars *)seq->effectdata;
2607 cv->col[0] = cv->col[1] = cv->col[2] = 0.5;
2610 static int num_inputs_color()
2615 static void free_solid_color(Sequence *seq)
2617 if(seq->effectdata)MEM_freeN(seq->effectdata);
2618 seq->effectdata = 0;
2621 static void copy_solid_color(Sequence *dst, Sequence *src)
2623 dst->effectdata = MEM_dupallocN(src->effectdata);
2626 static int early_out_color(struct Sequence *seq,
2627 float facf0, float facf1)
2632 static void do_solid_color(Sequence * seq,int cfra,
2633 float facf0, float facf1, int x, int y,
2634 struct ImBuf *ibuf1, struct ImBuf *ibuf2,
2635 struct ImBuf *ibuf3, struct ImBuf *out)
2637 SolidColorVars *cv = (SolidColorVars *)seq->effectdata;
2639 unsigned char *rect;
2643 unsigned char col0[3];
2644 unsigned char col1[3];
2646 col0[0] = facf0 * cv->col[0] * 255;
2647 col0[1] = facf0 * cv->col[1] * 255;
2648 col0[2] = facf0 * cv->col[2] * 255;
2650 col1[0] = facf1 * cv->col[0] * 255;
2651 col1[1] = facf1 * cv->col[1] * 255;
2652 col1[2] = facf1 * cv->col[2] * 255;
2654 rect = (unsigned char *)out->rect;
2656 for(y=0; y<out->y; y++) {
2657 for(x=0; x<out->x; x++, rect+=4) {
2665 for(x=0; x<out->x; x++, rect+=4) {
2674 } else if (out->rect_float) {
2678 col0[0] = facf0 * cv->col[0];
2679 col0[1] = facf0 * cv->col[1];
2680 col0[2] = facf0 * cv->col[2];
2682 col1[0] = facf1 * cv->col[0];
2683 col1[1] = facf1 * cv->col[1];
2684 col1[2] = facf1 * cv->col[2];
2686 rect_float = out->rect_float;
2688 for(y=0; y<out->y; y++) {
2689 for(x=0; x<out->x; x++, rect_float+=4) {
2690 rect_float[0]= col0[0];
2691 rect_float[1]= col0[1];
2692 rect_float[2]= col0[2];
2697 for(x=0; x<out->x; x++, rect_float+=4) {
2698 rect_float[0]= col1[0];
2699 rect_float[1]= col1[1];
2700 rect_float[2]= col1[2];
2708 /* **********************************************************************
2710 ********************************************************************** */
2711 static void init_speed_effect(Sequence *seq)
2713 SpeedControlVars * v;
2715 if(seq->effectdata) MEM_freeN(seq->effectdata);
2716 seq->effectdata = MEM_callocN(sizeof(struct SpeedControlVars),
2717 "speedcontrolvars");
2719 v = (SpeedControlVars *)seq->effectdata;
2720 v->globalSpeed = 1.0;
2722 v->flags = SEQ_SPEED_COMPRESS_IPO_Y;
2726 static void load_speed_effect(Sequence * seq)
2728 SpeedControlVars * v = (SpeedControlVars *)seq->effectdata;
2734 static int num_inputs_speed()
2739 static void free_speed_effect(Sequence *seq)
2741 SpeedControlVars * v = (SpeedControlVars *)seq->effectdata;
2742 if(v->frameMap) MEM_freeN(v->frameMap);
2743 if(seq->effectdata) MEM_freeN(seq->effectdata);
2744 seq->effectdata = 0;
2747 static void copy_speed_effect(Sequence *dst, Sequence *src)
2749 SpeedControlVars * v;
2750 dst->effectdata = MEM_dupallocN(src->effectdata);
2751 v = (SpeedControlVars *)dst->effectdata;
2756 static int early_out_speed(struct Sequence *seq,
2757 float facf0, float facf1)
2762 static void store_icu_yrange_speed(struct Sequence * seq,
2763 short adrcode, float * ymin, float * ymax)
2765 SpeedControlVars * v = (SpeedControlVars *)seq->effectdata;
2767 /* if not already done, load / initialize data */
2768 get_sequence_effect(seq);
2770 if ((v->flags & SEQ_SPEED_INTEGRATE) != 0) {
2774 if (v->flags & SEQ_SPEED_COMPRESS_IPO_Y) {
2783 void sequence_effect_speed_rebuild_map(Scene *scene, Sequence * seq, int force)
2788 SpeedControlVars * v = (SpeedControlVars *)seq->effectdata;
2791 /* if not already done, load / initialize data */
2792 get_sequence_effect(seq);
2794 if (!(force || seq->len != v->length || !v->frameMap)) {
2797 if (!seq->seq1) { /* make coverity happy and check for (CID 598)
2802 /* XXX - new in 2.5x. should we use the animation system this way?
2803 * The fcurve is needed because many frames need evaluating at once - campbell */
2804 fcu= id_data_find_fcurve(&scene->id, seq, &RNA_Sequence, "speed_fader", 0);
2807 if (!v->frameMap || v->length != seq->len) {
2808 if (v->frameMap) MEM_freeN(v->frameMap);
2810 v->length = seq->len;
2812 v->frameMap = MEM_callocN(sizeof(float) * v->length,
2813 "speedcontrol frameMap");
2818 /* if there is no IPO, try to make retiming easy by stretching the
2820 // XXX old animation system - seq
2821 if (!fcu && seq->seq1->enddisp != seq->seq1->start && seq->seq1->len != 0) {
2822 fallback_fac = (float) seq->seq1->len /
2823 (float) (seq->seq1->enddisp - seq->seq1->start);
2824 /* FIXME: this strip stretching gets screwed by stripdata
2825 handling one layer up.
2827 So it currently works by enlarging, never by shrinking!
2829 (IPOs still work, if used correctly)
2831 if (fallback_fac > 1.0) {
2836 if ((v->flags & SEQ_SPEED_INTEGRATE) != 0) {
2841 v->lastValidFrame = 0;
2843 for (cfra = 1; cfra < v->length; cfra++) {
2845 if((seq->flag & SEQ_IPO_FRAME_LOCKED) != 0) {
2846 ctime = seq->startdisp + cfra;
2850 div= v->length / 100.0f;
2851 if(div==0.0) return;
2854 facf = evaluate_fcurve(fcu, ctime/div);
2856 facf = fallback_fac;
2858 facf *= v->globalSpeed;
2862 if (cursor >= v->length) {
2863 v->frameMap[cfra] = v->length - 1;
2865 v->frameMap[cfra] = cursor;
2866 v->lastValidFrame = cfra;
2872 v->lastValidFrame = 0;
2873 for (cfra = 0; cfra < v->length; cfra++) {
2876 if((seq->flag & SEQ_IPO_FRAME_LOCKED) != 0) {
2877 ctime = seq->startdisp + cfra;
2881 div= v->length / 100.0f;
2882 if(div==0.0) return;
2885 facf = evaluate_fcurve(fcu, ctime / div);
2886 if (v->flags & SEQ_SPEED_COMPRESS_IPO_Y) {
2892 facf = (float) cfra * fallback_fac;
2894 facf *= v->globalSpeed;
2895 if (facf >= v->length) {
2896 facf = v->length - 1;
2898 v->lastValidFrame = cfra;
2900 v->frameMap[cfra] = facf;
2906 simply reuse do_cross_effect for blending...
2908 static void do_speed_effect(Sequence * seq,int cfra,
2909 float facf0, float facf1, int x, int y,
2910 struct ImBuf *ibuf1, struct ImBuf *ibuf2,
2911 struct ImBuf *ibuf3, struct ImBuf *out)
2918 /* **********************************************************************
2919 sequence effect factory
2920 ********************************************************************** */
2923 static void init_noop(struct Sequence *seq)
2928 static void load_noop(struct Sequence *seq)
2933 static void init_plugin_noop(struct Sequence *seq, const char * fname)
2938 static void free_noop(struct Sequence *seq)
2943 static int num_inputs_default()
2948 static int early_out_noop(struct Sequence *seq,
2949 float facf0, float facf1)
2954 static int early_out_fade(struct Sequence *seq,
2955 float facf0, float facf1)
2957 if (facf0 == 0.0 && facf1 == 0.0) {
2959 } else if (facf0 == 1.0 && facf1 == 1.0) {
2965 static int early_out_mul_input2(struct Sequence *seq,
2966 float facf0, float facf1)
2968 if (facf0 == 0.0 && facf1 == 0.0) {
2974 static void store_icu_yrange_noop(struct Sequence * seq,
2975 short adrcode, float * ymin, float * ymax)
2977 /* defaults are fine */
2980 static void get_default_fac_noop(struct Sequence *seq, int cfra,
2981 float * facf0, float * facf1)
2983 *facf0 = *facf1 = 1.0;
2986 static void get_default_fac_fade(struct Sequence *seq, int cfra,
2987 float * facf0, float * facf1)
2989 *facf0 = (float)(cfra - seq->startdisp);
2990 *facf1 = (float)(*facf0 + 0.5);
2995 static void do_overdrop_effect(struct Sequence * seq, int cfra,
2996 float fac, float facf,
2997 int x, int y, struct ImBuf * ibuf1,
2998 struct ImBuf * ibuf2,
2999 struct ImBuf * ibuf3,
3002 do_drop_effect(seq, cfra, fac, facf, x, y,
3003 ibuf1, ibuf2, ibuf3, out);
3004 do_alphaover_effect(seq, cfra, fac, facf, x, y,
3005 ibuf1, ibuf2, ibuf3, out);
3008 static struct SeqEffectHandle get_sequence_effect_impl(int seq_type)
3010 struct SeqEffectHandle rval;
3011 int sequence_type = seq_type;
3013 rval.init = init_noop;
3014 rval.init_plugin = init_plugin_noop;
3015 rval.num_inputs = num_inputs_default;
3016 rval.load = load_noop;
3017 rval.free = free_noop;
3018 rval.early_out = early_out_noop;
3019 rval.get_default_fac = get_default_fac_noop;
3020 rval.store_icu_yrange = store_icu_yrange_noop;
3021 rval.execute = NULL;
3024 switch (sequence_type) {
3026 rval.execute = do_cross_effect;
3027 rval.early_out = early_out_fade;
3028 rval.get_default_fac = get_default_fac_fade;
3031 rval.init = init_gammacross;
3032 rval.load = load_gammacross;
3033 rval.free = free_gammacross;
3034 rval.early_out = early_out_fade;
3035 rval.get_default_fac = get_default_fac_fade;
3036 rval.execute = do_gammacross_effect;
3039 rval.execute = do_add_effect;
3040 rval.early_out = early_out_mul_input2;
3043 rval.execute = do_sub_effect;
3044 rval.early_out = early_out_mul_input2;
3047 rval.execute = do_mul_effect;
3048 rval.early_out = early_out_mul_input2;
3051 rval.init = init_alpha_over_or_under;
3052 rval.execute = do_alphaover_effect;
3055 rval.execute = do_overdrop_effect;
3057 case SEQ_ALPHAUNDER:
3058 rval.init = init_alpha_over_or_under;
3059 rval.execute = do_alphaunder_effect;
3062 rval.init = init_wipe_effect;
3063 rval.num_inputs = num_inputs_wipe;
3064 rval.free = free_wipe_effect;
3065 rval.copy = copy_wipe_effect;
3066 rval.early_out = early_out_fade;
3067 rval.get_default_fac = get_default_fac_fade;
3068 rval.execute = do_wipe_effect;
3071 rval.init = init_glow_effect;
3072 rval.num_inputs = num_inputs_glow;
3073 rval.free = free_glow_effect;
3074 rval.copy = copy_glow_effect;
3075 rval.execute = do_glow_effect;
3078 rval.init = init_transform_effect;
3079 rval.num_inputs = num_inputs_transform;
3080 rval.free = free_transform_effect;
3081 rval.copy = copy_transform_effect;
3082 rval.execute = do_transform_effect;
3085 rval.init = init_speed_effect;
3086 rval.num_inputs = num_inputs_speed;
3087 rval.load = load_speed_effect;
3088 rval.free = free_speed_effect;
3089 rval.copy = copy_speed_effect;
3090 rval.execute = do_cross_effect;
3091 rval.early_out = early_out_speed;
3092 rval.store_icu_yrange = store_icu_yrange_speed;
3095 rval.init = init_solid_color;
3096 rval.num_inputs = num_inputs_color;
3097 rval.early_out = early_out_color;