==Sequencer==
[blender.git] / source / blender / src / seqeffects.c
1 /**
2  * $Id$
3  *
4  * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
5  *
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. The Blender
10  * Foundation also sells licenses for use in proprietary software under
11  * the Blender License.  See http://www.blender.org/BL/ for information
12  * about this.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software Foundation,
21  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22  *
23  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
24  * All rights reserved.
25  *
26  * Contributor(s): Peter Schlaile <peter [at] schlaile [dot] de> 2005/2006
27  *
28  * ***** END GPL/BL DUAL LICENSE BLOCK *****
29  */
30
31 #include <string.h>
32 #include <math.h>
33 #include <stdlib.h>
34
35 #include "MEM_guardedalloc.h"
36 #include "PIL_dynlib.h"
37 #include "BKE_plugin_types.h"
38
39 #include "IMB_imbuf_types.h"
40 #include "IMB_imbuf.h"
41
42 #include "DNA_sequence_types.h"
43 #include "BSE_seqeffects.h"
44
45 #include "BLI_blenlib.h"
46 #include "BLI_arithb.h"
47
48 #include "DNA_sequence_types.h"
49
50 #include "BKE_utildefines.h"
51 #include "BKE_global.h"
52 #include "BKE_ipo.h"
53 #include "BKE_texture.h"
54 #include "BIF_toolbox.h"
55 #include "BIF_interface.h"
56
57 #include "BSE_sequence.h"
58
59 #include "RE_pipeline.h"                // talks to entire render API
60
61 #include "blendef.h"
62
63 /* Glow effect */
64 enum {
65         GlowR=0,
66         GlowG=1,
67         GlowB=2,
68         GlowA=3
69 };
70
71
72 /* **********************************************************************
73    PLUGINS
74    ********************************************************************** */
75
76 static void open_plugin_seq(PluginSeq *pis, const char *seqname)
77 {
78         int (*version)();
79         void* (*alloc_private)();
80         char *cp;
81
82         /* to be sure: (is tested for) */
83         pis->doit= 0;
84         pis->pname= 0;
85         pis->varstr= 0;
86         pis->cfra= 0;
87         pis->version= 0;
88         pis->instance_private_data = 0;
89
90         /* clear the error list */
91         PIL_dynlib_get_error_as_string(NULL);
92
93         /* if(pis->handle) PIL_dynlib_close(pis->handle); */
94         /* pis->handle= 0; */
95
96         /* open the needed object */
97         pis->handle= PIL_dynlib_open(pis->name);
98         if(test_dlerr(pis->name, pis->name)) return;
99
100         if (pis->handle != 0) {
101                 /* find the address of the version function */
102                 version= (int (*)())PIL_dynlib_find_symbol(pis->handle, "plugin_seq_getversion");
103                 if (test_dlerr(pis->name, "plugin_seq_getversion")) return;
104
105                 if (version != 0) {
106                         pis->version= version();
107                         if (pis->version==2 || pis->version==3
108                             || pis->version==4) {
109                                 int (*info_func)(PluginInfo *);
110                                 PluginInfo *info= (PluginInfo*) MEM_mallocN(sizeof(PluginInfo), "plugin_info");;
111
112                                 info_func= (int (*)(PluginInfo *))PIL_dynlib_find_symbol(pis->handle, "plugin_getinfo");
113
114                                 if(info_func == NULL) error("No info func");
115                                 else {
116                                         info_func(info);
117
118                                         pis->pname= info->name;
119                                         pis->vars= info->nvars;
120                                         pis->cfra= info->cfra;
121
122                                         pis->varstr= info->varstr;
123
124                                         pis->doit= (void(*)(void))info->seq_doit;
125                                         if (info->init)
126                                                 info->init();
127                                 }
128                                 MEM_freeN(info);
129
130                                 cp= PIL_dynlib_find_symbol(pis->handle, "seqname");
131                                 if(cp) strncpy(cp, seqname, 21);
132                         } else {
133                                 printf ("Plugin returned unrecognized version number\n");
134                                 return;
135                         }
136                 }
137                 alloc_private = (void* (*)())PIL_dynlib_find_symbol(
138                         pis->handle, "plugin_seq_alloc_private_data");
139                 if (alloc_private) {
140                         pis->instance_private_data = alloc_private();
141                 }
142                 
143                 pis->current_private_data = (void**) 
144                         PIL_dynlib_find_symbol(
145                                 pis->handle, "plugin_private_data");
146         }
147 }
148
149 static PluginSeq *add_plugin_seq(const char *str, const char *seqname)
150 {
151         PluginSeq *pis;
152         VarStruct *varstr;
153         int a;
154
155         pis= MEM_callocN(sizeof(PluginSeq), "PluginSeq");
156
157         strncpy(pis->name, str, FILE_MAXDIR+FILE_MAXFILE);
158         open_plugin_seq(pis, seqname);
159
160         if(pis->doit==0) {
161                 if(pis->handle==0) error("no plugin: %s", str);
162                 else error("in plugin: %s", str);
163                 MEM_freeN(pis);
164                 return 0;
165         }
166
167         /* default values */
168         varstr= pis->varstr;
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;
174         }
175
176         return pis;
177 }
178
179 static void free_plugin_seq(PluginSeq *pis)
180 {
181         if(pis==0) return;
182
183         /* no PIL_dynlib_close: same plugin can be opened multiple times with 1 handle */
184
185         if (pis->instance_private_data) {
186                 void (*free_private)(void *);
187
188                 free_private = (void (*)(void *))PIL_dynlib_find_symbol(
189                         pis->handle, "plugin_seq_free_private_data");
190                 if (free_private) {
191                         free_private(pis->instance_private_data);
192                 }
193         }
194
195         MEM_freeN(pis);
196 }
197
198 static void init_plugin(Sequence * seq, const char * fname)
199 {
200         seq->plugin= (PluginSeq *)add_plugin_seq(fname, seq->name+2);
201 }
202
203 static void load_plugin(Sequence * seq)
204 {
205         if (seq) {
206                 open_plugin_seq(seq->plugin, seq->name+2);
207         }
208 }
209
210 static void copy_plugin(Sequence * dst, Sequence * src)
211 {
212         if(src->plugin) {
213                 dst->plugin= MEM_dupallocN(src->plugin);
214                 open_plugin_seq(dst->plugin, dst->name+2);
215         }
216 }
217
218 static void do_plugin_effect(Sequence * seq,int cfra,
219                              float facf0, float facf1, int x, int y, 
220                              struct ImBuf *ibuf1, struct ImBuf *ibuf2, 
221                              struct ImBuf *ibuf3, struct ImBuf *out)
222 {
223         char *cp;
224         int float_rendering;
225         int use_temp_bufs = 0; /* Are needed since blur.c (and maybe some other
226                                   old plugins) do very bad stuff
227                                   with imbuf-internals */
228
229         if(seq->plugin && seq->plugin->doit) {
230                 if(seq->plugin->cfra) 
231                         *(seq->plugin->cfra)= frame_to_float(cfra);
232
233                 cp = PIL_dynlib_find_symbol(
234                         seq->plugin->handle, "seqname");
235
236                 if(cp) strncpy(cp, seq->name+2, 22);
237
238                 if (seq->plugin->current_private_data) {
239                         *seq->plugin->current_private_data 
240                                 = seq->plugin->instance_private_data;
241                 }
242
243                 float_rendering = (out->rect_float != NULL);
244
245                 if (seq->plugin->version<=3 && float_rendering) {
246                         use_temp_bufs = 1;
247
248                         if (ibuf1) {
249                                 ibuf1 = IMB_dupImBuf(ibuf1);
250                                 IMB_rect_from_float(ibuf1);
251                                 imb_freerectfloatImBuf(ibuf1);
252                                 ibuf1->flags &= ~IB_rectfloat;
253                         }
254                         if (ibuf2) {
255                                 ibuf2 = IMB_dupImBuf(ibuf2);
256                                 IMB_rect_from_float(ibuf2);
257                                 imb_freerectfloatImBuf(ibuf2);
258                                 ibuf2->flags &= ~IB_rectfloat;
259                         } 
260                         if (ibuf3) {
261                                 ibuf3 = IMB_dupImBuf(ibuf3);
262                                 IMB_rect_from_float(ibuf3);
263                                 imb_freerectfloatImBuf(ibuf3);
264                                 ibuf3->flags &= ~IB_rectfloat;
265                         } 
266                         if (!out->rect) imb_addrectImBuf(out);
267                         imb_freerectfloatImBuf(out);
268                         out->flags &= ~IB_rectfloat;
269                 }
270
271                 if (seq->plugin->version<=2) {
272                         if(ibuf1) IMB_convert_rgba_to_abgr(ibuf1);
273                         if(ibuf2) IMB_convert_rgba_to_abgr(ibuf2);
274                         if(ibuf3) IMB_convert_rgba_to_abgr(ibuf3);
275                 }
276
277                 ((SeqDoit)seq->plugin->doit)(
278                         seq->plugin->data, facf0, facf1, x, y,
279                         ibuf1, ibuf2, out, ibuf3);
280
281                 if (seq->plugin->version<=2) {
282                         if (!use_temp_bufs) {
283                                 if(ibuf1) IMB_convert_rgba_to_abgr(ibuf1);
284                                 if(ibuf2) IMB_convert_rgba_to_abgr(ibuf2);
285                                 if(ibuf3) IMB_convert_rgba_to_abgr(ibuf3);
286                         }
287                         IMB_convert_rgba_to_abgr(out);
288                 }
289                 if (seq->plugin->version<=3 && float_rendering) {
290                         IMB_float_from_rect(out);
291                 }
292
293                 if (use_temp_bufs) {
294                         if (ibuf1) IMB_freeImBuf(ibuf1);
295                         if (ibuf2) IMB_freeImBuf(ibuf2);
296                         if (ibuf3) IMB_freeImBuf(ibuf3);
297                 }
298         }
299 }
300
301 static int do_plugin_early_out(struct Sequence *seq,
302                                float facf0, float facf1)
303 {
304         return 0;
305 }
306
307 static void free_plugin(struct Sequence * seq)
308 {
309         free_plugin_seq(seq->plugin);
310         seq->plugin = 0;
311 }
312
313 /* **********************************************************************
314    ALPHA OVER
315    ********************************************************************** */
316
317 static void init_alpha_over_or_under(Sequence * seq)
318 {
319         Sequence * seq1 = seq->seq1;
320         Sequence * seq2 = seq->seq2;
321
322         seq->seq2= seq1;
323         seq->seq1= seq2;
324 }
325
326 static void do_alphaover_effect_byte(float facf0, float facf1, int x, int y, 
327                                      char * rect1, char *rect2, char *out)
328 {
329         int fac2, mfac, fac, fac4;
330         int xo, tempc;
331         char *rt1, *rt2, *rt;
332
333         xo= x;
334         rt1= (char *)rect1;
335         rt2= (char *)rect2;
336         rt= (char *)out;
337
338         fac2= (int)(256.0*facf0);
339         fac4= (int)(256.0*facf1);
340
341         while(y--) {
342
343                 x= xo;
344                 while(x--) {
345
346                         /* rt = rt1 over rt2  (alpha from rt1) */
347
348                         fac= fac2;
349                         mfac= 256 - ( (fac2*rt1[3])>>8 );
350
351                         if(fac==0) *( (unsigned int *)rt) = *( (unsigned int *)rt2);
352                         else if(mfac==0) *( (unsigned int *)rt) = *( (unsigned int *)rt1);
353                         else {
354                                 tempc= ( fac*rt1[0] + mfac*rt2[0])>>8;
355                                 if(tempc>255) rt[0]= 255; else rt[0]= tempc;
356                                 tempc= ( fac*rt1[1] + mfac*rt2[1])>>8;
357                                 if(tempc>255) rt[1]= 255; else rt[1]= tempc;
358                                 tempc= ( fac*rt1[2] + mfac*rt2[2])>>8;
359                                 if(tempc>255) rt[2]= 255; else rt[2]= tempc;
360                                 tempc= ( fac*rt1[3] + mfac*rt2[3])>>8;
361                                 if(tempc>255) rt[3]= 255; else rt[3]= tempc;
362                         }
363                         rt1+= 4; rt2+= 4; rt+= 4;
364                 }
365
366                 if(y==0) break;
367                 y--;
368
369                 x= xo;
370                 while(x--) {
371
372                         fac= fac4;
373                         mfac= 256 - ( (fac4*rt1[3])>>8 );
374
375                         if(fac==0) *( (unsigned int *)rt) = *( (unsigned int *)rt2);
376                         else if(mfac==0) *( (unsigned int *)rt) = *( (unsigned int *)rt1);
377                         else {
378                                 tempc= ( fac*rt1[0] + mfac*rt2[0])>>8;
379                                 if(tempc>255) rt[0]= 255; else rt[0]= tempc;
380                                 tempc= ( fac*rt1[1] + mfac*rt2[1])>>8;
381                                 if(tempc>255) rt[1]= 255; else rt[1]= tempc;
382                                 tempc= ( fac*rt1[2] + mfac*rt2[2])>>8;
383                                 if(tempc>255) rt[2]= 255; else rt[2]= tempc;
384                                 tempc= ( fac*rt1[3] + mfac*rt2[3])>>8;
385                                 if(tempc>255) rt[3]= 255; else rt[3]= tempc;
386                         }
387                         rt1+= 4; rt2+= 4; rt+= 4;
388                 }
389         }
390 }
391
392 static void do_alphaover_effect_float(float facf0, float facf1, int x, int y, 
393                                       float * rect1, float *rect2, float *out)
394 {
395         float fac2, mfac, fac, fac4;
396         int xo;
397         float *rt1, *rt2, *rt;
398
399         xo= x;
400         rt1= rect1;
401         rt2= rect2;
402         rt= out;
403
404         fac2= facf0;
405         fac4= facf1;
406
407         while(y--) {
408
409                 x= xo;
410                 while(x--) {
411
412                         /* rt = rt1 over rt2  (alpha from rt1) */
413
414                         fac= fac2;
415                         mfac= 1.0 - (fac2*rt1[3]) ;
416
417                         if(fac <= 0.0) {
418                                 memcpy(rt, rt2, 4 * sizeof(float));
419                         } else if(mfac <=0) {
420                                 memcpy(rt, rt1, 4 * sizeof(float));
421                         } else {
422                                 rt[0] = fac*rt1[0] + mfac*rt2[0];
423                                 rt[1] = fac*rt1[1] + mfac*rt2[1];
424                                 rt[2] = fac*rt1[2] + mfac*rt2[2];
425                                 rt[3] = fac*rt1[3] + mfac*rt2[3];
426                         }
427                         rt1+= 4; rt2+= 4; rt+= 4;
428                 }
429
430                 if(y==0) break;
431                 y--;
432
433                 x= xo;
434                 while(x--) {
435
436                         fac= fac4;
437                         mfac= 1.0 - (fac4*rt1[3]);
438
439                         if(fac <= 0.0) {
440                                 memcpy(rt, rt2, 4 * sizeof(float));
441                         } else if(mfac <= 0.0) {
442                                 memcpy(rt, rt1, 4 * sizeof(float));
443                         } else {
444                                 rt[0] = fac*rt1[0] + mfac*rt2[0];
445                                 rt[1] = fac*rt1[1] + mfac*rt2[1];
446                                 rt[2] = fac*rt1[2] + mfac*rt2[2];
447                                 rt[3] = fac*rt1[3] + mfac*rt2[3];
448                         }
449                         rt1+= 4; rt2+= 4; rt+= 4;
450                 }
451         }
452 }
453
454 static void do_alphaover_effect(Sequence * seq,int cfra,
455                                 float facf0, float facf1, int x, int y, 
456                                 struct ImBuf *ibuf1, struct ImBuf *ibuf2, 
457                                 struct ImBuf *ibuf3, struct ImBuf *out)
458 {
459         if (out->rect_float) {
460                 do_alphaover_effect_float(
461                         facf0, facf1, x, y,
462                         ibuf1->rect_float, ibuf2->rect_float,
463                         out->rect_float);
464         } else {
465                 do_alphaover_effect_byte(
466                         facf0, facf1, x, y,
467                         (char*) ibuf1->rect, (char*) ibuf2->rect,
468                         (char*) out->rect);
469         }
470 }
471
472
473 /* **********************************************************************
474    ALPHA UNDER
475    ********************************************************************** */
476
477 void do_alphaunder_effect_byte(
478         float facf0, float facf1, int x, int y, char *rect1, 
479         char *rect2, char *out)
480 {
481         int fac2, mfac, fac, fac4;
482         int xo;
483         char *rt1, *rt2, *rt;
484
485         xo= x;
486         rt1= rect1;
487         rt2= rect2;
488         rt= out;
489
490         fac2= (int)(256.0*facf0);
491         fac4= (int)(256.0*facf1);
492
493         while(y--) {
494
495                 x= xo;
496                 while(x--) {
497
498                         /* rt = rt1 under rt2  (alpha from rt2) */
499
500                         /* this complex optimalisation is because the
501                          * 'skybuf' can be crossed in
502                          */
503                         if(rt2[3]==0 && fac2==256) *( (unsigned int *)rt) = *( (unsigned int *)rt1);
504                         else if(rt2[3]==255) *( (unsigned int *)rt) = *( (unsigned int *)rt2);
505                         else {
506                                 mfac= rt2[3];
507                                 fac= (fac2*(256-mfac))>>8;
508
509                                 if(fac==0) *( (unsigned int *)rt) = *( (unsigned int *)rt2);
510                                 else {
511                                         rt[0]= ( fac*rt1[0] + mfac*rt2[0])>>8;
512                                         rt[1]= ( fac*rt1[1] + mfac*rt2[1])>>8;
513                                         rt[2]= ( fac*rt1[2] + mfac*rt2[2])>>8;
514                                         rt[3]= ( fac*rt1[3] + mfac*rt2[3])>>8;
515                                 }
516                         }
517                         rt1+= 4; rt2+= 4; rt+= 4;
518                 }
519
520                 if(y==0) break;
521                 y--;
522
523                 x= xo;
524                 while(x--) {
525
526                         if(rt2[3]==0 && fac4==256) *( (unsigned int *)rt) = *( (unsigned int *)rt1);
527                         else if(rt2[3]==255) *( (unsigned int *)rt) = *( (unsigned int *)rt2);
528                         else {
529                                 mfac= rt2[3];
530                                 fac= (fac4*(256-mfac))>>8;
531
532                                 if(fac==0) *( (unsigned int *)rt) = *( (unsigned int *)rt2);
533                                 else {
534                                         rt[0]= ( fac*rt1[0] + mfac*rt2[0])>>8;
535                                         rt[1]= ( fac*rt1[1] + mfac*rt2[1])>>8;
536                                         rt[2]= ( fac*rt1[2] + mfac*rt2[2])>>8;
537                                         rt[3]= ( fac*rt1[3] + mfac*rt2[3])>>8;
538                                 }
539                         }
540                         rt1+= 4; rt2+= 4; rt+= 4;
541                 }
542         }
543 }
544
545
546 static void do_alphaunder_effect_float(float facf0, float facf1, int x, int y, 
547                                        float *rect1, float *rect2, 
548                                        float *out)
549 {
550         float fac2, mfac, fac, fac4;
551         int xo;
552         float *rt1, *rt2, *rt;
553
554         xo= x;
555         rt1= rect1;
556         rt2= rect2;
557         rt= out;
558
559         fac2= facf0;
560         fac4= facf1;
561
562         while(y--) {
563
564                 x= xo;
565                 while(x--) {
566
567                         /* rt = rt1 under rt2  (alpha from rt2) */
568
569                         /* this complex optimalisation is because the
570                          * 'skybuf' can be crossed in
571                          */
572                         if( rt2[3]<=0 && fac2>=1.0) {
573                                 memcpy(rt, rt1, 4 * sizeof(float));
574                         } else if(rt2[3]>=1.0) {
575                                 memcpy(rt, rt2, 4 * sizeof(float));
576                         } else {
577                                 mfac = rt2[3];
578                                 fac = fac2 * (1.0 - mfac);
579
580                                 if(fac == 0) {
581                                         memcpy(rt, rt2, 4 * sizeof(float));
582                                 } else {
583                                         rt[0]= fac*rt1[0] + mfac*rt2[0];
584                                         rt[1]= fac*rt1[1] + mfac*rt2[1];
585                                         rt[2]= fac*rt1[2] + mfac*rt2[2];
586                                         rt[3]= fac*rt1[3] + mfac*rt2[3];
587                                 }
588                         }
589                         rt1+= 4; rt2+= 4; rt+= 4;
590                 }
591
592                 if(y==0) break;
593                 y--;
594
595                 x= xo;
596                 while(x--) {
597
598                         if(rt2[3]<=0 && fac4 >= 1.0) {
599                                 memcpy(rt, rt1, 4 * sizeof(float));
600  
601                         } else if(rt2[3]>=1.0) {
602                                 memcpy(rt, rt2, 4 * sizeof(float));
603                         } else {
604                                 mfac= rt2[3];
605                                 fac= fac4*(1.0-mfac);
606
607                                 if(fac == 0) {
608                                         memcpy(rt, rt2, 4 * sizeof(float));
609                                 } else {
610                                         rt[0]= fac * rt1[0] + mfac * rt2[0];
611                                         rt[1]= fac * rt1[1] + mfac * rt2[1];
612                                         rt[2]= fac * rt1[2] + mfac * rt2[2];
613                                         rt[3]= fac * rt1[3] + mfac * rt2[3];
614                                 }
615                         }
616                         rt1+= 4; rt2+= 4; rt+= 4;
617                 }
618         }
619 }
620
621 static void do_alphaunder_effect(Sequence * seq,int cfra,
622                                 float facf0, float facf1, int x, int y, 
623                                 struct ImBuf *ibuf1, struct ImBuf *ibuf2, 
624                                 struct ImBuf *ibuf3, struct ImBuf *out)
625 {
626         if (out->rect_float) {
627                 do_alphaunder_effect_float(
628                         facf0, facf1, x, y,
629                         ibuf1->rect_float, ibuf2->rect_float,
630                         out->rect_float);
631         } else {
632                 do_alphaunder_effect_byte(
633                         facf0, facf1, x, y,
634                         (char*) ibuf1->rect, (char*) ibuf2->rect,
635                         (char*) out->rect);
636         }
637 }
638
639
640 /* **********************************************************************
641    CROSS
642    ********************************************************************** */
643
644 void do_cross_effect_byte(float facf0, float facf1, int x, int y, 
645                           char *rect1, char *rect2, 
646                           char *out)
647 {
648         int fac1, fac2, fac3, fac4;
649         int xo;
650         char *rt1, *rt2, *rt;
651
652         xo= x;
653         rt1= rect1;
654         rt2= rect2;
655         rt= out;
656
657         fac2= (int)(256.0*facf0);
658         fac1= 256-fac2;
659         fac4= (int)(256.0*facf1);
660         fac3= 256-fac4;
661
662         while(y--) {
663
664                 x= xo;
665                 while(x--) {
666
667                         rt[0]= (fac1*rt1[0] + fac2*rt2[0])>>8;
668                         rt[1]= (fac1*rt1[1] + fac2*rt2[1])>>8;
669                         rt[2]= (fac1*rt1[2] + fac2*rt2[2])>>8;
670                         rt[3]= (fac1*rt1[3] + fac2*rt2[3])>>8;
671
672                         rt1+= 4; rt2+= 4; rt+= 4;
673                 }
674
675                 if(y==0) break;
676                 y--;
677
678                 x= xo;
679                 while(x--) {
680
681                         rt[0]= (fac3*rt1[0] + fac4*rt2[0])>>8;
682                         rt[1]= (fac3*rt1[1] + fac4*rt2[1])>>8;
683                         rt[2]= (fac3*rt1[2] + fac4*rt2[2])>>8;
684                         rt[3]= (fac3*rt1[3] + fac4*rt2[3])>>8;
685
686                         rt1+= 4; rt2+= 4; rt+= 4;
687                 }
688
689         }
690 }
691
692 void do_cross_effect_float(float facf0, float facf1, int x, int y, 
693                            float *rect1, float *rect2, float *out)
694 {
695         float fac1, fac2, fac3, fac4;
696         int xo;
697         float *rt1, *rt2, *rt;
698
699         xo= x;
700         rt1= rect1;
701         rt2= rect2;
702         rt= out;
703
704         fac2= facf0;
705         fac1= 1.0 - fac2;
706         fac4= facf1;
707         fac3= 1.0 - fac4;
708
709         while(y--) {
710
711                 x= xo;
712                 while(x--) {
713
714                         rt[0]= fac1*rt1[0] + fac2*rt2[0];
715                         rt[1]= fac1*rt1[1] + fac2*rt2[1];
716                         rt[2]= fac1*rt1[2] + fac2*rt2[2];
717                         rt[3]= fac1*rt1[3] + fac2*rt2[3];
718
719                         rt1+= 4; rt2+= 4; rt+= 4;
720                 }
721
722                 if(y==0) break;
723                 y--;
724
725                 x= xo;
726                 while(x--) {
727
728                         rt[0]= fac3*rt1[0] + fac4*rt2[0];
729                         rt[1]= fac3*rt1[1] + fac4*rt2[1];
730                         rt[2]= fac3*rt1[2] + fac4*rt2[2];
731                         rt[3]= fac3*rt1[3] + fac4*rt2[3];
732
733                         rt1+= 4; rt2+= 4; rt+= 4;
734                 }
735
736         }
737 }
738
739 static void do_cross_effect(Sequence * seq,int cfra,
740                             float facf0, float facf1, int x, int y, 
741                             struct ImBuf *ibuf1, struct ImBuf *ibuf2, 
742                             struct ImBuf *ibuf3, struct ImBuf *out)
743 {
744         if (out->rect_float) {
745                 do_cross_effect_float(
746                         facf0, facf1, x, y,
747                         ibuf1->rect_float, ibuf2->rect_float,
748                         out->rect_float);
749         } else {
750                 do_cross_effect_byte(
751                         facf0, facf1, x, y,
752                         (char*) ibuf1->rect, (char*) ibuf2->rect,
753                         (char*) out->rect);
754         }
755 }
756
757
758 /* **********************************************************************
759    GAMMA CROSS
760    ********************************************************************** */
761
762 /* copied code from initrender.c */
763 static unsigned short *gamtab = 0;
764 static unsigned short *igamtab1 = 0;
765 static int gamma_tabs_refcount = 0;
766
767 #define RE_GAMMA_TABLE_SIZE 400
768
769 static float gamma_range_table[RE_GAMMA_TABLE_SIZE + 1];
770 static float gamfactor_table[RE_GAMMA_TABLE_SIZE];
771 static float inv_gamma_range_table[RE_GAMMA_TABLE_SIZE + 1];
772 static float inv_gamfactor_table[RE_GAMMA_TABLE_SIZE];
773 static float colour_domain_table[RE_GAMMA_TABLE_SIZE + 1];
774 static float colour_step;
775 static float inv_colour_step;
776 static float valid_gamma;
777 static float valid_inv_gamma;
778
779 static void makeGammaTables(float gamma)
780 {
781         /* we need two tables: one forward, one backward */
782         int i;
783
784         valid_gamma        = gamma;
785         valid_inv_gamma    = 1.0 / gamma;
786         colour_step        = 1.0 / RE_GAMMA_TABLE_SIZE;
787         inv_colour_step    = (float) RE_GAMMA_TABLE_SIZE; 
788
789         /* We could squeeze out the two range tables to gain some memory.        */     
790         for (i = 0; i < RE_GAMMA_TABLE_SIZE; i++) {
791                 colour_domain_table[i]   = i * colour_step;
792                 gamma_range_table[i]     = pow(colour_domain_table[i],
793                                                                                 valid_gamma);
794                 inv_gamma_range_table[i] = pow(colour_domain_table[i],
795                                                                                 valid_inv_gamma);
796         }
797
798         /* The end of the table should match 1.0 carefully. In order to avoid    */
799         /* rounding errors, we just set this explicitly. The last segment may    */
800         /* have a different lenght than the other segments, but our              */
801         /* interpolation is insensitive to that.                                 */
802         colour_domain_table[RE_GAMMA_TABLE_SIZE]   = 1.0;
803         gamma_range_table[RE_GAMMA_TABLE_SIZE]     = 1.0;
804         inv_gamma_range_table[RE_GAMMA_TABLE_SIZE] = 1.0;
805
806         /* To speed up calculations, we make these calc factor tables. They are  */
807         /* multiplication factors used in scaling the interpolation.             */
808         for (i = 0; i < RE_GAMMA_TABLE_SIZE; i++ ) {
809                 gamfactor_table[i] = inv_colour_step
810                         * (gamma_range_table[i + 1] - gamma_range_table[i]) ;
811                 inv_gamfactor_table[i] = inv_colour_step
812                         * (inv_gamma_range_table[i + 1] - inv_gamma_range_table[i]) ;
813         }
814
815 } /* end of void makeGammaTables(float gamma) */
816
817
818 static float gammaCorrect(float c)
819 {
820         int i;
821         float res = 0.0;
822         
823         i = floor(c * inv_colour_step);
824         /* Clip to range [0,1]: outside, just do the complete calculation.       */
825         /* We may have some performance problems here. Stretching up the LUT     */
826         /* may help solve that, by exchanging LUT size for the interpolation.    */
827         /* Negative colours are explicitly handled.                              */
828         if (i < 0) res = -pow(abs(c), valid_gamma);
829         else if (i >= RE_GAMMA_TABLE_SIZE ) res = pow(c, valid_gamma);
830         else res = gamma_range_table[i] + 
831                          ( (c - colour_domain_table[i]) * gamfactor_table[i]); 
832         
833         return res;
834 } /* end of float gammaCorrect(float col) */
835
836 /* ------------------------------------------------------------------------- */
837
838 static float invGammaCorrect(float col)
839 {
840         int i;
841         float res = 0.0;
842
843         i = floor(col*inv_colour_step);
844         /* Negative colours are explicitly handled.                              */
845         if (i < 0) res = -pow(abs(col), valid_inv_gamma);
846         else if (i >= RE_GAMMA_TABLE_SIZE) res = pow(col, valid_inv_gamma);
847         else res = inv_gamma_range_table[i] + 
848                          ( (col - colour_domain_table[i]) * inv_gamfactor_table[i]);
849                            
850         return res;
851 } /* end of float invGammaCorrect(float col) */
852
853
854 static void gamtabs(float gamma)
855 {
856         float val, igamma= 1.0f/gamma;
857         int a;
858         
859         gamtab= MEM_mallocN(65536*sizeof(short), "initGaus2");
860         igamtab1= MEM_mallocN(256*sizeof(short), "initGaus2");
861
862         /* gamtab: in short, out short */
863         for(a=0; a<65536; a++) {
864                 val= a;
865                 val/= 65535.0;
866                 
867                 if(gamma==2.0) val= sqrt(val);
868                 else if(gamma!=1.0) val= pow(val, igamma);
869                 
870                 gamtab[a]= (65535.99*val);
871         }
872         /* inverse gamtab1 : in byte, out short */
873         for(a=1; a<=256; a++) {
874                 if(gamma==2.0) igamtab1[a-1]= a*a-1;
875                 else if(gamma==1.0) igamtab1[a-1]= 256*a-1;
876                 else {
877                         val= a/256.0;
878                         igamtab1[a-1]= (65535.0*pow(val, gamma)) -1 ;
879                 }
880         }
881
882 }
883
884 static void alloc_or_ref_gammatabs()
885 {
886         if (gamma_tabs_refcount == 0) {
887                 gamtabs(2.0f);
888                 makeGammaTables(2.0f);
889         }
890         gamma_tabs_refcount++;
891 }
892
893 static void init_gammacross(Sequence * seq)
894 {
895         alloc_or_ref_gammatabs();
896 }
897
898 static void load_gammacross(Sequence * seq)
899 {
900         alloc_or_ref_gammatabs();
901 }
902
903 static void free_gammacross(Sequence * seq)
904 {
905         if (--gamma_tabs_refcount == 0) {
906                 MEM_freeN(gamtab);
907                 MEM_freeN(igamtab1);
908                 gamtab = 0;
909                 igamtab1 = 0;
910         }
911         if (gamma_tabs_refcount < 0) {
912                 fprintf(stderr, "seqeffects: free_gammacross double free!\n");
913         }
914 }
915
916 static void do_gammacross_effect_byte(float facf0, float facf1, 
917                                       int x, int y, 
918                                       char *rect1, 
919                                       char *rect2, 
920                                       char *out)
921 {
922         int fac1, fac2, col;
923         int xo;
924         char *rt1, *rt2, *rt;
925         
926         xo= x;
927         rt1= (char *)rect1;
928         rt2= (char *)rect2;
929         rt= (char *)out;
930
931         fac2= (int)(256.0*facf0);
932         fac1= 256-fac2;
933
934         while(y--) {
935
936                 x= xo;
937                 while(x--) {
938
939                         col= (fac1*igamtab1[rt1[0]] + fac2*igamtab1[rt2[0]])>>8;
940                         if(col>65535) rt[0]= 255; else rt[0]= ( (char *)(gamtab+col))[MOST_SIG_BYTE];
941                         col=(fac1*igamtab1[rt1[1]] + fac2*igamtab1[rt2[1]])>>8;
942                         if(col>65535) rt[1]= 255; else rt[1]= ( (char *)(gamtab+col))[MOST_SIG_BYTE];
943                         col= (fac1*igamtab1[rt1[2]] + fac2*igamtab1[rt2[2]])>>8;
944                         if(col>65535) rt[2]= 255; else rt[2]= ( (char *)(gamtab+col))[MOST_SIG_BYTE];
945                         col= (fac1*igamtab1[rt1[3]] + fac2*igamtab1[rt2[3]])>>8;
946                         if(col>65535) rt[3]= 255; else rt[3]= ( (char *)(gamtab+col))[MOST_SIG_BYTE];
947
948                         rt1+= 4; rt2+= 4; rt+= 4;
949                 }
950
951                 if(y==0) break;
952                 y--;
953
954                 x= xo;
955                 while(x--) {
956
957                         col= (fac1*igamtab1[rt1[0]] + fac2*igamtab1[rt2[0]])>>8;
958                         if(col>65535) rt[0]= 255; else rt[0]= ( (char *)(gamtab+col))[MOST_SIG_BYTE];
959                         col= (fac1*igamtab1[rt1[1]] + fac2*igamtab1[rt2[1]])>>8;
960                         if(col>65535) rt[1]= 255; else rt[1]= ( (char *)(gamtab+col))[MOST_SIG_BYTE];
961                         col= (fac1*igamtab1[rt1[2]] + fac2*igamtab1[rt2[2]])>>8;
962                         if(col>65535) rt[2]= 255; else rt[2]= ( (char *)(gamtab+col))[MOST_SIG_BYTE];
963                         col= (fac1*igamtab1[rt1[3]] + fac2*igamtab1[rt2[3]])>>8;
964                         if(col>65535) rt[3]= 255; else rt[3]= ( (char *)(gamtab+col))[MOST_SIG_BYTE];
965
966                         rt1+= 4; rt2+= 4; rt+= 4;
967                 }
968         }
969
970 }
971
972 static void do_gammacross_effect_float(float facf0, float facf1, 
973                                        int x, int y, 
974                                        float *rect1, float *rect2, 
975                                        float *out)
976 {
977         float fac1, fac2, col;
978         int xo;
979         float *rt1, *rt2, *rt;
980
981         xo= x;
982         rt1= rect1;
983         rt2= rect2;
984         rt= out;
985
986         fac2= facf0;
987         fac1= 1.0 - fac2;
988
989         while(y--) {
990
991                 x= xo * 4;
992                 while(x--) {
993
994                         *rt= gammaCorrect(
995                                 fac1 * invGammaCorrect(*rt1) 
996                                 + fac2 * invGammaCorrect(*rt2));
997                         rt1++; rt2++; rt++;
998                 }
999
1000                 if(y==0) break;
1001                 y--;
1002
1003                 x= xo * 4;
1004                 while(x--) {
1005
1006                         col= gammaCorrect(
1007                                 fac1*invGammaCorrect(*rt1) 
1008                                 + fac2*invGammaCorrect(*rt2));
1009
1010                         rt1++; rt2++; rt++;
1011                 }
1012         }
1013 }
1014
1015 static void do_gammacross_effect(Sequence * seq,int cfra,
1016                                  float facf0, float facf1, int x, int y, 
1017                                  struct ImBuf *ibuf1, struct ImBuf *ibuf2, 
1018                                  struct ImBuf *ibuf3, struct ImBuf *out)
1019 {
1020         if (out->rect_float) {
1021                 do_gammacross_effect_float(
1022                         facf0, facf1, x, y,
1023                         ibuf1->rect_float, ibuf2->rect_float,
1024                         out->rect_float);
1025         } else {
1026                 do_gammacross_effect_byte(
1027                         facf0, facf1, x, y,
1028                         (char*) ibuf1->rect, (char*) ibuf2->rect,
1029                         (char*) out->rect);
1030         }
1031 }
1032
1033
1034 /* **********************************************************************
1035    ADD
1036    ********************************************************************** */
1037
1038 static void do_add_effect_byte(float facf0, float facf1, int x, int y, 
1039                                unsigned char *rect1, unsigned char *rect2, 
1040                                unsigned char *out)
1041 {
1042         int col, xo, fac1, fac3;
1043         char *rt1, *rt2, *rt;
1044
1045         xo= x;
1046         rt1= (char *)rect1;
1047         rt2= (char *)rect2;
1048         rt= (char *)out;
1049
1050         fac1= (int)(256.0*facf0);
1051         fac3= (int)(256.0*facf1);
1052
1053         while(y--) {
1054
1055                 x= xo;
1056                 while(x--) {
1057
1058                         col= rt1[0]+ ((fac1*rt2[0])>>8);
1059                         if(col>255) rt[0]= 255; else rt[0]= col;
1060                         col= rt1[1]+ ((fac1*rt2[1])>>8);
1061                         if(col>255) rt[1]= 255; else rt[1]= col;
1062                         col= rt1[2]+ ((fac1*rt2[2])>>8);
1063                         if(col>255) rt[2]= 255; else rt[2]= col;
1064                         col= rt1[3]+ ((fac1*rt2[3])>>8);
1065                         if(col>255) rt[3]= 255; else rt[3]= col;
1066
1067                         rt1+= 4; rt2+= 4; rt+= 4;
1068                 }
1069
1070                 if(y==0) break;
1071                 y--;
1072
1073                 x= xo;
1074                 while(x--) {
1075
1076                         col= rt1[0]+ ((fac3*rt2[0])>>8);
1077                         if(col>255) rt[0]= 255; else rt[0]= col;
1078                         col= rt1[1]+ ((fac3*rt2[1])>>8);
1079                         if(col>255) rt[1]= 255; else rt[1]= col;
1080                         col= rt1[2]+ ((fac3*rt2[2])>>8);
1081                         if(col>255) rt[2]= 255; else rt[2]= col;
1082                         col= rt1[3]+ ((fac3*rt2[3])>>8);
1083                         if(col>255) rt[3]= 255; else rt[3]= col;
1084
1085                         rt1+= 4; rt2+= 4; rt+= 4;
1086                 }
1087         }
1088 }
1089
1090 static void do_add_effect_float(float facf0, float facf1, int x, int y, 
1091                                 float *rect1, float *rect2, 
1092                                 float *out)
1093 {
1094         int xo;
1095         float fac1, fac3;
1096         float *rt1, *rt2, *rt;
1097
1098         xo= x;
1099         rt1= rect1;
1100         rt2= rect2;
1101         rt= out;
1102
1103         fac1= facf0;
1104         fac3= facf1;
1105
1106         while(y--) {
1107
1108                 x= xo * 4;
1109                 while(x--) {
1110                         *rt = *rt1 + fac1 * (*rt2);
1111
1112                         rt1++; rt2++; rt++;
1113                 }
1114
1115                 if(y==0) break;
1116                 y--;
1117
1118                 x= xo * 4;
1119                 while(x--) {
1120                         *rt = *rt1 + fac3 * (*rt2);
1121
1122                         rt1++; rt2++; rt++;
1123                 }
1124         }
1125 }
1126
1127 static void do_add_effect(Sequence * seq,int cfra,
1128                           float facf0, float facf1, int x, int y, 
1129                           struct ImBuf *ibuf1, struct ImBuf *ibuf2, 
1130                           struct ImBuf *ibuf3, struct ImBuf *out)
1131 {
1132         if (out->rect_float) {
1133                 do_add_effect_float(
1134                         facf0, facf1, x, y,
1135                         ibuf1->rect_float, ibuf2->rect_float,
1136                         out->rect_float);
1137         } else {
1138                 do_add_effect_byte(
1139                         facf0, facf1, x, y,
1140                         (char*) ibuf1->rect, (char*) ibuf2->rect,
1141                         (char*) out->rect);
1142         }
1143 }
1144
1145
1146 /* **********************************************************************
1147    SUB
1148    ********************************************************************** */
1149
1150 static void do_sub_effect_byte(float facf0, float facf1, 
1151                                int x, int y, 
1152                                char *rect1, char *rect2, char *out)
1153 {
1154         int col, xo, fac1, fac3;
1155         char *rt1, *rt2, *rt;
1156
1157         xo= x;
1158         rt1= (char *)rect1;
1159         rt2= (char *)rect2;
1160         rt= (char *)out;
1161
1162         fac1= (int)(256.0*facf0);
1163         fac3= (int)(256.0*facf1);
1164
1165         while(y--) {
1166
1167                 x= xo;
1168                 while(x--) {
1169
1170                         col= rt1[0]- ((fac1*rt2[0])>>8);
1171                         if(col<0) rt[0]= 0; else rt[0]= col;
1172                         col= rt1[1]- ((fac1*rt2[1])>>8);
1173                         if(col<0) rt[1]= 0; else rt[1]= col;
1174                         col= rt1[2]- ((fac1*rt2[2])>>8);
1175                         if(col<0) rt[2]= 0; else rt[2]= col;
1176                         col= rt1[3]- ((fac1*rt2[3])>>8);
1177                         if(col<0) rt[3]= 0; else rt[3]= col;
1178
1179                         rt1+= 4; rt2+= 4; rt+= 4;
1180                 }
1181
1182                 if(y==0) break;
1183                 y--;
1184
1185                 x= xo;
1186                 while(x--) {
1187
1188                         col= rt1[0]- ((fac3*rt2[0])>>8);
1189                         if(col<0) rt[0]= 0; else rt[0]= col;
1190                         col= rt1[1]- ((fac3*rt2[1])>>8);
1191                         if(col<0) rt[1]= 0; else rt[1]= col;
1192                         col= rt1[2]- ((fac3*rt2[2])>>8);
1193                         if(col<0) rt[2]= 0; else rt[2]= col;
1194                         col= rt1[3]- ((fac3*rt2[3])>>8);
1195                         if(col<0) rt[3]= 0; else rt[3]= col;
1196
1197                         rt1+= 4; rt2+= 4; rt+= 4;
1198                 }
1199         }
1200 }
1201
1202 static void do_sub_effect_float(float facf0, float facf1, int x, int y, 
1203                                 float *rect1, float *rect2, 
1204                                 float *out)
1205 {
1206         int xo;
1207         float fac1, fac3;
1208         float *rt1, *rt2, *rt;
1209
1210         xo= x;
1211         rt1= rect1;
1212         rt2= rect2;
1213         rt= out;
1214
1215         fac1= facf0;
1216         fac3= facf1;
1217
1218         while(y--) {
1219
1220                 x= xo * 4;
1221                 while(x--) {
1222                         *rt = *rt1 - fac1 * (*rt2);
1223
1224                         rt1++; rt2++; rt++;
1225                 }
1226
1227                 if(y==0) break;
1228                 y--;
1229
1230                 x= xo * 4;
1231                 while(x--) {
1232                         *rt = *rt1 - fac3 * (*rt2);
1233
1234                         rt1++; rt2++; rt++;
1235                 }
1236         }
1237 }
1238
1239 static void do_sub_effect(Sequence * seq,int cfra,
1240                           float facf0, float facf1, int x, int y, 
1241                           struct ImBuf *ibuf1, struct ImBuf *ibuf2, 
1242                           struct ImBuf *ibuf3, struct ImBuf *out)
1243 {
1244         if (out->rect_float) {
1245                 do_sub_effect_float(
1246                         facf0, facf1, x, y,
1247                         ibuf1->rect_float, ibuf2->rect_float,
1248                         out->rect_float);
1249         } else {
1250                 do_sub_effect_byte(
1251                         facf0, facf1, x, y,
1252                         (char*) ibuf1->rect, (char*) ibuf2->rect,
1253                         (char*) out->rect);
1254         }
1255 }
1256
1257 /* **********************************************************************
1258    DROP
1259    ********************************************************************** */
1260
1261 /* Must be > 0 or add precopy, etc to the function */
1262 #define XOFF    8
1263 #define YOFF    8
1264
1265 static void do_drop_effect_byte(float facf0, float facf1, int x, int y, 
1266                                 unsigned char *rect2i, unsigned char *rect1i, 
1267                                 unsigned char *outi)
1268 {
1269         int height, width, temp, fac, fac1, fac2;
1270         char *rt1, *rt2, *out;
1271         int field= 1;
1272
1273         width= x;
1274         height= y;
1275
1276         fac1= (int)(70.0*facf0);
1277         fac2= (int)(70.0*facf1);
1278
1279         rt2= (char*) (rect2i + YOFF*width);
1280         rt1= (char*) rect1i;
1281         out= (char*) outi;
1282         for (y=0; y<height-YOFF; y++) {
1283                 if(field) fac= fac1;
1284                 else fac= fac2;
1285                 field= !field;
1286
1287                 memcpy(out, rt1, sizeof(int)*XOFF);
1288                 rt1+= XOFF*4;
1289                 out+= XOFF*4;
1290
1291                 for (x=XOFF; x<width; x++) {
1292                         temp= ((fac*rt2[3])>>8);
1293
1294                         *(out++)= MAX2(0, *rt1 - temp); rt1++;
1295                         *(out++)= MAX2(0, *rt1 - temp); rt1++;
1296                         *(out++)= MAX2(0, *rt1 - temp); rt1++;
1297                         *(out++)= MAX2(0, *rt1 - temp); rt1++;
1298                         rt2+=4;
1299                 }
1300                 rt2+=XOFF*4;
1301         }
1302         memcpy(out, rt1, sizeof(int)*YOFF*width);
1303 }
1304
1305 static void do_drop_effect_float(float facf0, float facf1, int x, int y, 
1306                                  float *rect2i, float *rect1i, 
1307                                  float *outi)
1308 {
1309         int height, width;
1310         float temp, fac, fac1, fac2;
1311         float *rt1, *rt2, *out;
1312         int field= 1;
1313
1314         width= x;
1315         height= y;
1316
1317         fac1= 70.0*facf0;
1318         fac2= 70.0*facf1;
1319
1320         rt2=  (rect2i + YOFF*width);
1321         rt1=  rect1i;
1322         out=  outi;
1323         for (y=0; y<height-YOFF; y++) {
1324                 if(field) fac= fac1;
1325                 else fac= fac2;
1326                 field= !field;
1327
1328                 memcpy(out, rt1, 4 * sizeof(float)*XOFF);
1329                 rt1+= XOFF*4;
1330                 out+= XOFF*4;
1331
1332                 for (x=XOFF; x<width; x++) {
1333                         temp= fac * rt2[3];
1334
1335                         *(out++)= MAX2(0.0, *rt1 - temp); rt1++;
1336                         *(out++)= MAX2(0.0, *rt1 - temp); rt1++;
1337                         *(out++)= MAX2(0.0, *rt1 - temp); rt1++;
1338                         *(out++)= MAX2(0.0, *rt1 - temp); rt1++;
1339                         rt2+=4;
1340                 }
1341                 rt2+=XOFF*4;
1342         }
1343         memcpy(out, rt1, 4 * sizeof(float)*YOFF*width);
1344 }
1345
1346
1347 static void do_drop_effect(Sequence * seq,int cfra,
1348                            float facf0, float facf1, int x, int y, 
1349                            struct ImBuf *ibuf1, struct ImBuf *ibuf2, 
1350                            struct ImBuf * ibuf3,
1351                            struct ImBuf *out)
1352 {
1353         if (out->rect_float) {
1354                 do_drop_effect_float(
1355                         facf0, facf1, x, y,
1356                         ibuf1->rect_float, ibuf2->rect_float,
1357                         out->rect_float);
1358         } else {
1359                 do_drop_effect_byte(
1360                         facf0, facf1, x, y,
1361                         (char*) ibuf1->rect, (char*) ibuf2->rect,
1362                         (char*) out->rect);
1363         }
1364 }
1365
1366 /* **********************************************************************
1367    MUL
1368    ********************************************************************** */
1369
1370 static void do_mul_effect_byte(float facf0, float facf1, int x, int y, 
1371                                unsigned char *rect1, unsigned char *rect2, 
1372                                unsigned char *out)
1373 {
1374         int  xo, fac1, fac3;
1375         char *rt1, *rt2, *rt;
1376
1377         xo= x;
1378         rt1= (char *)rect1;
1379         rt2= (char *)rect2;
1380         rt= (char *)out;
1381
1382         fac1= (int)(256.0*facf0);
1383         fac3= (int)(256.0*facf1);
1384
1385         /* formula:
1386          *              fac*(a*b) + (1-fac)*a  => fac*a*(b-1)+a
1387          */
1388
1389         while(y--) {
1390
1391                 x= xo;
1392                 while(x--) {
1393
1394                         rt[0]= rt1[0] + ((fac1*rt1[0]*(rt2[0]-256))>>16);
1395                         rt[1]= rt1[1] + ((fac1*rt1[1]*(rt2[1]-256))>>16);
1396                         rt[2]= rt1[2] + ((fac1*rt1[2]*(rt2[2]-256))>>16);
1397                         rt[3]= rt1[3] + ((fac1*rt1[3]*(rt2[3]-256))>>16);
1398
1399                         rt1+= 4; rt2+= 4; rt+= 4;
1400                 }
1401
1402                 if(y==0) break;
1403                 y--;
1404
1405                 x= xo;
1406                 while(x--) {
1407
1408                         rt[0]= rt1[0] + ((fac3*rt1[0]*(rt2[0]-256))>>16);
1409                         rt[1]= rt1[1] + ((fac3*rt1[1]*(rt2[1]-256))>>16);
1410                         rt[2]= rt1[2] + ((fac3*rt1[2]*(rt2[2]-256))>>16);
1411                         rt[3]= rt1[3] + ((fac3*rt1[3]*(rt2[3]-256))>>16);
1412
1413                         rt1+= 4; rt2+= 4; rt+= 4;
1414                 }
1415         }
1416 }
1417
1418 static void do_mul_effect_float(float facf0, float facf1, int x, int y, 
1419                                 float *rect1, float *rect2, 
1420                                 float *out)
1421 {
1422         int  xo;
1423         float fac1, fac3;
1424         float *rt1, *rt2, *rt;
1425
1426         xo= x;
1427         rt1= rect1;
1428         rt2= rect2;
1429         rt= out;
1430
1431         fac1= facf0;
1432         fac3= facf1;
1433
1434         /* formula:
1435          *              fac*(a*b) + (1-fac)*a  => fac*a*(b-1)+a
1436          */
1437
1438         while(y--) {
1439
1440                 x= xo;
1441                 while(x--) {
1442
1443                         rt[0]= rt1[0] + fac1*rt1[0]*(rt2[0]-1.0);
1444                         rt[1]= rt1[1] + fac1*rt1[1]*(rt2[1]-1.0);
1445                         rt[2]= rt1[2] + fac1*rt1[2]*(rt2[2]-1.0);
1446                         rt[3]= rt1[3] + fac1*rt1[3]*(rt2[3]-1.0);
1447
1448                         rt1+= 4; rt2+= 4; rt+= 4;
1449                 }
1450
1451                 if(y==0) break;
1452                 y--;
1453
1454                 x= xo;
1455                 while(x--) {
1456
1457                         rt[0]= rt1[0] + fac3*rt1[0]*(rt2[0]-1.0);
1458                         rt[1]= rt1[1] + fac3*rt1[1]*(rt2[1]-1.0);
1459                         rt[2]= rt1[2] + fac3*rt1[2]*(rt2[2]-1.0);
1460                         rt[3]= rt1[3] + fac3*rt1[3]*(rt2[3]-1.0);
1461
1462                         rt1+= 4; rt2+= 4; rt+= 4;
1463                 }
1464         }
1465 }
1466
1467 static void do_mul_effect(Sequence * seq,int cfra,
1468                           float facf0, float facf1, int x, int y, 
1469                           struct ImBuf *ibuf1, struct ImBuf *ibuf2, 
1470                           struct ImBuf *ibuf3, struct ImBuf *out)
1471 {
1472         if (out->rect_float) {
1473                 do_mul_effect_float(
1474                         facf0, facf1, x, y,
1475                         ibuf1->rect_float, ibuf2->rect_float,
1476                         out->rect_float);
1477         } else {
1478                 do_mul_effect_byte(
1479                         facf0, facf1, x, y,
1480                         (char*) ibuf1->rect, (char*) ibuf2->rect,
1481                         (char*) out->rect);
1482         }
1483 }
1484
1485 /* **********************************************************************
1486    WIPE
1487    ********************************************************************** */
1488
1489 // This function calculates the blur band for the wipe effects
1490 static float in_band(float width,float dist, float perc,int side,int dir){
1491         
1492         float t1,t2,alpha,percwidth;
1493         if(width == 0)
1494                 return (float)side;
1495         if(side == 1)
1496                 percwidth = width * perc;
1497         else
1498                 percwidth = width * (1 - perc);
1499         
1500         if(width < dist)
1501                 return side;
1502         
1503         t1 = dist / width;  //percentange of width that is
1504         t2 = 1 / width;  //amount of alpha per % point
1505         
1506         if(side == 1)
1507                 alpha = (t1*t2*100) + (1-perc); // add point's alpha contrib to current position in wipe
1508         else
1509                 alpha = (1-perc) - (t1*t2*100);
1510         
1511         if(dir == 0)
1512                 alpha = 1-alpha;
1513         return alpha;
1514 }
1515
1516 static float check_zone(int x, int y, int xo, int yo, 
1517                         Sequence *seq, float facf0) 
1518 {
1519    float posx, posy,hyp,hyp2,angle,hwidth,b1,b2,b3,pointdist;
1520    /*some future stuff
1521    float hyp3,hyp4,b4,b5           
1522    */
1523    float temp1,temp2,temp3,temp4; //some placeholder variables
1524    float halfx = xo/2;
1525    float halfy = yo/2;
1526    float widthf,output=0;
1527    WipeVars *wipe = (WipeVars *)seq->effectdata;
1528    int width;
1529
1530         angle = wipe->angle;
1531         if(angle < 0){
1532                 x = xo-x;
1533                 //y = yo-y
1534                 }
1535         angle = pow(fabs(angle)/45,log(xo)/log(2));
1536
1537         posy = facf0 * yo;
1538         if(wipe->forward){
1539                 posx = facf0 * xo;
1540                 posy = facf0 * yo;
1541         } else{
1542                 posx = xo - facf0 * xo;
1543                 posy = yo - facf0 * yo;
1544         }
1545    switch (wipe->wipetype) {
1546        case DO_SINGLE_WIPE:
1547          width = (int)(wipe->edgeWidth*((xo+yo)/2.0));
1548          hwidth = (float)width/2.0;       
1549                 
1550          if (angle == 0.0)angle = 0.000001;
1551          b1 = posy - (-angle)*posx;
1552          b2 = y - (-angle)*x;
1553          hyp  = fabs(angle*x+y+(-posy-angle*posx))/sqrt(angle*angle+1);
1554          if(angle < 0){
1555                  temp1 = b1;
1556                  b1 = b2;
1557                  b2 = temp1;
1558          }
1559          if(wipe->forward){      
1560                      if(b1 < b2)
1561                                 output = in_band(width,hyp,facf0,1,1);
1562                  else
1563                                 output = in_band(width,hyp,facf0,0,1);
1564                  }
1565                  else{   
1566                  if(b1 < b2)
1567                                 output = in_band(width,hyp,facf0,0,1);
1568                  else
1569                                 output = in_band(width,hyp,facf0,1,1);
1570                  }
1571                  break;
1572          
1573          
1574           case DO_DOUBLE_WIPE:
1575                  if(!wipe->forward)facf0 = 1-facf0;   // Go the other direction
1576
1577              width = (int)(wipe->edgeWidth*((xo+yo)/2.0));  // calculate the blur width
1578              hwidth = (float)width/2.0;       
1579              if (angle == 0)angle = 0.000001;
1580              b1 = posy/2 - (-angle)*posx/2;
1581              b3 = (yo-posy/2) - (-angle)*(xo-posx/2);
1582              b2 = y - (-angle)*x;
1583
1584              hyp = abs(angle*x+y+(-posy/2-angle*posx/2))/sqrt(angle*angle+1);
1585              hyp2 = abs(angle*x+y+(-(yo-posy/2)-angle*(xo-posx/2)))/sqrt(angle*angle+1);
1586              
1587              temp1 = xo*(1-facf0/2)-xo*facf0/2;
1588              temp2 = yo*(1-facf0/2)-yo*facf0/2;
1589                  pointdist = sqrt(temp1*temp1 + temp2*temp2);
1590
1591                          if(b2 < b1 && b2 < b3 ){
1592                                 if(hwidth < pointdist)
1593                                         output = in_band(hwidth,hyp,facf0,0,1);
1594                         }
1595                          else if(b2 > b1 && b2 > b3 ){
1596                                 if(hwidth < pointdist)
1597                                         output = in_band(hwidth,hyp2,facf0,0,1);        
1598                         } 
1599                      else{
1600                          if(  hyp < hwidth && hyp2 > hwidth )
1601                                  output = in_band(hwidth,hyp,facf0,1,1);
1602                          else if(  hyp > hwidth && hyp2 < hwidth )
1603                                          output = in_band(hwidth,hyp2,facf0,1,1);
1604                                  else
1605                                          output = in_band(hwidth,hyp2,facf0,1,1) * in_band(hwidth,hyp,facf0,1,1);
1606                      }
1607                      if(!wipe->forward)output = 1-output;
1608          break;     
1609          case DO_CLOCK_WIPE:
1610                         /*
1611                                 temp1: angle of effect center in rads
1612                                 temp2: angle of line through (halfx,halfy) and (x,y) in rads
1613                                 temp3: angle of low side of blur
1614                                 temp4: angle of high side of blur
1615                         */
1616                         output = 1-facf0;
1617                         widthf = wipe->edgeWidth*2*3.14159;
1618                         temp1 = 2 * 3.14159 * facf0;
1619                         
1620                         if(wipe->forward){
1621                                 temp1 = 2*3.14159-temp1;
1622                         }
1623                         
1624                         x = x - halfx;
1625                         y = y - halfy;
1626
1627                         temp2 = asin(abs(y)/sqrt(x*x + y*y));
1628                         if(x <= 0 && y >= 0)
1629                                 temp2 = 3.14159 - temp2;
1630                         else if(x<=0 && y <= 0)
1631                                 temp2 += 3.14159;
1632                         else if(x >= 0 && y <= 0)
1633                                 temp2 = 2*3.14159 - temp2;
1634                         
1635                         if(wipe->forward){
1636                                 temp3 = temp1-(widthf/2)*facf0;
1637                                 temp4 = temp1+(widthf/2)*(1-facf0);
1638                         }
1639                         else{
1640                                 temp3 = temp1-(widthf/2)*(1-facf0);
1641                                 temp4 = temp1+(widthf/2)*facf0;
1642                         }
1643                         if (temp3 < 0)  temp3 = 0;
1644                         if (temp4 > 2*3.14159) temp4 = 2*3.14159;
1645                         
1646                         
1647                         if(temp2 < temp3)
1648                                 output = 0;
1649                         else if (temp2 > temp4)
1650                                 output = 1;
1651                         else
1652                                 output = (temp2-temp3)/(temp4-temp3);
1653                         if(x == 0 && y == 0){
1654                                 output = 1;
1655                         }
1656                         if(output != output)
1657                                 output = 1;
1658                         if(wipe->forward)
1659                                 output = 1 - output;
1660         break;
1661         /* BOX WIPE IS NOT WORKING YET */
1662      /* case DO_CROSS_WIPE: */
1663         /* BOX WIPE IS NOT WORKING YET */
1664      /* case DO_BOX_WIPE: 
1665                  if(invert)facf0 = 1-facf0;
1666
1667              width = (int)(wipe->edgeWidth*((xo+yo)/2.0));
1668              hwidth = (float)width/2.0;       
1669              if (angle == 0)angle = 0.000001;
1670              b1 = posy/2 - (-angle)*posx/2;
1671              b3 = (yo-posy/2) - (-angle)*(xo-posx/2);
1672              b2 = y - (-angle)*x;
1673
1674              hyp = abs(angle*x+y+(-posy/2-angle*posx/2))/sqrt(angle*angle+1);
1675              hyp2 = abs(angle*x+y+(-(yo-posy/2)-angle*(xo-posx/2)))/sqrt(angle*angle+1);
1676              
1677              temp1 = xo*(1-facf0/2)-xo*facf0/2;
1678              temp2 = yo*(1-facf0/2)-yo*facf0/2;
1679                  pointdist = sqrt(temp1*temp1 + temp2*temp2);
1680
1681                          if(b2 < b1 && b2 < b3 ){
1682                                 if(hwidth < pointdist)
1683                                         output = in_band(hwidth,hyp,facf0,0,1);
1684                         }
1685                          else if(b2 > b1 && b2 > b3 ){
1686                                 if(hwidth < pointdist)
1687                                         output = in_band(hwidth,hyp2,facf0,0,1);        
1688                         } 
1689                      else{
1690                          if(  hyp < hwidth && hyp2 > hwidth )
1691                                  output = in_band(hwidth,hyp,facf0,1,1);
1692                          else if(  hyp > hwidth && hyp2 < hwidth )
1693                                          output = in_band(hwidth,hyp2,facf0,1,1);
1694                                  else
1695                                          output = in_band(hwidth,hyp2,facf0,1,1) * in_band(hwidth,hyp,facf0,1,1);
1696                      }
1697                  if(invert)facf0 = 1-facf0;
1698              angle = -1/angle;
1699              b1 = posy/2 - (-angle)*posx/2;
1700              b3 = (yo-posy/2) - (-angle)*(xo-posx/2);
1701              b2 = y - (-angle)*x;
1702
1703              hyp = abs(angle*x+y+(-posy/2-angle*posx/2))/sqrt(angle*angle+1);
1704              hyp2 = abs(angle*x+y+(-(yo-posy/2)-angle*(xo-posx/2)))/sqrt(angle*angle+1);
1705            
1706                  if(b2 < b1 && b2 < b3 ){
1707                                 if(hwidth < pointdist)
1708                                         output *= in_band(hwidth,hyp,facf0,0,1);
1709                         }
1710                          else if(b2 > b1 && b2 > b3 ){
1711                                 if(hwidth < pointdist)
1712                                         output *= in_band(hwidth,hyp2,facf0,0,1);       
1713                         } 
1714                      else{
1715                          if(  hyp < hwidth && hyp2 > hwidth )
1716                                  output *= in_band(hwidth,hyp,facf0,1,1);
1717                          else if(  hyp > hwidth && hyp2 < hwidth )
1718                                          output *= in_band(hwidth,hyp2,facf0,1,1);
1719                                  else
1720                                          output *= in_band(hwidth,hyp2,facf0,1,1) * in_band(hwidth,hyp,facf0,1,1);
1721                      }
1722                      
1723          break;*/
1724       case DO_IRIS_WIPE:
1725          if(xo > yo) yo = xo;
1726          else xo = yo;
1727          
1728                 if(!wipe->forward)
1729                         facf0 = 1-facf0;
1730
1731              width = (int)(wipe->edgeWidth*((xo+yo)/2.0));
1732              hwidth = (float)width/2.0; 
1733              
1734          temp1 = (halfx-(halfx)*facf0);     
1735                  pointdist = sqrt(temp1*temp1 + temp1*temp1);
1736                  
1737                  temp2 = sqrt((halfx-x)*(halfx-x)  +  (halfy-y)*(halfy-y));
1738                  if(temp2 > pointdist)
1739                          output = in_band(hwidth,fabs(temp2-pointdist),facf0,0,1);
1740                  else
1741                          output = in_band(hwidth,fabs(temp2-pointdist),facf0,1,1);
1742                  
1743                 if(!wipe->forward)
1744                         output = 1-output;
1745                         
1746          break;
1747    }
1748    if     (output < 0) output = 0;
1749    else if(output > 1) output = 1;
1750    return output;
1751 }
1752
1753 static void init_wipe_effect(Sequence *seq)
1754 {
1755         if(seq->effectdata)MEM_freeN(seq->effectdata);
1756         seq->effectdata = MEM_callocN(sizeof(struct WipeVars), "wipevars");
1757 }
1758
1759 static void free_wipe_effect(Sequence *seq)
1760 {
1761         if(seq->effectdata)MEM_freeN(seq->effectdata);
1762         seq->effectdata = 0;
1763 }
1764
1765 static void copy_wipe_effect(Sequence *dst, Sequence *src)
1766 {
1767         dst->effectdata = MEM_dupallocN(src->effectdata);
1768 }
1769
1770 static void do_wipe_effect_byte(Sequence *seq, float facf0, float facf1, 
1771                                 int x, int y, 
1772                                 unsigned char *rect1, 
1773                                 unsigned char *rect2, unsigned char *out)
1774 {
1775         int xo, yo;
1776         char *rt1, *rt2, *rt;
1777         rt1 = (char *)rect1;
1778         rt2 = (char *)rect2;
1779         rt = (char *)out;
1780
1781         xo = x;
1782         yo = y;
1783         for(y=0;y<yo;y++) {
1784                 for(x=0;x<xo;x++) {
1785                         float check = check_zone(x,y,xo,yo,seq,facf0);
1786                         if (check) {
1787                                 if (rt1) {
1788                                         rt[0] = (int)(rt1[0]*check)+ (int)(rt2[0]*(1-check));
1789                                         rt[1] = (int)(rt1[1]*check)+ (int)(rt2[1]*(1-check));
1790                                         rt[2] = (int)(rt1[2]*check)+ (int)(rt2[2]*(1-check));
1791                                         rt[3] = (int)(rt1[3]*check)+ (int)(rt2[3]*(1-check));
1792                                 } else {
1793                                         rt[0] = 0;
1794                                         rt[1] = 0;
1795                                         rt[2] = 0;
1796                                         rt[3] = 255;
1797                                 }
1798                         } else {
1799                                 if (rt2) {
1800                                         rt[0] = rt2[0];
1801                                         rt[1] = rt2[1];
1802                                         rt[2] = rt2[2];
1803                                         rt[3] = rt2[3];
1804                                 } else {
1805                                         rt[0] = 0;
1806                                         rt[1] = 0;
1807                                         rt[2] = 0;
1808                                         rt[3] = 255;
1809                                 }
1810                         }
1811
1812                         rt+=4;
1813                         if(rt1 !=NULL){
1814                                 rt1+=4;
1815                         }
1816                         if(rt2 !=NULL){
1817                                 rt2+=4;
1818                         }
1819                 }
1820         }
1821 }
1822
1823 static void do_wipe_effect_float(Sequence *seq, float facf0, float facf1, 
1824                                  int x, int y, 
1825                                  float *rect1, 
1826                                  float *rect2, float *out)
1827 {
1828         int xo, yo;
1829         float *rt1, *rt2, *rt;
1830         rt1 = rect1;
1831         rt2 = rect2;
1832         rt = out;
1833
1834         xo = x;
1835         yo = y;
1836         for(y=0;y<yo;y++) {
1837                 for(x=0;x<xo;x++) {
1838                         float check = check_zone(x,y,xo,yo,seq,facf0);
1839                         if (check) {
1840                                 if (rt1) {
1841                                         rt[0] = rt1[0]*check+ rt2[0]*(1-check);
1842                                         rt[1] = rt1[1]*check+ rt2[1]*(1-check);
1843                                         rt[2] = rt1[2]*check+ rt2[2]*(1-check);
1844                                         rt[3] = rt1[3]*check+ rt2[3]*(1-check);
1845                                 } else {
1846                                         rt[0] = 0;
1847                                         rt[1] = 0;
1848                                         rt[2] = 0;
1849                                         rt[3] = 1.0;
1850                                 }
1851                         } else {
1852                                 if (rt2) {
1853                                         rt[0] = rt2[0];
1854                                         rt[1] = rt2[1];
1855                                         rt[2] = rt2[2];
1856                                         rt[3] = rt2[3];
1857                                 } else {
1858                                         rt[0] = 0;
1859                                         rt[1] = 0;
1860                                         rt[2] = 0;
1861                                         rt[3] = 1.0;
1862                                 }
1863                         }
1864
1865                         rt+=4;
1866                         if(rt1 !=NULL){
1867                                 rt1+=4;
1868                         }
1869                         if(rt2 !=NULL){
1870                                 rt2+=4;
1871                         }
1872                 }
1873         }
1874 }
1875
1876 static void do_wipe_effect(Sequence * seq,int cfra,
1877                            float facf0, float facf1, int x, int y, 
1878                            struct ImBuf *ibuf1, struct ImBuf *ibuf2, 
1879                            struct ImBuf *ibuf3, struct ImBuf *out)
1880 {
1881         if (out->rect_float) {
1882                 do_wipe_effect_float(seq,
1883                                      facf0, facf1, x, y,
1884                                      ibuf1->rect_float, ibuf2->rect_float,
1885                                      out->rect_float);
1886         } else {
1887                 do_wipe_effect_byte(seq,
1888                                     facf0, facf1, x, y,
1889                                     (char*) ibuf1->rect, (char*) ibuf2->rect,
1890                                     (char*) out->rect);
1891         }
1892 }
1893
1894 /* **********************************************************************
1895    GLOW
1896    ********************************************************************** */
1897
1898 static void RVBlurBitmap2_byte ( unsigned char* map, int width,int height,
1899                                  float blur,
1900                                  int quality)
1901 /*      MUUUCCH better than the previous blur. */
1902 /*      We do the blurring in two passes which is a whole lot faster. */
1903 /*      I changed the math arount to implement an actual Gaussian */
1904 /*      distribution. */
1905 /* */
1906 /*      Watch out though, it tends to misbehaven with large blur values on */
1907 /*      a small bitmap.  Avoid avoid avoid. */
1908 /*=============================== */
1909 {
1910         unsigned char*  temp=NULL,*swap;
1911         float   *filter=NULL;
1912         int     x,y,i,fx,fy;
1913         int     index, ix, halfWidth;
1914         float   fval, k, curColor[3], curColor2[3], weight=0;
1915
1916         /*      If we're not really blurring, bail out */
1917         if (blur<=0)
1918                 return;
1919
1920         /*      Allocate memory for the tempmap and the blur filter matrix */
1921         temp= MEM_mallocN( (width*height*4), "blurbitmaptemp");
1922         if (!temp)
1923                 return;
1924
1925         /*      Allocate memory for the filter elements */
1926         halfWidth = ((quality+1)*blur);
1927         filter = (float *)MEM_mallocN(sizeof(float)*halfWidth*2, "blurbitmapfilter");
1928         if (!filter){
1929                 MEM_freeN (temp);
1930                 return;
1931         }
1932
1933         /*      Apparently we're calculating a bell curve */
1934         /*      based on the standard deviation (or radius) */
1935         /*      This code is based on an example */
1936         /*      posted to comp.graphics.algorithms by */
1937         /*      Blancmange (bmange@airdmhor.gen.nz) */
1938
1939         k = -1.0/(2.0*3.14159*blur*blur);
1940         fval=0;
1941         for (ix = 0;ix< halfWidth;ix++){
1942                 weight = (float)exp(k*(ix*ix));
1943                 filter[halfWidth - ix] = weight;
1944                 filter[halfWidth + ix] = weight;
1945         }
1946         filter[0] = weight;
1947
1948         /*      Normalize the array */
1949         fval=0;
1950         for (ix = 0;ix< halfWidth*2;ix++)
1951                 fval+=filter[ix];
1952
1953         for (ix = 0;ix< halfWidth*2;ix++)
1954                 filter[ix]/=fval;
1955
1956         /*      Blur the rows */
1957         for (y=0;y<height;y++){
1958                 /*      Do the left & right strips */
1959                 for (x=0;x<halfWidth;x++){
1960                         index=(x+y*width)*4;
1961                         fx=0;
1962                         curColor[0]=curColor[1]=curColor[2]=0;
1963                         curColor2[0]=curColor2[1]=curColor2[2]=0;
1964
1965                         for (i=x-halfWidth;i<x+halfWidth;i++){
1966                            if ((i>=0)&&(i<width)){
1967                                 curColor[0]+=map[(i+y*width)*4+GlowR]*filter[fx];
1968                                 curColor[1]+=map[(i+y*width)*4+GlowG]*filter[fx];
1969                                 curColor[2]+=map[(i+y*width)*4+GlowB]*filter[fx];
1970
1971                                 curColor2[0]+=map[(width-1-i+y*width)*4+GlowR] *
1972                                    filter[fx];
1973                                 curColor2[1]+=map[(width-1-i+y*width)*4+GlowG] *
1974                                    filter[fx];
1975                                 curColor2[2]+=map[(width-1-i+y*width)*4+GlowB] *
1976                                    filter[fx];
1977                                 }
1978                                 fx++;
1979                         }
1980                         temp[index+GlowR]=curColor[0];
1981                         temp[index+GlowG]=curColor[1];
1982                         temp[index+GlowB]=curColor[2];
1983
1984                         temp[((width-1-x+y*width)*4)+GlowR]=curColor2[0];
1985                         temp[((width-1-x+y*width)*4)+GlowG]=curColor2[1];
1986                         temp[((width-1-x+y*width)*4)+GlowB]=curColor2[2];
1987
1988                 }
1989                 /*      Do the main body */
1990                 for (x=halfWidth;x<width-halfWidth;x++){
1991                         index=(x+y*width)*4;
1992                         fx=0;
1993                         curColor[0]=curColor[1]=curColor[2]=0;
1994                         for (i=x-halfWidth;i<x+halfWidth;i++){
1995                                 curColor[0]+=map[(i+y*width)*4+GlowR]*filter[fx];
1996                                 curColor[1]+=map[(i+y*width)*4+GlowG]*filter[fx];
1997                                 curColor[2]+=map[(i+y*width)*4+GlowB]*filter[fx];
1998                                 fx++;
1999                         }
2000                         temp[index+GlowR]=curColor[0];
2001                         temp[index+GlowG]=curColor[1];
2002                         temp[index+GlowB]=curColor[2];
2003                 }
2004         }
2005
2006         /*      Swap buffers */
2007         swap=temp;temp=map;map=swap;
2008
2009
2010         /*      Blur the columns */
2011         for (x=0;x<width;x++){
2012                 /*      Do the top & bottom strips */
2013                 for (y=0;y<halfWidth;y++){
2014                         index=(x+y*width)*4;
2015                         fy=0;
2016                         curColor[0]=curColor[1]=curColor[2]=0;
2017                         curColor2[0]=curColor2[1]=curColor2[2]=0;
2018                         for (i=y-halfWidth;i<y+halfWidth;i++){
2019                                 if ((i>=0)&&(i<height)){
2020                                    /*   Bottom */
2021                                    curColor[0]+=map[(x+i*width)*4+GlowR]*filter[fy];
2022                                    curColor[1]+=map[(x+i*width)*4+GlowG]*filter[fy];
2023                                    curColor[2]+=map[(x+i*width)*4+GlowB]*filter[fy];
2024
2025                                    /*   Top */
2026                                    curColor2[0]+=map[(x+(height-1-i)*width) *
2027                                       4+GlowR]*filter[fy];
2028                                    curColor2[1]+=map[(x+(height-1-i)*width) *
2029                                       4+GlowG]*filter[fy];
2030                                    curColor2[2]+=map[(x+(height-1-i)*width) *
2031                                       4+GlowB]*filter[fy];
2032                                 }
2033                                 fy++;
2034                         }
2035                         temp[index+GlowR]=curColor[0];
2036                         temp[index+GlowG]=curColor[1];
2037                         temp[index+GlowB]=curColor[2];
2038                         temp[((x+(height-1-y)*width)*4)+GlowR]=curColor2[0];
2039                         temp[((x+(height-1-y)*width)*4)+GlowG]=curColor2[1];
2040                         temp[((x+(height-1-y)*width)*4)+GlowB]=curColor2[2];
2041                 }
2042                 /*      Do the main body */
2043                 for (y=halfWidth;y<height-halfWidth;y++){
2044                         index=(x+y*width)*4;
2045                         fy=0;
2046                         curColor[0]=curColor[1]=curColor[2]=0;
2047                         for (i=y-halfWidth;i<y+halfWidth;i++){
2048                                 curColor[0]+=map[(x+i*width)*4+GlowR]*filter[fy];
2049                                 curColor[1]+=map[(x+i*width)*4+GlowG]*filter[fy];
2050                                 curColor[2]+=map[(x+i*width)*4+GlowB]*filter[fy];
2051                                 fy++;
2052                         }
2053                         temp[index+GlowR]=curColor[0];
2054                         temp[index+GlowG]=curColor[1];
2055                         temp[index+GlowB]=curColor[2];
2056                 }
2057         }
2058
2059
2060         /*      Swap buffers */
2061         swap=temp;temp=map;map=swap;
2062
2063         /*      Tidy up  */
2064         MEM_freeN (filter);
2065         MEM_freeN (temp);
2066 }
2067
2068 static void RVBlurBitmap2_float ( float* map, int width,int height,
2069                                   float blur,
2070                                   int quality)
2071 /*      MUUUCCH better than the previous blur. */
2072 /*      We do the blurring in two passes which is a whole lot faster. */
2073 /*      I changed the math arount to implement an actual Gaussian */
2074 /*      distribution. */
2075 /* */
2076 /*      Watch out though, it tends to misbehaven with large blur values on */
2077 /*      a small bitmap.  Avoid avoid avoid. */
2078 /*=============================== */
2079 {
2080         float*  temp=NULL,*swap;
2081         float   *filter=NULL;
2082         int     x,y,i,fx,fy;
2083         int     index, ix, halfWidth;
2084         float   fval, k, curColor[3], curColor2[3], weight=0;
2085
2086         /*      If we're not really blurring, bail out */
2087         if (blur<=0)
2088                 return;
2089
2090         /*      Allocate memory for the tempmap and the blur filter matrix */
2091         temp= MEM_mallocN( (width*height*4*sizeof(float)), "blurbitmaptemp");
2092         if (!temp)
2093                 return;
2094
2095         /*      Allocate memory for the filter elements */
2096         halfWidth = ((quality+1)*blur);
2097         filter = (float *)MEM_mallocN(sizeof(float)*halfWidth*2, "blurbitmapfilter");
2098         if (!filter){
2099                 MEM_freeN (temp);
2100                 return;
2101         }
2102
2103         /*      Apparently we're calculating a bell curve */
2104         /*      based on the standard deviation (or radius) */
2105         /*      This code is based on an example */
2106         /*      posted to comp.graphics.algorithms by */
2107         /*      Blancmange (bmange@airdmhor.gen.nz) */
2108
2109         k = -1.0/(2.0*3.14159*blur*blur);
2110         fval=0;
2111         for (ix = 0;ix< halfWidth;ix++){
2112                 weight = (float)exp(k*(ix*ix));
2113                 filter[halfWidth - ix] = weight;
2114                 filter[halfWidth + ix] = weight;
2115         }
2116         filter[0] = weight;
2117
2118         /*      Normalize the array */
2119         fval=0;
2120         for (ix = 0;ix< halfWidth*2;ix++)
2121                 fval+=filter[ix];
2122
2123         for (ix = 0;ix< halfWidth*2;ix++)
2124                 filter[ix]/=fval;
2125
2126         /*      Blur the rows */
2127         for (y=0;y<height;y++){
2128                 /*      Do the left & right strips */
2129                 for (x=0;x<halfWidth;x++){
2130                         index=(x+y*width)*4;
2131                         fx=0;
2132                         curColor[0]=curColor[1]=curColor[2]=0;
2133                         curColor2[0]=curColor2[1]=curColor2[2]=0;
2134
2135                         for (i=x-halfWidth;i<x+halfWidth;i++){
2136                            if ((i>=0)&&(i<width)){
2137                                 curColor[0]+=map[(i+y*width)*4+GlowR]*filter[fx];
2138                                 curColor[1]+=map[(i+y*width)*4+GlowG]*filter[fx];
2139                                 curColor[2]+=map[(i+y*width)*4+GlowB]*filter[fx];
2140
2141                                 curColor2[0]+=map[(width-1-i+y*width)*4+GlowR] *
2142                                    filter[fx];
2143                                 curColor2[1]+=map[(width-1-i+y*width)*4+GlowG] *
2144                                    filter[fx];
2145                                 curColor2[2]+=map[(width-1-i+y*width)*4+GlowB] *
2146                                    filter[fx];
2147                                 }
2148                                 fx++;
2149                         }
2150                         temp[index+GlowR]=curColor[0];
2151                         temp[index+GlowG]=curColor[1];
2152                         temp[index+GlowB]=curColor[2];
2153
2154                         temp[((width-1-x+y*width)*4)+GlowR]=curColor2[0];
2155                         temp[((width-1-x+y*width)*4)+GlowG]=curColor2[1];
2156                         temp[((width-1-x+y*width)*4)+GlowB]=curColor2[2];
2157
2158                 }
2159                 /*      Do the main body */
2160                 for (x=halfWidth;x<width-halfWidth;x++){
2161                         index=(x+y*width)*4;
2162                         fx=0;
2163                         curColor[0]=curColor[1]=curColor[2]=0;
2164                         for (i=x-halfWidth;i<x+halfWidth;i++){
2165                                 curColor[0]+=map[(i+y*width)*4+GlowR]*filter[fx];
2166                                 curColor[1]+=map[(i+y*width)*4+GlowG]*filter[fx];
2167                                 curColor[2]+=map[(i+y*width)*4+GlowB]*filter[fx];
2168                                 fx++;
2169                         }
2170                         temp[index+GlowR]=curColor[0];
2171                         temp[index+GlowG]=curColor[1];
2172                         temp[index+GlowB]=curColor[2];
2173                 }
2174         }
2175
2176         /*      Swap buffers */
2177         swap=temp;temp=map;map=swap;
2178
2179
2180         /*      Blur the columns */
2181         for (x=0;x<width;x++){
2182                 /*      Do the top & bottom strips */
2183                 for (y=0;y<halfWidth;y++){
2184                         index=(x+y*width)*4;
2185                         fy=0;
2186                         curColor[0]=curColor[1]=curColor[2]=0;
2187                         curColor2[0]=curColor2[1]=curColor2[2]=0;
2188                         for (i=y-halfWidth;i<y+halfWidth;i++){
2189                                 if ((i>=0)&&(i<height)){
2190                                    /*   Bottom */
2191                                    curColor[0]+=map[(x+i*width)*4+GlowR]*filter[fy];
2192                                    curColor[1]+=map[(x+i*width)*4+GlowG]*filter[fy];
2193                                    curColor[2]+=map[(x+i*width)*4+GlowB]*filter[fy];
2194
2195                                    /*   Top */
2196                                    curColor2[0]+=map[(x+(height-1-i)*width) *
2197                                       4+GlowR]*filter[fy];
2198                                    curColor2[1]+=map[(x+(height-1-i)*width) *
2199                                       4+GlowG]*filter[fy];
2200                                    curColor2[2]+=map[(x+(height-1-i)*width) *
2201                                       4+GlowB]*filter[fy];
2202                                 }
2203                                 fy++;
2204                         }
2205                         temp[index+GlowR]=curColor[0];
2206                         temp[index+GlowG]=curColor[1];
2207                         temp[index+GlowB]=curColor[2];
2208                         temp[((x+(height-1-y)*width)*4)+GlowR]=curColor2[0];
2209                         temp[((x+(height-1-y)*width)*4)+GlowG]=curColor2[1];
2210                         temp[((x+(height-1-y)*width)*4)+GlowB]=curColor2[2];
2211                 }
2212                 /*      Do the main body */
2213                 for (y=halfWidth;y<height-halfWidth;y++){
2214                         index=(x+y*width)*4;
2215                         fy=0;
2216                         curColor[0]=curColor[1]=curColor[2]=0;
2217                         for (i=y-halfWidth;i<y+halfWidth;i++){
2218                                 curColor[0]+=map[(x+i*width)*4+GlowR]*filter[fy];
2219                                 curColor[1]+=map[(x+i*width)*4+GlowG]*filter[fy];
2220                                 curColor[2]+=map[(x+i*width)*4+GlowB]*filter[fy];
2221                                 fy++;
2222                         }
2223                         temp[index+GlowR]=curColor[0];
2224                         temp[index+GlowG]=curColor[1];
2225                         temp[index+GlowB]=curColor[2];
2226                 }
2227         }
2228
2229
2230         /*      Swap buffers */
2231         swap=temp;temp=map;map=swap;
2232
2233         /*      Tidy up  */
2234         MEM_freeN (filter);
2235         MEM_freeN (temp);
2236 }
2237
2238
2239 /*      Adds two bitmaps and puts the results into a third map. */
2240 /*      C must have been previously allocated but it may be A or B. */
2241 /*      We clamp values to 255 to prevent weirdness */
2242 /*=============================== */
2243 static void RVAddBitmaps_byte (unsigned char* a, unsigned char* b, unsigned char* c, int width, int height)
2244 {
2245         int     x,y,index;
2246
2247         for (y=0;y<height;y++){
2248                 for (x=0;x<width;x++){
2249                         index=(x+y*width)*4;
2250                         c[index+GlowR]=MIN2(255,a[index+GlowR]+b[index+GlowR]);
2251                         c[index+GlowG]=MIN2(255,a[index+GlowG]+b[index+GlowG]);
2252                         c[index+GlowB]=MIN2(255,a[index+GlowB]+b[index+GlowB]);
2253                         c[index+GlowA]=MIN2(255,a[index+GlowA]+b[index+GlowA]);
2254                 }
2255         }
2256 }
2257
2258 static void RVAddBitmaps_float (float* a, float* b, float* c, 
2259                                 int width, int height)
2260 {
2261         int     x,y,index;
2262
2263         for (y=0;y<height;y++){
2264                 for (x=0;x<width;x++){
2265                         index=(x+y*width)*4;
2266                         c[index+GlowR]=MIN2(1.0,a[index+GlowR]+b[index+GlowR]);
2267                         c[index+GlowG]=MIN2(1.0,a[index+GlowG]+b[index+GlowG]);
2268                         c[index+GlowB]=MIN2(1.0,a[index+GlowB]+b[index+GlowB]);
2269                         c[index+GlowA]=MIN2(1.0,a[index+GlowA]+b[index+GlowA]);
2270                 }
2271         }
2272 }
2273
2274 /*      For each pixel whose total luminance exceeds the threshold, */
2275 /*      Multiply it's value by BOOST and add it to the output map */
2276 static void RVIsolateHighlights_byte (unsigned char* in, unsigned char* out, 
2277                                       int width, int height, int threshold, 
2278                                       float boost, float clamp)
2279 {
2280         int x,y,index;
2281         int     intensity;
2282
2283
2284         for(y=0;y< height;y++) {
2285                 for (x=0;x< width;x++) {
2286                    index= (x+y*width)*4;
2287
2288                    /*   Isolate the intensity */
2289                    intensity=(in[index+GlowR]+in[index+GlowG]+in[index+GlowB]-threshold);
2290                    if (intensity>0){
2291                         out[index+GlowR]=MIN2(255*clamp, (in[index+GlowR]*boost*intensity)/255);
2292                         out[index+GlowG]=MIN2(255*clamp, (in[index+GlowG]*boost*intensity)/255);
2293                         out[index+GlowB]=MIN2(255*clamp, (in[index+GlowB]*boost*intensity)/255);
2294                         out[index+GlowA]=MIN2(255*clamp, (in[index+GlowA]*boost*intensity)/255);
2295                         }
2296                         else{
2297                                 out[index+GlowR]=0;
2298                                 out[index+GlowG]=0;
2299                                 out[index+GlowB]=0;
2300                                 out[index+GlowA]=0;
2301                         }
2302                 }
2303         }
2304 }
2305
2306 static void RVIsolateHighlights_float (float* in, float* out, 
2307                                       int width, int height, int threshold, 
2308                                       float boost, float clamp)
2309 {
2310         int x,y,index;
2311         float   intensity;
2312
2313
2314         for(y=0;y< height;y++) {
2315                 for (x=0;x< width;x++) {
2316                    index= (x+y*width)*4;
2317
2318                    /*   Isolate the intensity */
2319                    intensity=(in[index+GlowR]+in[index+GlowG]+in[index+GlowB]-threshold);
2320                    if (intensity>0){
2321                         out[index+GlowR]=MIN2(clamp, (in[index+GlowR]*boost*intensity));
2322                         out[index+GlowG]=MIN2(clamp, (in[index+GlowG]*boost*intensity));
2323                         out[index+GlowB]=MIN2(clamp, (in[index+GlowB]*boost*intensity));
2324                         out[index+GlowA]=MIN2(clamp, (in[index+GlowA]*boost*intensity));
2325                         }
2326                         else{
2327                                 out[index+GlowR]=0;
2328                                 out[index+GlowG]=0;
2329                                 out[index+GlowB]=0;
2330                                 out[index+GlowA]=0;
2331                         }
2332                 }
2333         }
2334 }
2335
2336 static void init_glow_effect(Sequence *seq)
2337 {
2338         GlowVars *glow;
2339
2340         if(seq->effectdata)MEM_freeN(seq->effectdata);
2341         seq->effectdata = MEM_callocN(sizeof(struct GlowVars), "glowvars");
2342
2343         glow = (GlowVars *)seq->effectdata;
2344         glow->fMini = 0.25;
2345         glow->fClamp = 1.0;
2346         glow->fBoost = 0.5;
2347         glow->dDist = 3.0;
2348         glow->dQuality = 3;
2349         glow->bNoComp = 0;
2350 }
2351
2352 static void free_glow_effect(Sequence *seq)
2353 {
2354         if(seq->effectdata)MEM_freeN(seq->effectdata);
2355         seq->effectdata = 0;
2356 }
2357
2358 static void copy_glow_effect(Sequence *dst, Sequence *src)
2359 {
2360         dst->effectdata = MEM_dupallocN(src->effectdata);
2361 }
2362
2363 //void do_glow_effect(Cast *cast, float facf0, float facf1, int xo, int yo, ImBuf *ibuf1, ImBuf *ibuf2, ImBuf *outbuf, ImBuf *use)
2364 static void do_glow_effect_byte(Sequence *seq, float facf0, float facf1, 
2365                                 int x, int y, char *rect1, 
2366                                 char *rect2, char *out)
2367 {
2368         unsigned char *outbuf=(unsigned char *)out;
2369         unsigned char *inbuf=(unsigned char *)rect1;
2370         GlowVars *glow = (GlowVars *)seq->effectdata;
2371
2372         RVIsolateHighlights_byte(inbuf, outbuf , x, y, glow->fMini*765, glow->fBoost, glow->fClamp);
2373         RVBlurBitmap2_byte (outbuf, x, y, glow->dDist,glow->dQuality);
2374         if (!glow->bNoComp)
2375                 RVAddBitmaps_byte (inbuf , outbuf, outbuf, x, y);
2376 }
2377
2378 static void do_glow_effect_float(Sequence *seq, float facf0, float facf1, 
2379                                  int x, int y, 
2380                                  float *rect1, float *rect2, float *out)
2381 {
2382         float *outbuf = out;
2383         float *inbuf = rect1;
2384         GlowVars *glow = (GlowVars *)seq->effectdata;
2385
2386         RVIsolateHighlights_float(inbuf, outbuf , x, y, glow->fMini*765, glow->fBoost, glow->fClamp);
2387         RVBlurBitmap2_float (outbuf, x, y, glow->dDist,glow->dQuality);
2388         if (!glow->bNoComp)
2389                 RVAddBitmaps_float (inbuf , outbuf, outbuf, x, y);
2390 }
2391
2392 static void do_glow_effect(Sequence * seq,int cfra,
2393                            float facf0, float facf1, int x, int y, 
2394                            struct ImBuf *ibuf1, struct ImBuf *ibuf2, 
2395                            struct ImBuf *ibuf3, struct ImBuf *out)
2396 {
2397         if (out->rect_float) {
2398                 do_glow_effect_float(seq,
2399                                      facf0, facf1, x, y,
2400                                      ibuf1->rect_float, ibuf2->rect_float,
2401                                      out->rect_float);
2402         } else {
2403                 do_glow_effect_byte(seq,
2404                                     facf0, facf1, x, y,
2405                                     (char*) ibuf1->rect, (char*) ibuf2->rect,
2406                                     (char*) out->rect);
2407         }
2408 }
2409
2410
2411 /* **********************************************************************
2412    sequence effect factory
2413    ********************************************************************** */
2414
2415
2416 static void init_noop(struct Sequence *seq)
2417 {
2418
2419 }
2420
2421 static void load_noop(struct Sequence *seq)
2422 {
2423
2424 }
2425
2426 static void init_plugin_noop(struct Sequence *seq, const char * fname)
2427 {
2428
2429 }
2430
2431 static void free_noop(struct Sequence *seq)
2432 {
2433
2434 }
2435
2436 static int early_out_noop(struct Sequence *seq,
2437                           float facf0, float facf1)
2438 {
2439         return 0;
2440 }
2441
2442 static int early_out_fade(struct Sequence *seq,
2443                           float facf0, float facf1)
2444 {
2445         if (facf0 == 0.0 && facf1 == 0.0) {
2446                 return 1;
2447         } else if (facf0 == 1.0 && facf1 == 1.0) {
2448                 return 2;
2449         }
2450         return 0;
2451 }
2452
2453 static int early_out_mul_input2(struct Sequence *seq,
2454                                 float facf0, float facf1)
2455 {
2456         if (facf0 == 0.0 && facf1 == 0.0) {
2457                 return 1;
2458         }
2459         return 0;
2460 }
2461
2462 static void get_default_fac_noop(struct Sequence *seq, int cfra,
2463                                  float * facf0, float * facf1)
2464 {
2465         *facf0 = *facf1 = 1.0;
2466 }
2467
2468 static void get_default_fac_fade(struct Sequence *seq, int cfra,
2469                                  float * facf0, float * facf1)
2470 {
2471         *facf0  = (float)(cfra - seq->startdisp);
2472         *facf1 = (float)(*facf0 + 0.5);
2473         *facf0 /= seq->len;
2474         *facf1 /= seq->len;
2475 }
2476
2477 static void do_overdrop_effect(struct Sequence * seq, int cfra,
2478                                float fac, float facf, 
2479                                int x, int y, struct ImBuf * ibuf1, 
2480                                struct ImBuf * ibuf2, 
2481                                struct ImBuf * ibuf3, 
2482                                struct ImBuf * out)
2483 {
2484         do_drop_effect(seq, cfra, fac, facf, x, y, 
2485                        ibuf1, ibuf2, ibuf3, out);
2486         do_alphaover_effect(seq, cfra, fac, facf, x, y, 
2487                             ibuf1, ibuf2, ibuf3, out);
2488 }
2489
2490 struct SeqEffectHandle get_sequence_effect(Sequence * seq)
2491 {
2492         struct SeqEffectHandle rval;
2493         int sequence_type = seq->type;
2494
2495         rval.init = init_noop;
2496         rval.init_plugin = init_plugin_noop;
2497         rval.load = load_noop;
2498         rval.free = free_noop;
2499         rval.early_out = early_out_noop;
2500         rval.get_default_fac = get_default_fac_noop;
2501         rval.execute = NULL;
2502         rval.copy = NULL;
2503
2504         switch (sequence_type) {
2505         case SEQ_CROSS:
2506                 rval.execute = do_cross_effect;
2507                 rval.early_out = early_out_fade;
2508                 rval.get_default_fac = get_default_fac_fade;
2509                 break;
2510         case SEQ_GAMCROSS:
2511                 rval.init = init_gammacross;
2512                 rval.load = load_gammacross;
2513                 rval.free = free_gammacross;
2514                 rval.early_out = early_out_fade;
2515                 rval.get_default_fac = get_default_fac_fade;
2516                 rval.execute = do_gammacross_effect;
2517                 break;
2518         case SEQ_ADD:
2519                 rval.execute = do_add_effect;
2520                 rval.early_out = early_out_mul_input2;
2521                 break;
2522         case SEQ_SUB:
2523                 rval.execute = do_sub_effect;
2524                 rval.early_out = early_out_mul_input2;
2525                 break;
2526         case SEQ_MUL:
2527                 rval.execute = do_mul_effect;
2528                 rval.early_out = early_out_mul_input2;
2529                 break;
2530         case SEQ_ALPHAOVER:
2531                 rval.init = init_alpha_over_or_under;
2532                 rval.execute = do_alphaover_effect;
2533                 break;
2534         case SEQ_OVERDROP:
2535                 rval.execute = do_overdrop_effect;
2536                 break;
2537         case SEQ_ALPHAUNDER:
2538                 rval.init = init_alpha_over_or_under;
2539                 rval.execute = do_alphaunder_effect;
2540                 break;
2541         case SEQ_WIPE:
2542                 rval.init = init_wipe_effect;
2543                 rval.free = free_wipe_effect;
2544                 rval.copy = copy_wipe_effect;
2545                 rval.early_out = early_out_fade;
2546                 rval.get_default_fac = get_default_fac_fade;
2547                 rval.execute = do_wipe_effect;
2548                 break;
2549         case SEQ_GLOW:
2550                 rval.init = init_glow_effect;
2551                 rval.free = free_glow_effect;
2552                 rval.copy = copy_glow_effect;
2553                 rval.execute = do_glow_effect;
2554                 break;
2555         case SEQ_PLUGIN:
2556                 rval.init_plugin = init_plugin;
2557                 rval.load = load_plugin;
2558                 rval.free = free_plugin;
2559                 rval.copy = copy_plugin;
2560                 rval.execute = do_plugin_effect;
2561                 rval.early_out = do_plugin_early_out;
2562                 rval.get_default_fac = get_default_fac_fade;
2563                 break;
2564         }
2565
2566         if (seq->flag & SEQ_EFFECT_NOT_LOADED) {
2567                 rval.load(seq);
2568                 seq->flag &= ~SEQ_EFFECT_NOT_LOADED;
2569         }
2570
2571         return rval;
2572 }