Fix #27622: Sequencer Wipe Angle Incorrect
[blender.git] / source / blender / blenkernel / intern / seqeffects.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
19  * All rights reserved.
20  *
21  * Contributor(s): 
22  * - Blender Foundation, 2003-2009
23  * - Peter Schlaile <peter [at] schlaile [dot] de> 2005/2006
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  */
27
28 /** \file blender/blenkernel/intern/seqeffects.c
29  *  \ingroup bke
30  */
31
32
33 #include <string.h>
34 #include <math.h>
35 #include <stdlib.h>
36
37 #include "MEM_guardedalloc.h"
38 #include "BLI_dynlib.h"
39
40 #include "BLI_math.h" /* windows needs for M_PI */
41 #include "BLI_utildefines.h"
42 #include "BLI_string.h"
43
44 #include "DNA_scene_types.h"
45 #include "DNA_sequence_types.h"
46 #include "DNA_anim_types.h"
47
48 #include "BKE_fcurve.h"
49 #include "BKE_main.h"
50 #include "BKE_plugin_types.h"
51 #include "BKE_sequencer.h"
52 #include "BKE_texture.h"
53 #include "BKE_utildefines.h"
54
55 #include "IMB_imbuf_types.h"
56 #include "IMB_imbuf.h"
57
58 #include "RNA_access.h"
59
60 /* **** XXX **** */
61 static void error(const char *UNUSED(error), ...) {}
62
63 #define INT     96
64 #define FLO     128
65
66 /* **** XXX **** */
67
68 /* Glow effect */
69 enum {
70         GlowR=0,
71         GlowG=1,
72         GlowB=2,
73         GlowA=3
74 };
75
76 static struct ImBuf * prepare_effect_imbufs(
77         SeqRenderData context,
78         struct ImBuf *ibuf1, struct ImBuf *ibuf2,
79         struct ImBuf *ibuf3)
80 {
81         struct ImBuf * out;
82         int x = context.rectx;
83         int y = context.recty;
84
85         if (!ibuf1 && !ibuf2 && !ibuf3) {
86                 /* hmmm, global float option ? */
87                 out = IMB_allocImBuf((short)x, (short)y, 32, IB_rect);
88         } else if ((ibuf1 && ibuf1->rect_float) || 
89                    (ibuf2 && ibuf2->rect_float) || 
90                    (ibuf3 && ibuf3->rect_float)) {
91                 /* if any inputs are rectfloat, output is float too */
92
93                 out = IMB_allocImBuf((short)x, (short)y, 32, IB_rectfloat);
94         } else {
95                 out = IMB_allocImBuf((short)x, (short)y, 32, IB_rect);
96         }
97         
98         if (ibuf1 && !ibuf1->rect_float && out->rect_float) {
99                 IMB_float_from_rect_simple(ibuf1);
100         }
101         if (ibuf2 && !ibuf2->rect_float && out->rect_float) {
102                 IMB_float_from_rect_simple(ibuf2);
103         }
104         if (ibuf3 && !ibuf3->rect_float && out->rect_float) {
105                 IMB_float_from_rect_simple(ibuf3);
106         }
107         
108         if (ibuf1 && !ibuf1->rect && !out->rect_float) {
109                 IMB_rect_from_float(ibuf1);
110         }
111         if (ibuf2 && !ibuf2->rect && !out->rect_float) {
112                 IMB_rect_from_float(ibuf2);
113         }
114         if (ibuf3 && !ibuf3->rect && !out->rect_float) {
115                 IMB_rect_from_float(ibuf3);
116         }
117                         
118         return out;
119 }
120
121 /* **********************************************************************
122    PLUGINS
123    ********************************************************************** */
124
125 static void open_plugin_seq(PluginSeq *pis, const char *seqname)
126 {
127         int (*version)(void);
128         void* (*alloc_private)(void);
129         char *cp;
130
131         /* to be sure: (is tested for) */
132         pis->doit= NULL;
133         pis->pname= NULL;
134         pis->varstr= NULL;
135         pis->cfra= NULL;
136         pis->version= 0;
137         pis->instance_private_data = NULL;
138
139         /* clear the error list */
140         BLI_dynlib_get_error_as_string(NULL);
141
142         /* if(pis->handle) BLI_dynlib_close(pis->handle); */
143         /* pis->handle= 0; */
144
145         /* open the needed object */
146         pis->handle= BLI_dynlib_open(pis->name);
147         if(test_dlerr(pis->name, pis->name)) return;
148
149         if (pis->handle != NULL) {
150                 /* find the address of the version function */
151                 version= (int (*)(void))BLI_dynlib_find_symbol(pis->handle, "plugin_seq_getversion");
152                 if (test_dlerr(pis->name, "plugin_seq_getversion")) return;
153
154                 if (version != NULL) {
155                         pis->version= version();
156                         if (pis->version >= 2 && pis->version <= 6) {
157                                 int (*info_func)(PluginInfo *);
158                                 PluginInfo *info= (PluginInfo*) MEM_mallocN(sizeof(PluginInfo), "plugin_info");
159
160                                 info_func= (int (*)(PluginInfo *))BLI_dynlib_find_symbol(pis->handle, "plugin_getinfo");
161
162                                 if(info_func == NULL) error("No info func");
163                                 else {
164                                         info_func(info);
165
166                                         pis->pname= info->name;
167                                         pis->vars= info->nvars;
168                                         pis->cfra= info->cfra;
169
170                                         pis->varstr= info->varstr;
171
172                                         pis->doit= (void(*)(void))info->seq_doit;
173                                         if (info->init)
174                                                 info->init();
175                                 }
176                                 MEM_freeN(info);
177
178                                 cp= BLI_dynlib_find_symbol(pis->handle, "seqname");
179                                 if(cp) BLI_strncpy(cp, seqname, 21);
180                         } else {
181                                 printf ("Plugin returned unrecognized version number\n");
182                                 return;
183                         }
184                 }
185                 alloc_private = (void* (*)(void))BLI_dynlib_find_symbol(
186                         pis->handle, "plugin_seq_alloc_private_data");
187                 if (alloc_private) {
188                         pis->instance_private_data = alloc_private();
189                 }
190                 
191                 pis->current_private_data = (void**) 
192                         BLI_dynlib_find_symbol(
193                                 pis->handle, "plugin_private_data");
194         }
195 }
196
197 static PluginSeq *add_plugin_seq(const char *str, const char *seqname)
198 {
199         PluginSeq *pis;
200         VarStruct *varstr;
201         int a;
202
203         pis= MEM_callocN(sizeof(PluginSeq), "PluginSeq");
204
205         BLI_strncpy(pis->name, str, FILE_MAX);
206         open_plugin_seq(pis, seqname);
207
208         if(pis->doit==NULL) {
209                 if(pis->handle==NULL) error("no plugin: %s", str);
210                 else error("in plugin: %s", str);
211                 MEM_freeN(pis);
212                 return NULL;
213         }
214
215         /* default values */
216         varstr= pis->varstr;
217         for(a=0; a<pis->vars; a++, varstr++) {
218                 if( (varstr->type & FLO)==FLO)
219                         pis->data[a]= varstr->def;
220                 else if( (varstr->type & INT)==INT)
221                         *((int *)(pis->data+a))= (int) varstr->def;
222         }
223
224         return pis;
225 }
226
227 static void free_plugin_seq(PluginSeq *pis)
228 {
229         if(pis==NULL) return;
230
231         /* no BLI_dynlib_close: same plugin can be opened multiple times with 1 handle */
232
233         if (pis->instance_private_data) {
234                 void (*free_private)(void *);
235
236                 free_private = (void (*)(void *))BLI_dynlib_find_symbol(
237                         pis->handle, "plugin_seq_free_private_data");
238                 if (free_private) {
239                         free_private(pis->instance_private_data);
240                 }
241         }
242
243         MEM_freeN(pis);
244 }
245
246 static void init_plugin(Sequence * seq, const char * fname)
247 {
248         seq->plugin= (PluginSeq *)add_plugin_seq(fname, seq->name+2);
249 }
250
251 /* 
252  * FIXME: should query plugin! Could be generator, that needs zero inputs...
253  */
254 static int num_inputs_plugin(void)
255 {
256         return 1;
257 }
258
259 static void load_plugin(Sequence * seq)
260 {
261         if (seq) {
262                 open_plugin_seq(seq->plugin, seq->name+2);
263         }
264 }
265
266 static void copy_plugin(Sequence * dst, Sequence * src)
267 {
268         if(src->plugin) {
269                 dst->plugin= MEM_dupallocN(src->plugin);
270                 open_plugin_seq(dst->plugin, dst->name+2);
271         }
272 }
273
274 static ImBuf * IMB_cast_away_list(ImBuf * i)
275 {
276         if (!i) {
277                 return NULL;
278         }
279         return (ImBuf*) (((void**) i) + 2);
280 }
281
282 static struct ImBuf * do_plugin_effect(
283         SeqRenderData context, Sequence *seq, float cfra,
284         float facf0, float facf1,
285         struct ImBuf *ibuf1, struct ImBuf *ibuf2, 
286         struct ImBuf *ibuf3)
287 {
288         char *cp;
289         int float_rendering;
290         int use_temp_bufs = 0; /* Are needed since blur.c (and maybe some other
291                                   old plugins) do very bad stuff
292                                   with imbuf-internals */
293
294         struct ImBuf * out = prepare_effect_imbufs(context,ibuf1, ibuf2, ibuf3);
295         int x = context.rectx;
296         int y = context.recty;
297
298         if(seq->plugin && seq->plugin->doit) {
299                 
300                 if(seq->plugin->cfra) 
301                         *(seq->plugin->cfra)= cfra;
302                 
303                 cp = BLI_dynlib_find_symbol(
304                         seq->plugin->handle, "seqname");
305
306                 if(cp) strncpy(cp, seq->name+2, 22);
307
308                 if (seq->plugin->current_private_data) {
309                         *seq->plugin->current_private_data 
310                                 = seq->plugin->instance_private_data;
311                 }
312
313                 float_rendering = (out->rect_float != NULL);
314
315                 if (seq->plugin->version<=3 && float_rendering) {
316                         use_temp_bufs = 1;
317
318                         if (ibuf1) {
319                                 ibuf1 = IMB_dupImBuf(ibuf1);
320                                 IMB_rect_from_float(ibuf1);
321                                 imb_freerectfloatImBuf(ibuf1);
322                                 ibuf1->flags &= ~IB_rectfloat;
323                         }
324                         if (ibuf2) {
325                                 ibuf2 = IMB_dupImBuf(ibuf2);
326                                 IMB_rect_from_float(ibuf2);
327                                 imb_freerectfloatImBuf(ibuf2);
328                                 ibuf2->flags &= ~IB_rectfloat;
329                         } 
330                         if (ibuf3) {
331                                 ibuf3 = IMB_dupImBuf(ibuf3);
332                                 IMB_rect_from_float(ibuf3);
333                                 imb_freerectfloatImBuf(ibuf3);
334                                 ibuf3->flags &= ~IB_rectfloat;
335                         } 
336                         if (!out->rect) imb_addrectImBuf(out);
337                         imb_freerectfloatImBuf(out);
338                         out->flags &= ~IB_rectfloat;
339                 }
340
341                 if (seq->plugin->version<=2) {
342                         if(ibuf1) IMB_convert_rgba_to_abgr(ibuf1);
343                         if(ibuf2) IMB_convert_rgba_to_abgr(ibuf2);
344                         if(ibuf3) IMB_convert_rgba_to_abgr(ibuf3);
345                 }
346
347                 if (seq->plugin->version<=4) {
348                         ((SeqDoit)seq->plugin->doit)(
349                                 seq->plugin->data, facf0, facf1, x, y,
350                                 IMB_cast_away_list(ibuf1), 
351                                 IMB_cast_away_list(ibuf2), 
352                                 IMB_cast_away_list(out), 
353                                 IMB_cast_away_list(ibuf3));
354                 } else {
355                         ((SeqDoit)seq->plugin->doit)(
356                                 seq->plugin->data, facf0, facf1, x, y,
357                                 ibuf1, ibuf2, out, ibuf3);
358                 }
359
360                 if (seq->plugin->version<=2) {
361                         if (!use_temp_bufs) {
362                                 if(ibuf1) IMB_convert_rgba_to_abgr(ibuf1);
363                                 if(ibuf2) IMB_convert_rgba_to_abgr(ibuf2);
364                                 if(ibuf3) IMB_convert_rgba_to_abgr(ibuf3);
365                         }
366                         IMB_convert_rgba_to_abgr(out);
367                 }
368                 if (seq->plugin->version<=3 && float_rendering) {
369                         IMB_float_from_rect_simple(out);
370                 }
371
372                 if (use_temp_bufs) {
373                         if (ibuf1) IMB_freeImBuf(ibuf1);
374                         if (ibuf2) IMB_freeImBuf(ibuf2);
375                         if (ibuf3) IMB_freeImBuf(ibuf3);
376                 }
377         }
378         return out;
379 }
380
381 static int do_plugin_early_out(struct Sequence *UNUSED(seq),
382                                    float UNUSED(facf0), float UNUSED(facf1))
383 {
384         return 0;
385 }
386
387 static void free_plugin(struct Sequence * seq)
388 {
389         free_plugin_seq(seq->plugin);
390         seq->plugin = NULL;
391 }
392
393 /* **********************************************************************
394    ALPHA OVER
395    ********************************************************************** */
396
397 static void init_alpha_over_or_under(Sequence * seq)
398 {
399         Sequence * seq1 = seq->seq1;
400         Sequence * seq2 = seq->seq2;
401
402         seq->seq2= seq1;
403         seq->seq1= seq2;
404 }
405
406 static void do_alphaover_effect_byte(float facf0, float facf1, int x, int y, 
407                                          char * rect1, char *rect2, char *out)
408 {
409         int fac2, mfac, fac, fac4;
410         int xo, tempc;
411         char *rt1, *rt2, *rt;
412
413         xo= x;
414         rt1= (char *)rect1;
415         rt2= (char *)rect2;
416         rt= (char *)out;
417
418         fac2= (int)(256.0f*facf0);
419         fac4= (int)(256.0f*facf1);
420
421         while(y--) {
422
423                 x= xo;
424                 while(x--) {
425
426                         /* rt = rt1 over rt2  (alpha from rt1) */
427
428                         fac= fac2;
429                         mfac= 256 - ( (fac2*rt1[3])>>8 );
430
431                         if(fac==0) *( (unsigned int *)rt) = *( (unsigned int *)rt2);
432                         else if(mfac==0) *( (unsigned int *)rt) = *( (unsigned int *)rt1);
433                         else {
434                                 tempc= ( fac*rt1[0] + mfac*rt2[0])>>8;
435                                 if(tempc>255) rt[0]= 255; else rt[0]= tempc;
436                                 tempc= ( fac*rt1[1] + mfac*rt2[1])>>8;
437                                 if(tempc>255) rt[1]= 255; else rt[1]= tempc;
438                                 tempc= ( fac*rt1[2] + mfac*rt2[2])>>8;
439                                 if(tempc>255) rt[2]= 255; else rt[2]= tempc;
440                                 tempc= ( fac*rt1[3] + mfac*rt2[3])>>8;
441                                 if(tempc>255) rt[3]= 255; else rt[3]= tempc;
442                         }
443                         rt1+= 4; rt2+= 4; rt+= 4;
444                 }
445
446                 if(y==0) break;
447                 y--;
448
449                 x= xo;
450                 while(x--) {
451
452                         fac= fac4;
453                         mfac= 256 - ( (fac4*rt1[3])>>8 );
454
455                         if(fac==0) *( (unsigned int *)rt) = *( (unsigned int *)rt2);
456                         else if(mfac==0) *( (unsigned int *)rt) = *( (unsigned int *)rt1);
457                         else {
458                                 tempc= ( fac*rt1[0] + mfac*rt2[0])>>8;
459                                 if(tempc>255) rt[0]= 255; else rt[0]= tempc;
460                                 tempc= ( fac*rt1[1] + mfac*rt2[1])>>8;
461                                 if(tempc>255) rt[1]= 255; else rt[1]= tempc;
462                                 tempc= ( fac*rt1[2] + mfac*rt2[2])>>8;
463                                 if(tempc>255) rt[2]= 255; else rt[2]= tempc;
464                                 tempc= ( fac*rt1[3] + mfac*rt2[3])>>8;
465                                 if(tempc>255) rt[3]= 255; else rt[3]= tempc;
466                         }
467                         rt1+= 4; rt2+= 4; rt+= 4;
468                 }
469         }
470 }
471
472 static void do_alphaover_effect_float(float facf0, float facf1, int x, int y, 
473                                           float * rect1, float *rect2, float *out)
474 {
475         float fac2, mfac, fac, fac4;
476         int xo;
477         float *rt1, *rt2, *rt;
478
479         xo= x;
480         rt1= rect1;
481         rt2= rect2;
482         rt= out;
483
484         fac2= facf0;
485         fac4= facf1;
486
487         while(y--) {
488
489                 x= xo;
490                 while(x--) {
491
492                         /* rt = rt1 over rt2  (alpha from rt1) */
493
494                         fac= fac2;
495                         mfac= 1.0f - (fac2*rt1[3]) ;
496
497                         if(fac <= 0.0f) {
498                                 memcpy(rt, rt2, 4 * sizeof(float));
499                         } else if(mfac <=0) {
500                                 memcpy(rt, rt1, 4 * sizeof(float));
501                         } else {
502                                 rt[0] = fac*rt1[0] + mfac*rt2[0];
503                                 rt[1] = fac*rt1[1] + mfac*rt2[1];
504                                 rt[2] = fac*rt1[2] + mfac*rt2[2];
505                                 rt[3] = fac*rt1[3] + mfac*rt2[3];
506                         }
507                         rt1+= 4; rt2+= 4; rt+= 4;
508                 }
509
510                 if(y==0) break;
511                 y--;
512
513                 x= xo;
514                 while(x--) {
515
516                         fac= fac4;
517                         mfac= 1.0f - (fac4*rt1[3]);
518
519                         if(fac <= 0.0f) {
520                                 memcpy(rt, rt2, 4 * sizeof(float));
521                         } else if(mfac <= 0.0f) {
522                                 memcpy(rt, rt1, 4 * sizeof(float));
523                         } else {
524                                 rt[0] = fac*rt1[0] + mfac*rt2[0];
525                                 rt[1] = fac*rt1[1] + mfac*rt2[1];
526                                 rt[2] = fac*rt1[2] + mfac*rt2[2];
527                                 rt[3] = fac*rt1[3] + mfac*rt2[3];
528                         }
529                         rt1+= 4; rt2+= 4; rt+= 4;
530                 }
531         }
532 }
533
534 static struct ImBuf * do_alphaover_effect(
535         SeqRenderData context, Sequence *UNUSED(seq), float UNUSED(cfra),
536         float facf0, float facf1, 
537         struct ImBuf *ibuf1, struct ImBuf *ibuf2, 
538         struct ImBuf *ibuf3)
539 {
540         struct ImBuf * out = prepare_effect_imbufs(context,ibuf1, ibuf2, ibuf3);
541
542         if (out->rect_float) {
543                 do_alphaover_effect_float(
544                         facf0, facf1, context.rectx, context.recty,
545                         ibuf1->rect_float, ibuf2->rect_float,
546                         out->rect_float);
547         } else {
548                 do_alphaover_effect_byte(
549                         facf0, facf1, context.rectx, context.recty,
550                         (char*) ibuf1->rect, (char*) ibuf2->rect,
551                         (char*) out->rect);
552         }
553         return out;
554 }
555
556
557 /* **********************************************************************
558    ALPHA UNDER
559    ********************************************************************** */
560
561 static void do_alphaunder_effect_byte(
562         float facf0, float facf1, int x, int y, char *rect1, 
563         char *rect2, char *out)
564 {
565         int fac2, mfac, fac, fac4;
566         int xo;
567         char *rt1, *rt2, *rt;
568
569         xo= x;
570         rt1= rect1;
571         rt2= rect2;
572         rt= out;
573
574         fac2= (int)(256.0f*facf0);
575         fac4= (int)(256.0f*facf1);
576
577         while(y--) {
578
579                 x= xo;
580                 while(x--) {
581
582                         /* rt = rt1 under rt2  (alpha from rt2) */
583
584                         /* this complex optimalisation is because the
585                          * 'skybuf' can be crossed in
586                          */
587                         if(rt2[3]==0 && fac2==256) *( (unsigned int *)rt) = *( (unsigned int *)rt1);
588                         else if(rt2[3]==255) *( (unsigned int *)rt) = *( (unsigned int *)rt2);
589                         else {
590                                 mfac= rt2[3];
591                                 fac= (fac2*(256-mfac))>>8;
592
593                                 if(fac==0) *( (unsigned int *)rt) = *( (unsigned int *)rt2);
594                                 else {
595                                         rt[0]= ( fac*rt1[0] + mfac*rt2[0])>>8;
596                                         rt[1]= ( fac*rt1[1] + mfac*rt2[1])>>8;
597                                         rt[2]= ( fac*rt1[2] + mfac*rt2[2])>>8;
598                                         rt[3]= ( fac*rt1[3] + mfac*rt2[3])>>8;
599                                 }
600                         }
601                         rt1+= 4; rt2+= 4; rt+= 4;
602                 }
603
604                 if(y==0) break;
605                 y--;
606
607                 x= xo;
608                 while(x--) {
609
610                         if(rt2[3]==0 && fac4==256) *( (unsigned int *)rt) = *( (unsigned int *)rt1);
611                         else if(rt2[3]==255) *( (unsigned int *)rt) = *( (unsigned int *)rt2);
612                         else {
613                                 mfac= rt2[3];
614                                 fac= (fac4*(256-mfac))>>8;
615
616                                 if(fac==0) *( (unsigned int *)rt) = *( (unsigned int *)rt2);
617                                 else {
618                                         rt[0]= ( fac*rt1[0] + mfac*rt2[0])>>8;
619                                         rt[1]= ( fac*rt1[1] + mfac*rt2[1])>>8;
620                                         rt[2]= ( fac*rt1[2] + mfac*rt2[2])>>8;
621                                         rt[3]= ( fac*rt1[3] + mfac*rt2[3])>>8;
622                                 }
623                         }
624                         rt1+= 4; rt2+= 4; rt+= 4;
625                 }
626         }
627 }
628
629
630 static void do_alphaunder_effect_float(float facf0, float facf1, int x, int y, 
631                                            float *rect1, float *rect2, 
632                                            float *out)
633 {
634         float fac2, mfac, fac, fac4;
635         int xo;
636         float *rt1, *rt2, *rt;
637
638         xo= x;
639         rt1= rect1;
640         rt2= rect2;
641         rt= out;
642
643         fac2= facf0;
644         fac4= facf1;
645
646         while(y--) {
647
648                 x= xo;
649                 while(x--) {
650
651                         /* rt = rt1 under rt2  (alpha from rt2) */
652
653                         /* this complex optimalisation is because the
654                          * 'skybuf' can be crossed in
655                          */
656                         if( rt2[3]<=0 && fac2 >= 1.0f) {
657                                 memcpy(rt, rt1, 4 * sizeof(float));
658                         } else if(rt2[3] >= 1.0f) {
659                                 memcpy(rt, rt2, 4 * sizeof(float));
660                         } else {
661                                 mfac = rt2[3];
662                                 fac = fac2 * (1.0f - mfac);
663
664                                 if(fac == 0) {
665                                         memcpy(rt, rt2, 4 * sizeof(float));
666                                 } else {
667                                         rt[0]= fac*rt1[0] + mfac*rt2[0];
668                                         rt[1]= fac*rt1[1] + mfac*rt2[1];
669                                         rt[2]= fac*rt1[2] + mfac*rt2[2];
670                                         rt[3]= fac*rt1[3] + mfac*rt2[3];
671                                 }
672                         }
673                         rt1+= 4; rt2+= 4; rt+= 4;
674                 }
675
676                 if(y==0) break;
677                 y--;
678
679                 x= xo;
680                 while(x--) {
681
682                         if(rt2[3]<=0 && fac4 >= 1.0f) {
683                                 memcpy(rt, rt1, 4 * sizeof(float));
684  
685                         } else if(rt2[3]>=1.0f) {
686                                 memcpy(rt, rt2, 4 * sizeof(float));
687                         } else {
688                                 mfac= rt2[3];
689                                 fac= fac4*(1.0f-mfac);
690
691                                 if(fac == 0) {
692                                         memcpy(rt, rt2, 4 * sizeof(float));
693                                 } else {
694                                         rt[0]= fac * rt1[0] + mfac * rt2[0];
695                                         rt[1]= fac * rt1[1] + mfac * rt2[1];
696                                         rt[2]= fac * rt1[2] + mfac * rt2[2];
697                                         rt[3]= fac * rt1[3] + mfac * rt2[3];
698                                 }
699                         }
700                         rt1+= 4; rt2+= 4; rt+= 4;
701                 }
702         }
703 }
704
705 static struct ImBuf* do_alphaunder_effect(
706         SeqRenderData context, Sequence *UNUSED(seq), float UNUSED(cfra),
707         float facf0, float facf1, 
708         struct ImBuf *ibuf1, struct ImBuf *ibuf2, 
709         struct ImBuf *ibuf3)
710 {
711         struct ImBuf * out = prepare_effect_imbufs(
712                 context, ibuf1, ibuf2, ibuf3);
713
714         if (out->rect_float) {
715                 do_alphaunder_effect_float(
716                         facf0, facf1, context.rectx, context.recty,
717                         ibuf1->rect_float, ibuf2->rect_float,
718                         out->rect_float);
719         } else {
720                 do_alphaunder_effect_byte(
721                         facf0, facf1, context.rectx, context.recty,
722                         (char*) ibuf1->rect, (char*) ibuf2->rect,
723                         (char*) out->rect);
724         }
725         return out;
726 }
727
728
729 /* **********************************************************************
730    CROSS
731    ********************************************************************** */
732
733 static void do_cross_effect_byte(float facf0, float facf1, int x, int y, 
734                           char *rect1, char *rect2, 
735                           char *out)
736 {
737         int fac1, fac2, fac3, fac4;
738         int xo;
739         char *rt1, *rt2, *rt;
740
741         xo= x;
742         rt1= rect1;
743         rt2= rect2;
744         rt= out;
745
746         fac2= (int)(256.0f*facf0);
747         fac1= 256-fac2;
748         fac4= (int)(256.0f*facf1);
749         fac3= 256-fac4;
750
751         while(y--) {
752
753                 x= xo;
754                 while(x--) {
755
756                         rt[0]= (fac1*rt1[0] + fac2*rt2[0])>>8;
757                         rt[1]= (fac1*rt1[1] + fac2*rt2[1])>>8;
758                         rt[2]= (fac1*rt1[2] + fac2*rt2[2])>>8;
759                         rt[3]= (fac1*rt1[3] + fac2*rt2[3])>>8;
760
761                         rt1+= 4; rt2+= 4; rt+= 4;
762                 }
763
764                 if(y==0) break;
765                 y--;
766
767                 x= xo;
768                 while(x--) {
769
770                         rt[0]= (fac3*rt1[0] + fac4*rt2[0])>>8;
771                         rt[1]= (fac3*rt1[1] + fac4*rt2[1])>>8;
772                         rt[2]= (fac3*rt1[2] + fac4*rt2[2])>>8;
773                         rt[3]= (fac3*rt1[3] + fac4*rt2[3])>>8;
774
775                         rt1+= 4; rt2+= 4; rt+= 4;
776                 }
777
778         }
779 }
780
781 static void do_cross_effect_float(float facf0, float facf1, int x, int y, 
782                            float *rect1, float *rect2, float *out)
783 {
784         float fac1, fac2, fac3, fac4;
785         int xo;
786         float *rt1, *rt2, *rt;
787
788         xo= x;
789         rt1= rect1;
790         rt2= rect2;
791         rt= out;
792
793         fac2= facf0;
794         fac1= 1.0f - fac2;
795         fac4= facf1;
796         fac3= 1.0f - fac4;
797
798         while(y--) {
799
800                 x= xo;
801                 while(x--) {
802
803                         rt[0]= fac1*rt1[0] + fac2*rt2[0];
804                         rt[1]= fac1*rt1[1] + fac2*rt2[1];
805                         rt[2]= fac1*rt1[2] + fac2*rt2[2];
806                         rt[3]= fac1*rt1[3] + fac2*rt2[3];
807
808                         rt1+= 4; rt2+= 4; rt+= 4;
809                 }
810
811                 if(y==0) break;
812                 y--;
813
814                 x= xo;
815                 while(x--) {
816
817                         rt[0]= fac3*rt1[0] + fac4*rt2[0];
818                         rt[1]= fac3*rt1[1] + fac4*rt2[1];
819                         rt[2]= fac3*rt1[2] + fac4*rt2[2];
820                         rt[3]= fac3*rt1[3] + fac4*rt2[3];
821
822                         rt1+= 4; rt2+= 4; rt+= 4;
823                 }
824
825         }
826 }
827
828 /* careful: also used by speed effect! */
829
830 static struct ImBuf* do_cross_effect(
831         SeqRenderData context, Sequence *UNUSED(seq), float UNUSED(cfra),
832         float facf0, float facf1, 
833         struct ImBuf *ibuf1, struct ImBuf *ibuf2, 
834         struct ImBuf *ibuf3)
835 {
836         struct ImBuf * out = prepare_effect_imbufs(
837                 context, ibuf1, ibuf2, ibuf3);
838
839         if (out->rect_float) {
840                 do_cross_effect_float(
841                         facf0, facf1, context.rectx, context.recty,
842                         ibuf1->rect_float, ibuf2->rect_float,
843                         out->rect_float);
844         } else {
845                 do_cross_effect_byte(
846                         facf0, facf1, context.rectx, context.recty,
847                         (char*) ibuf1->rect, (char*) ibuf2->rect,
848                         (char*) out->rect);
849         }
850         return out;
851 }
852
853
854 /* **********************************************************************
855    GAMMA CROSS
856    ********************************************************************** */
857
858 /* copied code from initrender.c */
859 static unsigned short gamtab[65536];
860 static unsigned short igamtab1[256];
861 static int gamma_tabs_init = FALSE;
862
863 #define RE_GAMMA_TABLE_SIZE 400
864
865 static float gamma_range_table[RE_GAMMA_TABLE_SIZE + 1];
866 static float gamfactor_table[RE_GAMMA_TABLE_SIZE];
867 static float inv_gamma_range_table[RE_GAMMA_TABLE_SIZE + 1];
868 static float inv_gamfactor_table[RE_GAMMA_TABLE_SIZE];
869 static float color_domain_table[RE_GAMMA_TABLE_SIZE + 1]; 
870 static float color_step;
871 static float inv_color_step;
872 static float valid_gamma;
873 static float valid_inv_gamma;
874
875 static void makeGammaTables(float gamma)
876 {
877         /* we need two tables: one forward, one backward */
878         int i;
879
880         valid_gamma        = gamma;
881         valid_inv_gamma    = 1.0f / gamma;
882         color_step        = 1.0f / RE_GAMMA_TABLE_SIZE;
883         inv_color_step    = (float) RE_GAMMA_TABLE_SIZE; 
884
885         /* We could squeeze out the two range tables to gain some memory.        */     
886         for (i = 0; i < RE_GAMMA_TABLE_SIZE; i++) {
887                 color_domain_table[i]   = i * color_step;
888                 gamma_range_table[i]     = pow(color_domain_table[i],
889                                                                                 valid_gamma);
890                 inv_gamma_range_table[i] = pow(color_domain_table[i],
891                                                                                 valid_inv_gamma);
892         }
893
894         /* The end of the table should match 1.0 carefully. In order to avoid    */
895         /* rounding errors, we just set this explicitly. The last segment may    */
896         /* have a different length than the other segments, but our              */
897         /* interpolation is insensitive to that.                                 */
898         color_domain_table[RE_GAMMA_TABLE_SIZE]   = 1.0;
899         gamma_range_table[RE_GAMMA_TABLE_SIZE]     = 1.0;
900         inv_gamma_range_table[RE_GAMMA_TABLE_SIZE] = 1.0;
901
902         /* To speed up calculations, we make these calc factor tables. They are  */
903         /* multiplication factors used in scaling the interpolation.             */
904         for (i = 0; i < RE_GAMMA_TABLE_SIZE; i++ ) {
905                 gamfactor_table[i] = inv_color_step
906                         * (gamma_range_table[i + 1] - gamma_range_table[i]) ;
907                 inv_gamfactor_table[i] = inv_color_step
908                         * (inv_gamma_range_table[i + 1] - inv_gamma_range_table[i]) ;
909         }
910
911 } /* end of void makeGammaTables(float gamma) */
912
913
914 static float gammaCorrect(float c)
915 {
916         int i;
917         float res = 0.0;
918         
919         i = floor(c * inv_color_step);
920         /* Clip to range [0,1]: outside, just do the complete calculation.       */
921         /* We may have some performance problems here. Stretching up the LUT     */
922         /* may help solve that, by exchanging LUT size for the interpolation.    */
923         /* Negative colors are explicitly handled.                              */
924         if (i < 0) res = -pow(abs(c), valid_gamma);
925         else if (i >= RE_GAMMA_TABLE_SIZE ) res = pow(c, valid_gamma);
926         else res = gamma_range_table[i] + 
927                            ( (c - color_domain_table[i]) * gamfactor_table[i]); 
928         
929         return res;
930 } /* end of float gammaCorrect(float col) */
931
932 /* ------------------------------------------------------------------------- */
933
934 static float invGammaCorrect(float col)
935 {
936         int i;
937         float res = 0.0;
938
939         i = floor(col*inv_color_step);
940         /* Negative colors are explicitly handled.                              */
941         if (i < 0) res = -pow(abs(col), valid_inv_gamma);
942         else if (i >= RE_GAMMA_TABLE_SIZE) res = pow(col, valid_inv_gamma);
943         else res = inv_gamma_range_table[i] + 
944                            ( (col - color_domain_table[i]) * inv_gamfactor_table[i]);
945  
946         return res;
947 } /* end of float invGammaCorrect(float col) */
948
949
950 static void gamtabs(float gamma)
951 {
952         float val, igamma= 1.0f/gamma;
953         int a;
954         
955         /* gamtab: in short, out short */
956         for(a=0; a<65536; a++) {
957                 val= a;
958                 val/= 65535.0f;
959                 
960                 if(gamma==2.0f) val= sqrt(val);
961                 else if(gamma!=1.0f) val= pow(val, igamma);
962                 
963                 gamtab[a]= (65535.99f*val);
964         }
965         /* inverse gamtab1 : in byte, out short */
966         for(a=1; a<=256; a++) {
967                 if(gamma==2.0f) igamtab1[a-1]= a*a-1;
968                 else if(gamma==1.0f) igamtab1[a-1]= 256*a-1;
969                 else {
970                         val= a/256.0f;
971                         igamtab1[a-1]= (65535.0*pow(val, gamma)) -1 ;
972                 }
973         }
974
975 }
976
977 static void build_gammatabs(void)
978 {
979         if (gamma_tabs_init == FALSE) {
980                 gamtabs(2.0f);
981                 makeGammaTables(2.0f);
982                 gamma_tabs_init = TRUE;
983         }
984 }
985
986 static void init_gammacross(Sequence * UNUSED(seq))
987 {
988 }
989
990 static void load_gammacross(Sequence * UNUSED(seq))
991 {
992 }
993
994 static void free_gammacross(Sequence * UNUSED(seq))
995 {
996 }
997
998 static void do_gammacross_effect_byte(float facf0, float UNUSED(facf1), 
999                                           int x, int y, 
1000                                           unsigned char *rect1, 
1001                                           unsigned char *rect2, 
1002                                           unsigned char *out)
1003 {
1004         int fac1, fac2, col;
1005         int xo;
1006         unsigned char *rt1, *rt2, *rt;
1007         
1008         xo= x;
1009         rt1= (unsigned char *)rect1;
1010         rt2= (unsigned char *)rect2;
1011         rt= (unsigned char *)out;
1012
1013         fac2= (int)(256.0f*facf0);
1014         fac1= 256-fac2;
1015
1016         while(y--) {
1017
1018                 x= xo;
1019                 while(x--) {
1020
1021                         col= (fac1*igamtab1[rt1[0]] + fac2*igamtab1[rt2[0]])>>8;
1022                         if(col>65535) rt[0]= 255; else rt[0]= ( (char *)(gamtab+col))[MOST_SIG_BYTE];
1023                         col=(fac1*igamtab1[rt1[1]] + fac2*igamtab1[rt2[1]])>>8;
1024                         if(col>65535) rt[1]= 255; else rt[1]= ( (char *)(gamtab+col))[MOST_SIG_BYTE];
1025                         col= (fac1*igamtab1[rt1[2]] + fac2*igamtab1[rt2[2]])>>8;
1026                         if(col>65535) rt[2]= 255; else rt[2]= ( (char *)(gamtab+col))[MOST_SIG_BYTE];
1027                         col= (fac1*igamtab1[rt1[3]] + fac2*igamtab1[rt2[3]])>>8;
1028                         if(col>65535) rt[3]= 255; else rt[3]= ( (char *)(gamtab+col))[MOST_SIG_BYTE];
1029
1030                         rt1+= 4; rt2+= 4; rt+= 4;
1031                 }
1032
1033                 if(y==0) break;
1034                 y--;
1035
1036                 x= xo;
1037                 while(x--) {
1038
1039                         col= (fac1*igamtab1[rt1[0]] + fac2*igamtab1[rt2[0]])>>8;
1040                         if(col>65535) rt[0]= 255; else rt[0]= ( (char *)(gamtab+col))[MOST_SIG_BYTE];
1041                         col= (fac1*igamtab1[rt1[1]] + fac2*igamtab1[rt2[1]])>>8;
1042                         if(col>65535) rt[1]= 255; else rt[1]= ( (char *)(gamtab+col))[MOST_SIG_BYTE];
1043                         col= (fac1*igamtab1[rt1[2]] + fac2*igamtab1[rt2[2]])>>8;
1044                         if(col>65535) rt[2]= 255; else rt[2]= ( (char *)(gamtab+col))[MOST_SIG_BYTE];
1045                         col= (fac1*igamtab1[rt1[3]] + fac2*igamtab1[rt2[3]])>>8;
1046                         if(col>65535) rt[3]= 255; else rt[3]= ( (char *)(gamtab+col))[MOST_SIG_BYTE];
1047
1048                         rt1+= 4; rt2+= 4; rt+= 4;
1049                 }
1050         }
1051
1052 }
1053
1054 static void do_gammacross_effect_float(float facf0, float UNUSED(facf1), 
1055                                            int x, int y, 
1056                                            float *rect1, float *rect2, 
1057                                            float *out)
1058 {
1059         float fac1, fac2;
1060         int xo;
1061         float *rt1, *rt2, *rt;
1062
1063         xo= x;
1064         rt1= rect1;
1065         rt2= rect2;
1066         rt= out;
1067
1068         fac2= facf0;
1069         fac1= 1.0f - fac2;
1070
1071         while(y--) {
1072
1073                 x= xo * 4;
1074                 while(x--) {
1075
1076                         *rt= gammaCorrect(
1077                                 fac1 * invGammaCorrect(*rt1) 
1078                                 + fac2 * invGammaCorrect(*rt2));
1079                         rt1++; rt2++; rt++;
1080                 }
1081
1082                 if(y==0) break;
1083                 y--;
1084
1085                 x= xo * 4;
1086                 while(x--) {
1087
1088                         *rt= gammaCorrect(
1089                                 fac1*invGammaCorrect(*rt1) 
1090                                 + fac2*invGammaCorrect(*rt2));
1091
1092                         rt1++; rt2++; rt++;
1093                 }
1094         }
1095 }
1096
1097 static struct ImBuf * do_gammacross_effect(
1098         SeqRenderData context,
1099         Sequence *UNUSED(seq), float UNUSED(cfra),
1100         float facf0, float facf1, 
1101         struct ImBuf *ibuf1, struct ImBuf *ibuf2, 
1102         struct ImBuf *ibuf3)
1103 {
1104         struct ImBuf * out = prepare_effect_imbufs(context,ibuf1, ibuf2, ibuf3);
1105
1106         build_gammatabs();
1107
1108         if (out->rect_float) {
1109                 do_gammacross_effect_float(
1110                         facf0, facf1, context.rectx, context.recty,
1111                         ibuf1->rect_float, ibuf2->rect_float,
1112                         out->rect_float);
1113         } else {
1114                 do_gammacross_effect_byte(
1115                         facf0, facf1, context.rectx, context.recty,
1116                         (unsigned char*) ibuf1->rect, (unsigned char*) ibuf2->rect,
1117                         (unsigned char*) out->rect);
1118         }
1119         return out;
1120 }
1121
1122
1123 /* **********************************************************************
1124    ADD
1125    ********************************************************************** */
1126
1127 static void do_add_effect_byte(float facf0, float facf1, int x, int y, 
1128                                    unsigned char *rect1, unsigned char *rect2, 
1129                                    unsigned char *out)
1130 {
1131         int col, xo, fac1, fac3;
1132         char *rt1, *rt2, *rt;
1133
1134         xo= x;
1135         rt1= (char *)rect1;
1136         rt2= (char *)rect2;
1137         rt= (char *)out;
1138
1139         fac1= (int)(256.0f*facf0);
1140         fac3= (int)(256.0f*facf1);
1141
1142         while(y--) {
1143
1144                 x= xo;
1145                 while(x--) {
1146
1147                         col= rt1[0]+ ((fac1*rt2[0])>>8);
1148                         if(col>255) rt[0]= 255; else rt[0]= col;
1149                         col= rt1[1]+ ((fac1*rt2[1])>>8);
1150                         if(col>255) rt[1]= 255; else rt[1]= col;
1151                         col= rt1[2]+ ((fac1*rt2[2])>>8);
1152                         if(col>255) rt[2]= 255; else rt[2]= col;
1153                         col= rt1[3]+ ((fac1*rt2[3])>>8);
1154                         if(col>255) rt[3]= 255; else rt[3]= col;
1155
1156                         rt1+= 4; rt2+= 4; rt+= 4;
1157                 }
1158
1159                 if(y==0) break;
1160                 y--;
1161
1162                 x= xo;
1163                 while(x--) {
1164
1165                         col= rt1[0]+ ((fac3*rt2[0])>>8);
1166                         if(col>255) rt[0]= 255; else rt[0]= col;
1167                         col= rt1[1]+ ((fac3*rt2[1])>>8);
1168                         if(col>255) rt[1]= 255; else rt[1]= col;
1169                         col= rt1[2]+ ((fac3*rt2[2])>>8);
1170                         if(col>255) rt[2]= 255; else rt[2]= col;
1171                         col= rt1[3]+ ((fac3*rt2[3])>>8);
1172                         if(col>255) rt[3]= 255; else rt[3]= col;
1173
1174                         rt1+= 4; rt2+= 4; rt+= 4;
1175                 }
1176         }
1177 }
1178
1179 static void do_add_effect_float(float facf0, float facf1, int x, int y, 
1180                                 float *rect1, float *rect2, 
1181                                 float *out)
1182 {
1183         int xo;
1184         float fac1, fac3;
1185         float *rt1, *rt2, *rt;
1186
1187         xo= x;
1188         rt1= rect1;
1189         rt2= rect2;
1190         rt= out;
1191
1192         fac1= facf0;
1193         fac3= facf1;
1194
1195         while(y--) {
1196
1197                 x= xo * 4;
1198                 while(x--) {
1199                         *rt = *rt1 + fac1 * (*rt2);
1200
1201                         rt1++; rt2++; rt++;
1202                 }
1203
1204                 if(y==0) break;
1205                 y--;
1206
1207                 x= xo * 4;
1208                 while(x--) {
1209                         *rt = *rt1 + fac3 * (*rt2);
1210
1211                         rt1++; rt2++; rt++;
1212                 }
1213         }
1214 }
1215
1216 static struct ImBuf * do_add_effect(SeqRenderData context, 
1217                                     Sequence *UNUSED(seq), float UNUSED(cfra),
1218                                     float facf0, float facf1,
1219                                     struct ImBuf *ibuf1, struct ImBuf *ibuf2, 
1220                                     struct ImBuf *ibuf3)
1221 {
1222         struct ImBuf * out = prepare_effect_imbufs(context,ibuf1, ibuf2, ibuf3);
1223
1224         if (out->rect_float) {
1225                 do_add_effect_float(
1226                         facf0, facf1, context.rectx, context.recty,
1227                         ibuf1->rect_float, ibuf2->rect_float,
1228                         out->rect_float);
1229         } else {
1230                 do_add_effect_byte(
1231                         facf0, facf1, context.rectx, context.recty,
1232                         (unsigned char*) ibuf1->rect, (unsigned char*) ibuf2->rect,
1233                         (unsigned char*) out->rect);
1234         }
1235         return out;
1236 }
1237
1238
1239 /* **********************************************************************
1240    SUB
1241    ********************************************************************** */
1242
1243 static void do_sub_effect_byte(float facf0, float facf1, 
1244                                    int x, int y, 
1245                                    char *rect1, char *rect2, char *out)
1246 {
1247         int col, xo, fac1, fac3;
1248         char *rt1, *rt2, *rt;
1249
1250         xo= x;
1251         rt1= (char *)rect1;
1252         rt2= (char *)rect2;
1253         rt= (char *)out;
1254
1255         fac1= (int)(256.0f*facf0);
1256         fac3= (int)(256.0f*facf1);
1257
1258         while(y--) {
1259
1260                 x= xo;
1261                 while(x--) {
1262
1263                         col= rt1[0]- ((fac1*rt2[0])>>8);
1264                         if(col<0) rt[0]= 0; else rt[0]= col;
1265                         col= rt1[1]- ((fac1*rt2[1])>>8);
1266                         if(col<0) rt[1]= 0; else rt[1]= col;
1267                         col= rt1[2]- ((fac1*rt2[2])>>8);
1268                         if(col<0) rt[2]= 0; else rt[2]= col;
1269                         col= rt1[3]- ((fac1*rt2[3])>>8);
1270                         if(col<0) rt[3]= 0; else rt[3]= col;
1271
1272                         rt1+= 4; rt2+= 4; rt+= 4;
1273                 }
1274
1275                 if(y==0) break;
1276                 y--;
1277
1278                 x= xo;
1279                 while(x--) {
1280
1281                         col= rt1[0]- ((fac3*rt2[0])>>8);
1282                         if(col<0) rt[0]= 0; else rt[0]= col;
1283                         col= rt1[1]- ((fac3*rt2[1])>>8);
1284                         if(col<0) rt[1]= 0; else rt[1]= col;
1285                         col= rt1[2]- ((fac3*rt2[2])>>8);
1286                         if(col<0) rt[2]= 0; else rt[2]= col;
1287                         col= rt1[3]- ((fac3*rt2[3])>>8);
1288                         if(col<0) rt[3]= 0; else rt[3]= col;
1289
1290                         rt1+= 4; rt2+= 4; rt+= 4;
1291                 }
1292         }
1293 }
1294
1295 static void do_sub_effect_float(float facf0, float facf1, int x, int y, 
1296                                 float *rect1, float *rect2, 
1297                                 float *out)
1298 {
1299         int xo;
1300         float fac1, fac3;
1301         float *rt1, *rt2, *rt;
1302
1303         xo= x;
1304         rt1= rect1;
1305         rt2= rect2;
1306         rt= out;
1307
1308         fac1= facf0;
1309         fac3= facf1;
1310
1311         while(y--) {
1312
1313                 x= xo * 4;
1314                 while(x--) {
1315                         *rt = *rt1 - fac1 * (*rt2);
1316
1317                         rt1++; rt2++; rt++;
1318                 }
1319
1320                 if(y==0) break;
1321                 y--;
1322
1323                 x= xo * 4;
1324                 while(x--) {
1325                         *rt = *rt1 - fac3 * (*rt2);
1326
1327                         rt1++; rt2++; rt++;
1328                 }
1329         }
1330 }
1331
1332 static struct ImBuf * do_sub_effect(
1333         SeqRenderData context, Sequence *UNUSED(seq), float UNUSED(cfra),
1334         float facf0, float facf1, 
1335         struct ImBuf *ibuf1, struct ImBuf *ibuf2, 
1336         struct ImBuf *ibuf3)
1337 {
1338         struct ImBuf * out = prepare_effect_imbufs(context,ibuf1, ibuf2, ibuf3);
1339
1340         if (out->rect_float) {
1341                 do_sub_effect_float(
1342                         facf0, facf1, context.rectx, context.recty,
1343                         ibuf1->rect_float, ibuf2->rect_float,
1344                         out->rect_float);
1345         } else {
1346                 do_sub_effect_byte(
1347                         facf0, facf1, context.rectx, context.recty,
1348                         (char*) ibuf1->rect, (char*) ibuf2->rect,
1349                         (char*) out->rect);
1350         }
1351         return out;
1352 }
1353
1354 /* **********************************************************************
1355    DROP
1356    ********************************************************************** */
1357
1358 /* Must be > 0 or add precopy, etc to the function */
1359 #define XOFF    8
1360 #define YOFF    8
1361
1362 static void do_drop_effect_byte(float facf0, float facf1, int x, int y, 
1363                                 char *rect2i, char *rect1i, 
1364                                 char *outi)
1365 {
1366         int height, width, temp, fac, fac1, fac2;
1367         char *rt1, *rt2, *out;
1368         int field= 1;
1369
1370         width= x;
1371         height= y;
1372
1373         fac1= (int)(70.0f*facf0);
1374         fac2= (int)(70.0f*facf1);
1375
1376         rt2= (char*) (rect2i + YOFF*width);
1377         rt1= (char*) rect1i;
1378         out= (char*) outi;
1379         for (y=0; y<height-YOFF; y++) {
1380                 if(field) fac= fac1;
1381                 else fac= fac2;
1382                 field= !field;
1383
1384                 memcpy(out, rt1, sizeof(int)*XOFF);
1385                 rt1+= XOFF*4;
1386                 out+= XOFF*4;
1387
1388                 for (x=XOFF; x<width; x++) {
1389                         temp= ((fac*rt2[3])>>8);
1390
1391                         *(out++)= MAX2(0, *rt1 - temp); rt1++;
1392                         *(out++)= MAX2(0, *rt1 - temp); rt1++;
1393                         *(out++)= MAX2(0, *rt1 - temp); rt1++;
1394                         *(out++)= MAX2(0, *rt1 - temp); rt1++;
1395                         rt2+=4;
1396                 }
1397                 rt2+=XOFF*4;
1398         }
1399         memcpy(out, rt1, sizeof(int)*YOFF*width);
1400 }
1401
1402 static void do_drop_effect_float(float facf0, float facf1, int x, int y, 
1403                                  float *rect2i, float *rect1i, 
1404                                  float *outi)
1405 {
1406         int height, width;
1407         float temp, fac, fac1, fac2;
1408         float *rt1, *rt2, *out;
1409         int field= 1;
1410
1411         width= x;
1412         height= y;
1413
1414         fac1= 70.0f*facf0;
1415         fac2= 70.0f*facf1;
1416
1417         rt2=  (rect2i + YOFF*width);
1418         rt1=  rect1i;
1419         out=  outi;
1420         for (y=0; y<height-YOFF; y++) {
1421                 if(field) fac= fac1;
1422                 else fac= fac2;
1423                 field= !field;
1424
1425                 memcpy(out, rt1, 4 * sizeof(float)*XOFF);
1426                 rt1+= XOFF*4;
1427                 out+= XOFF*4;
1428
1429                 for (x=XOFF; x<width; x++) {
1430                         temp= fac * rt2[3];
1431
1432                         *(out++)= MAX2(0.0f, *rt1 - temp); rt1++;
1433                         *(out++)= MAX2(0.0f, *rt1 - temp); rt1++;
1434                         *(out++)= MAX2(0.0f, *rt1 - temp); rt1++;
1435                         *(out++)= MAX2(0.0f, *rt1 - temp); rt1++;
1436                         rt2+=4;
1437                 }
1438                 rt2+=XOFF*4;
1439         }
1440         memcpy(out, rt1, 4 * sizeof(float)*YOFF*width);
1441 }
1442
1443 /* **********************************************************************
1444    MUL
1445    ********************************************************************** */
1446
1447 static void do_mul_effect_byte(float facf0, float facf1, int x, int y, 
1448                                    unsigned char *rect1, unsigned char *rect2, 
1449                                    unsigned char *out)
1450 {
1451         int xo, fac1, fac3;
1452         char *rt1, *rt2, *rt;
1453
1454         xo= x;
1455         rt1= (char *)rect1;
1456         rt2= (char *)rect2;
1457         rt= (char *)out;
1458
1459         fac1= (int)(256.0f*facf0);
1460         fac3= (int)(256.0f*facf1);
1461
1462         /* formula:
1463          *              fac*(a*b) + (1-fac)*a  => fac*a*(b-1)+axaux= c*px + py*s ;//+centx
1464                         yaux= -s*px + c*py;//+centy
1465          */
1466
1467         while(y--) {
1468
1469                 x= xo;
1470                 while(x--) {
1471
1472                         rt[0]= rt1[0] + ((fac1*rt1[0]*(rt2[0]-256))>>16);
1473                         rt[1]= rt1[1] + ((fac1*rt1[1]*(rt2[1]-256))>>16);
1474                         rt[2]= rt1[2] + ((fac1*rt1[2]*(rt2[2]-256))>>16);
1475                         rt[3]= rt1[3] + ((fac1*rt1[3]*(rt2[3]-256))>>16);
1476
1477                         rt1+= 4; rt2+= 4; rt+= 4;
1478                 }
1479
1480                 if(y==0) break;
1481                 y--;
1482
1483                 x= xo;
1484                 while(x--) {
1485
1486                         rt[0]= rt1[0] + ((fac3*rt1[0]*(rt2[0]-256))>>16);
1487                         rt[1]= rt1[1] + ((fac3*rt1[1]*(rt2[1]-256))>>16);
1488                         rt[2]= rt1[2] + ((fac3*rt1[2]*(rt2[2]-256))>>16);
1489                         rt[3]= rt1[3] + ((fac3*rt1[3]*(rt2[3]-256))>>16);
1490
1491                         rt1+= 4; rt2+= 4; rt+= 4;
1492                 }
1493         }
1494 }
1495
1496 static void do_mul_effect_float(float facf0, float facf1, int x, int y, 
1497                                         float *rect1, float *rect2, 
1498                                         float *out)
1499 {
1500         int xo;
1501         float fac1, fac3;
1502         float *rt1, *rt2, *rt;
1503
1504         xo= x;
1505         rt1= rect1;
1506         rt2= rect2;
1507         rt= out;
1508
1509         fac1= facf0;
1510         fac3= facf1;
1511
1512         /* formula:
1513          *              fac*(a*b) + (1-fac)*a  => fac*a*(b-1)+a
1514          */
1515
1516         while(y--) {
1517
1518                 x= xo;
1519                 while(x--) {
1520
1521                         rt[0]= rt1[0] + fac1*rt1[0]*(rt2[0]-1.0f);
1522                         rt[1]= rt1[1] + fac1*rt1[1]*(rt2[1]-1.0f);
1523                         rt[2]= rt1[2] + fac1*rt1[2]*(rt2[2]-1.0f);
1524                         rt[3]= rt1[3] + fac1*rt1[3]*(rt2[3]-1.0f);
1525
1526                         rt1+= 4; rt2+= 4; rt+= 4;
1527                 }
1528
1529                 if(y==0) break;
1530                 y--;
1531
1532                 x= xo;
1533                 while(x--) {
1534
1535                         rt[0]= rt1[0] + fac3*rt1[0]*(rt2[0]-1.0f);
1536                         rt[1]= rt1[1] + fac3*rt1[1]*(rt2[1]-1.0f);
1537                         rt[2]= rt1[2] + fac3*rt1[2]*(rt2[2]-1.0f);
1538                         rt[3]= rt1[3] + fac3*rt1[3]*(rt2[3]-1.0f);
1539
1540                         rt1+= 4; rt2+= 4; rt+= 4;
1541                 }
1542         }
1543 }
1544
1545 static struct ImBuf * do_mul_effect(
1546         SeqRenderData context, Sequence *UNUSED(seq), float UNUSED(cfra),
1547         float facf0, float facf1, 
1548         struct ImBuf *ibuf1, struct ImBuf *ibuf2, 
1549         struct ImBuf *ibuf3)
1550 {
1551         struct ImBuf * out = prepare_effect_imbufs(context,ibuf1, ibuf2, ibuf3);
1552
1553         if (out->rect_float) {
1554                 do_mul_effect_float(
1555                         facf0, facf1, context.rectx, context.recty,
1556                         ibuf1->rect_float, ibuf2->rect_float,
1557                         out->rect_float);
1558         } else {
1559                 do_mul_effect_byte(
1560                         facf0, facf1, context.rectx, context.recty,
1561                         (unsigned char*) ibuf1->rect, (unsigned char*) ibuf2->rect,
1562                         (unsigned char*) out->rect);
1563         }
1564
1565         return out;
1566 }
1567
1568 /* **********************************************************************
1569    WIPE
1570    ********************************************************************** */
1571
1572 typedef struct WipeZone {
1573         float angle;
1574         int flip;
1575         int xo, yo;
1576         int width;
1577         float invwidth;
1578         float pythangle;
1579 } WipeZone;
1580
1581 static void precalc_wipe_zone(WipeZone *wipezone, WipeVars *wipe, int xo, int yo)
1582 {
1583         wipezone->flip = (wipe->angle < 0);
1584         wipezone->angle = tan(DEG2RAD(fabsf(wipe->angle)));
1585         wipezone->xo = xo;
1586         wipezone->yo = yo;
1587         wipezone->width = (int)(wipe->edgeWidth*((xo+yo)/2.0f));
1588         wipezone->pythangle = 1.0f/sqrtf(wipe->angle*wipe->angle + 1.0f);
1589
1590         if(wipe->wipetype == DO_SINGLE_WIPE)
1591                 wipezone->invwidth = 1.0f/wipezone->width;
1592         else
1593                 wipezone->invwidth = 1.0f/(0.5f*wipezone->width);
1594 }
1595
1596 // This function calculates the blur band for the wipe effects
1597 static float in_band(WipeZone *wipezone,float width,float dist,float perc,int side,int dir)
1598 {
1599         float t1,t2,alpha;
1600
1601         if(width == 0)
1602                 return (float)side;
1603         
1604         if(width < dist)
1605                 return side;
1606         
1607         t1 = dist * wipezone->invwidth;  //percentange of width that is
1608         t2 = wipezone->invwidth;  //amount of alpha per % point
1609         
1610         if(side == 1)
1611                 alpha = (t1*t2*100) + (1-perc); // add point's alpha contrib to current position in wipe
1612         else
1613                 alpha = (1-perc) - (t1*t2*100);
1614         
1615         if(dir == 0)
1616                 alpha = 1-alpha;
1617
1618         return alpha;
1619 }
1620
1621 static float check_zone(WipeZone *wipezone, int x, int y,
1622         Sequence *seq, float facf0) 
1623 {
1624         float posx, posy,hyp,hyp2,angle,hwidth,b1,b2,b3,pointdist;
1625 /*some future stuff
1626 float hyp3,hyp4,b4,b5      
1627 */
1628         float temp1,temp2,temp3,temp4; //some placeholder variables
1629         int xo = wipezone->xo;
1630         int yo = wipezone->yo;
1631         float halfx = xo*0.5f;
1632         float halfy = yo*0.5f;
1633         float widthf,output=0;
1634         WipeVars *wipe = (WipeVars *)seq->effectdata;
1635         int width;
1636
1637         if(wipezone->flip) x = xo - x;
1638         angle = wipezone->angle;
1639
1640         if(wipe->forward){
1641                 posx = facf0 * xo;
1642                 posy = facf0 * yo;
1643         } else{
1644                 posx = xo - facf0 * xo;
1645                 posy = yo - facf0 * yo;
1646         }
1647
1648         switch (wipe->wipetype) {
1649                 case DO_SINGLE_WIPE:
1650                         width = wipezone->width;
1651                         hwidth = width*0.5f;
1652
1653                         if(angle == 0.0f) {
1654                                 b1 = posy;
1655                                 b2 = y;
1656                                 hyp = fabs(y - posy);
1657                         }
1658                         else {
1659                                 b1 = posy - (-angle)*posx;
1660                                 b2 = y - (-angle)*x;
1661                                 hyp = fabsf(angle*x+y+(-posy-angle*posx))*wipezone->pythangle;
1662                         }
1663
1664                         if(angle < 0) {
1665                                 temp1 = b1;
1666                                 b1 = b2;
1667                                 b2 = temp1;
1668                         }
1669
1670                         if(wipe->forward) {
1671                                 if(b1 < b2)
1672                                         output = in_band(wipezone,width,hyp,facf0,1,1);
1673                                 else
1674                                         output = in_band(wipezone,width,hyp,facf0,0,1);
1675                         }
1676                         else {
1677                                 if(b1 < b2)
1678                                         output = in_band(wipezone,width,hyp,facf0,0,1);
1679                                 else
1680                                         output = in_band(wipezone,width,hyp,facf0,1,1);
1681                         }
1682                 break;
1683
1684                 case DO_DOUBLE_WIPE:
1685                         if(!wipe->forward)
1686                                 facf0 = 1.0f-facf0;   // Go the other direction
1687
1688                         width = wipezone->width;  // calculate the blur width
1689                         hwidth = width*0.5f;
1690                         if (angle == 0) {
1691                                 b1 = posy*0.5f;
1692                                 b3 = yo-posy*0.5f;
1693                                 b2 = y;
1694
1695                                 hyp = abs(y - posy*0.5f);
1696                                 hyp2 = abs(y - (yo-posy*0.5f));
1697                         }
1698                         else {
1699                                 b1 = posy*0.5f - (-angle)*posx*0.5f;
1700                                 b3 = (yo-posy*0.5f) - (-angle)*(xo-posx*0.5f);
1701                                 b2 = y - (-angle)*x;
1702
1703                                 hyp = abs(angle*x+y+(-posy*0.5f-angle*posx*0.5f))*wipezone->pythangle;
1704                                 hyp2 = abs(angle*x+y+(-(yo-posy*0.5f)-angle*(xo-posx*0.5f)))*wipezone->pythangle;
1705                         }
1706
1707                         temp1 = xo*(1-facf0*0.5f)-xo*facf0*0.5f;
1708                         temp2 = yo*(1-facf0*0.5f)-yo*facf0*0.5f;
1709                         pointdist = sqrt(temp1*temp1 + temp2*temp2);
1710
1711                         if(b2 < b1 && b2 < b3 ){
1712                                 if(hwidth < pointdist)
1713                                         output = in_band(wipezone,hwidth,hyp,facf0,0,1);
1714                         } else if(b2 > b1 && b2 > b3 ){
1715                                 if(hwidth < pointdist)
1716                                         output = in_band(wipezone,hwidth,hyp2,facf0,0,1);       
1717                         } else {
1718                                 if(  hyp < hwidth && hyp2 > hwidth )
1719                                         output = in_band(wipezone,hwidth,hyp,facf0,1,1);
1720                                 else if( hyp > hwidth && hyp2 < hwidth )
1721                                           output = in_band(wipezone,hwidth,hyp2,facf0,1,1);
1722                                 else
1723                                           output = in_band(wipezone,hwidth,hyp2,facf0,1,1) * in_band(wipezone,hwidth,hyp,facf0,1,1);
1724                         }
1725                         if(!wipe->forward)output = 1-output;
1726                 break;
1727                 case DO_CLOCK_WIPE:
1728                           /*
1729                                   temp1: angle of effect center in rads
1730                                   temp2: angle of line through (halfx,halfy) and (x,y) in rads
1731                                   temp3: angle of low side of blur
1732                                   temp4: angle of high side of blur
1733                           */
1734                         output = 1.0f - facf0;
1735                         widthf = wipe->edgeWidth*2.0f*(float)M_PI;
1736                         temp1 = 2.0f * (float)M_PI * facf0;
1737
1738                         if(wipe->forward){
1739                                 temp1 = 2.0f*(float)M_PI - temp1;
1740                         }
1741
1742                         x = x - halfx;
1743                         y = y - halfy;
1744
1745                         temp2 = asin(abs(y)/sqrt(x*x + y*y));
1746                         if(x <= 0 && y >= 0) temp2 = (float)M_PI - temp2;
1747                         else if(x<=0 && y <= 0) temp2 += (float)M_PI;
1748                         else if(x >= 0 && y <= 0) temp2 = 2.0f*(float)M_PI - temp2;
1749
1750                         if(wipe->forward){
1751                                 temp3 = temp1-(widthf*0.5f)*facf0;
1752                                 temp4 = temp1+(widthf*0.5f)*(1-facf0);
1753                         } else{
1754                                 temp3 = temp1-(widthf*0.5f)*(1-facf0);
1755                                 temp4 = temp1+(widthf*0.5f)*facf0;
1756                         }
1757                         if (temp3 < 0) temp3 = 0;
1758                         if (temp4 > 2.0f*(float)M_PI) temp4 = 2.0f*(float)M_PI;
1759
1760
1761                         if(temp2 < temp3) output = 0;
1762                         else if (temp2 > temp4) output = 1;
1763                         else output = (temp2-temp3)/(temp4-temp3);
1764                         if(x == 0 && y == 0) output = 1;
1765                         if(output != output) output = 1;
1766                         if(wipe->forward) output = 1 - output;
1767                 break;
1768         /* BOX WIPE IS NOT WORKING YET */
1769         /* case DO_CROSS_WIPE: */
1770         /* BOX WIPE IS NOT WORKING YET */
1771         /* 
1772                 case DO_BOX_WIPE: 
1773                         if(invert)facf0 = 1-facf0;
1774
1775                         width = (int)(wipe->edgeWidth*((xo+yo)/2.0));
1776                         hwidth = (float)width/2.0;
1777                         if (angle == 0)angle = 0.000001;
1778                         b1 = posy/2 - (-angle)*posx/2;
1779                         b3 = (yo-posy/2) - (-angle)*(xo-posx/2);
1780                         b2 = y - (-angle)*x;
1781
1782                         hyp = abs(angle*x+y+(-posy/2-angle*posx/2))*wipezone->pythangle;
1783                         hyp2 = abs(angle*x+y+(-(yo-posy/2)-angle*(xo-posx/2)))*wipezone->pythangle;
1784
1785                         temp1 = xo*(1-facf0/2)-xo*facf0/2;
1786                         temp2 = yo*(1-facf0/2)-yo*facf0/2;
1787                         pointdist = sqrt(temp1*temp1 + temp2*temp2);
1788
1789                         if(b2 < b1 && b2 < b3 ){
1790                                 if(hwidth < pointdist)
1791                                         output = in_band(wipezone,hwidth,hyp,facf0,0,1);
1792                         } else if(b2 > b1 && b2 > b3 ){
1793                                 if(hwidth < pointdist)
1794                                         output = in_band(wipezone,hwidth,hyp2,facf0,0,1);       
1795                         } else {
1796                                 if( hyp < hwidth && hyp2 > hwidth )
1797                                         output = in_band(wipezone,hwidth,hyp,facf0,1,1);
1798                                 else if( hyp > hwidth && hyp2 < hwidth )
1799                                          output = in_band(wipezone,hwidth,hyp2,facf0,1,1);
1800                                 else
1801                                          output = in_band(wipezone,hwidth,hyp2,facf0,1,1) * in_band(wipezone,hwidth,hyp,facf0,1,1);
1802                         }
1803
1804                         if(invert)facf0 = 1-facf0;
1805                         angle = -1/angle;
1806                         b1 = posy/2 - (-angle)*posx/2;
1807                         b3 = (yo-posy/2) - (-angle)*(xo-posx/2);
1808                         b2 = y - (-angle)*x;
1809
1810                         hyp = abs(angle*x+y+(-posy/2-angle*posx/2))*wipezone->pythangle;
1811                         hyp2 = abs(angle*x+y+(-(yo-posy/2)-angle*(xo-posx/2)))*wipezone->pythangle;
1812
1813                         if(b2 < b1 && b2 < b3 ){
1814                                 if(hwidth < pointdist)
1815                                         output *= in_band(wipezone,hwidth,hyp,facf0,0,1);
1816                         } else if(b2 > b1 && b2 > b3 ){
1817                                 if(hwidth < pointdist)
1818                                         output *= in_band(wipezone,hwidth,hyp2,facf0,0,1);      
1819                         } else {
1820                                 if( hyp < hwidth && hyp2 > hwidth )
1821                                         output *= in_band(wipezone,hwidth,hyp,facf0,1,1);
1822                                 else if( hyp > hwidth && hyp2 < hwidth )
1823                                         output *= in_band(wipezone,hwidth,hyp2,facf0,1,1);
1824                                 else
1825                                         output *= in_band(wipezone,hwidth,hyp2,facf0,1,1) * in_band(wipezone,hwidth,hyp,facf0,1,1);
1826                         }
1827
1828                 break;
1829 */
1830                 case DO_IRIS_WIPE:
1831                         if(xo > yo) yo = xo;
1832                         else xo = yo;
1833
1834                         if(!wipe->forward) facf0 = 1-facf0;
1835
1836                         width = wipezone->width;
1837                         hwidth = width*0.5f;
1838
1839                         temp1 = (halfx-(halfx)*facf0);
1840                         pointdist = sqrt(temp1*temp1 + temp1*temp1);
1841
1842                         temp2 = sqrt((halfx-x)*(halfx-x) + (halfy-y)*(halfy-y));
1843                         if(temp2 > pointdist) output = in_band(wipezone,hwidth,fabs(temp2-pointdist),facf0,0,1);
1844                         else output = in_band(wipezone,hwidth,fabs(temp2-pointdist),facf0,1,1);
1845
1846                         if(!wipe->forward) output = 1-output;
1847                         
1848                 break;
1849         }
1850         if (output < 0) output = 0;
1851         else if(output > 1) output = 1;
1852         return output;
1853 }
1854
1855 static void init_wipe_effect(Sequence *seq)
1856 {
1857         if(seq->effectdata)MEM_freeN(seq->effectdata);
1858         seq->effectdata = MEM_callocN(sizeof(struct WipeVars), "wipevars");
1859 }
1860
1861 static int num_inputs_wipe(void)
1862 {
1863         return 1;
1864 }
1865
1866 static void free_wipe_effect(Sequence *seq)
1867 {
1868         if(seq->effectdata)MEM_freeN(seq->effectdata);
1869         seq->effectdata = NULL;
1870 }
1871
1872 static void copy_wipe_effect(Sequence *dst, Sequence *src)
1873 {
1874         dst->effectdata = MEM_dupallocN(src->effectdata);
1875 }
1876
1877 static void do_wipe_effect_byte(Sequence *seq, float facf0, float UNUSED(facf1), 
1878                                 int x, int y, 
1879                                 unsigned char *rect1, 
1880                                 unsigned char *rect2, unsigned char *out)
1881 {
1882         WipeZone wipezone;
1883         WipeVars *wipe = (WipeVars *)seq->effectdata;
1884         int xo, yo;
1885         char *rt1, *rt2, *rt;
1886
1887         precalc_wipe_zone(&wipezone, wipe, x, y);
1888
1889         rt1 = (char *)rect1;
1890         rt2 = (char *)rect2;
1891         rt = (char *)out;
1892
1893         xo = x;
1894         yo = y;
1895         for(y=0;y<yo;y++) {
1896                 for(x=0;x<xo;x++) {
1897                         float check = check_zone(&wipezone,x,y,seq,facf0);
1898                         if (check) {
1899                                 if (rt1) {
1900                                         rt[0] = (int)(rt1[0]*check)+ (int)(rt2[0]*(1-check));
1901                                         rt[1] = (int)(rt1[1]*check)+ (int)(rt2[1]*(1-check));
1902                                         rt[2] = (int)(rt1[2]*check)+ (int)(rt2[2]*(1-check));
1903                                         rt[3] = (int)(rt1[3]*check)+ (int)(rt2[3]*(1-check));
1904                                 } else {
1905                                         rt[0] = 0;
1906                                         rt[1] = 0;
1907                                         rt[2] = 0;
1908                                         rt[3] = 255;
1909                                 }
1910                         } else {
1911                                 if (rt2) {
1912                                         rt[0] = rt2[0];
1913                                         rt[1] = rt2[1];
1914                                         rt[2] = rt2[2];
1915                                         rt[3] = rt2[3];
1916                                 } else {
1917                                         rt[0] = 0;
1918                                         rt[1] = 0;
1919                                         rt[2] = 0;
1920                                         rt[3] = 255;
1921                                 }
1922                         }
1923
1924                         rt+=4;
1925                         if(rt1 !=NULL){
1926                                 rt1+=4;
1927                         }
1928                         if(rt2 !=NULL){
1929                                 rt2+=4;
1930                         }
1931                 }
1932         }
1933 }
1934
1935 static void do_wipe_effect_float(Sequence *seq, float facf0, float UNUSED(facf1), 
1936                                  int x, int y, 
1937                                  float *rect1, 
1938                                  float *rect2, float *out)
1939 {
1940         WipeZone wipezone;
1941         WipeVars *wipe = (WipeVars *)seq->effectdata;
1942         int xo, yo;
1943         float *rt1, *rt2, *rt;
1944
1945         precalc_wipe_zone(&wipezone, wipe, x, y);
1946
1947         rt1 = rect1;
1948         rt2 = rect2;
1949         rt = out;
1950
1951         xo = x;
1952         yo = y;
1953         for(y=0;y<yo;y++) {
1954                 for(x=0;x<xo;x++) {
1955                         float check = check_zone(&wipezone,x,y,seq,facf0);
1956                         if (check) {
1957                                 if (rt1) {
1958                                         rt[0] = rt1[0]*check+ rt2[0]*(1-check);
1959                                         rt[1] = rt1[1]*check+ rt2[1]*(1-check);
1960                                         rt[2] = rt1[2]*check+ rt2[2]*(1-check);
1961                                         rt[3] = rt1[3]*check+ rt2[3]*(1-check);
1962                                 } else {
1963                                         rt[0] = 0;
1964                                         rt[1] = 0;
1965                                         rt[2] = 0;
1966                                         rt[3] = 1.0;
1967                                 }
1968                         } else {
1969                                 if (rt2) {
1970                                         rt[0] = rt2[0];
1971                                         rt[1] = rt2[1];
1972                                         rt[2] = rt2[2];
1973                                         rt[3] = rt2[3];
1974                                 } else {
1975                                         rt[0] = 0;
1976                                         rt[1] = 0;
1977                                         rt[2] = 0;
1978                                         rt[3] = 1.0;
1979                                 }
1980                         }
1981
1982                         rt+=4;
1983                         if(rt1 !=NULL){
1984                                 rt1+=4;
1985                         }
1986                         if(rt2 !=NULL){
1987                                 rt2+=4;
1988                         }
1989                 }
1990         }
1991 }
1992
1993 static struct ImBuf * do_wipe_effect(
1994         SeqRenderData context, Sequence *seq, float UNUSED(cfra),
1995         float facf0, float facf1, 
1996         struct ImBuf *ibuf1, struct ImBuf *ibuf2, 
1997         struct ImBuf *ibuf3)
1998 {
1999         struct ImBuf * out = prepare_effect_imbufs(context,ibuf1, ibuf2, ibuf3);
2000
2001         if (out->rect_float) {
2002                 do_wipe_effect_float(seq,
2003                                      facf0, facf1, context.rectx, context.recty,
2004                                      ibuf1->rect_float, ibuf2->rect_float,
2005                                      out->rect_float);
2006         } else {
2007                 do_wipe_effect_byte(seq,
2008                                     facf0, facf1, context.rectx, context.recty,
2009                                     (unsigned char*) ibuf1->rect, (unsigned char*) ibuf2->rect,
2010                                     (unsigned char*) out->rect);
2011         }
2012
2013         return out;
2014 }
2015 /* **********************************************************************
2016    TRANSFORM
2017    ********************************************************************** */
2018 static void init_transform_effect(Sequence *seq)
2019 {
2020         TransformVars *transform;
2021
2022         if(seq->effectdata)MEM_freeN(seq->effectdata);
2023         seq->effectdata = MEM_callocN(sizeof(struct TransformVars), "transformvars");
2024
2025         transform = (TransformVars *)seq->effectdata;
2026
2027         transform->ScalexIni = 1.0f;
2028         transform->ScaleyIni = 1.0f;
2029
2030         transform->xIni=0.0f;
2031         transform->yIni=0.0f;
2032
2033         transform->rotIni=0.0f;
2034         
2035         transform->interpolation=1;
2036         transform->percent=1;
2037         transform->uniform_scale=0;
2038 }
2039
2040 static int num_inputs_transform(void)
2041 {
2042         return 1;
2043 }
2044
2045 static void free_transform_effect(Sequence *seq)
2046 {
2047         if(seq->effectdata)MEM_freeN(seq->effectdata);
2048         seq->effectdata = NULL;
2049 }
2050
2051 static void copy_transform_effect(Sequence *dst, Sequence *src)
2052 {
2053         dst->effectdata = MEM_dupallocN(src->effectdata);
2054 }
2055
2056 static void transform_image(int x, int y, struct ImBuf *ibuf1, struct ImBuf *out, 
2057                             float scale_x, float scale_y, float translate_x, float translate_y, 
2058                             float rotate, int interpolation)
2059 {
2060         int xo, yo, xi, yi;
2061         float xt, yt, xr, yr;
2062         float s,c;
2063
2064         xo = x;
2065         yo = y;
2066         
2067         // Rotate
2068         s= sin(rotate);
2069         c= cos(rotate);
2070
2071         for (yi = 0; yi < yo; yi++) {
2072                 for (xi = 0; xi < xo; xi++) {
2073
2074                         //translate point
2075                         xt = xi-translate_x;
2076                         yt = yi-translate_y;
2077
2078                         //rotate point with center ref
2079                         xr =  c*xt + s*yt;
2080                         yr = -s*xt + c*yt;
2081
2082                         //scale point with center ref
2083                         xt = xr / scale_x;
2084                         yt = yr / scale_y;
2085
2086                         //undo reference center point 
2087                         xt += (xo / 2.0f);
2088                         yt += (yo / 2.0f);
2089
2090                         //interpolate
2091                         switch(interpolation) {
2092                         case 0:
2093                                 neareast_interpolation(ibuf1,out, xt,yt,xi,yi);
2094                                 break;
2095                         case 1:
2096                                 bilinear_interpolation(ibuf1,out, xt,yt,xi,yi);
2097                                 break;
2098                         case 2:
2099                                 bicubic_interpolation(ibuf1,out, xt,yt,xi,yi);
2100                                 break;
2101                         }
2102                 }
2103         }
2104 }
2105
2106 static void do_transform(Scene *scene, Sequence *seq, float UNUSED(facf0), int x, int y, 
2107                           struct ImBuf *ibuf1,struct ImBuf *out)
2108 {
2109         TransformVars *transform = (TransformVars *)seq->effectdata;
2110         float scale_x, scale_y, translate_x, translate_y, rotate_radians;
2111         
2112         // Scale
2113         if (transform->uniform_scale) {
2114                 scale_x = scale_y = transform->ScalexIni;
2115         } else {
2116                 scale_x = transform->ScalexIni;
2117                 scale_y = transform->ScaleyIni;
2118         }
2119
2120         // Translate
2121         if(!transform->percent){
2122                 float rd_s = (scene->r.size/100.0f);
2123
2124                 translate_x = transform->xIni*rd_s+(x/2.0f);
2125                 translate_y = transform->yIni*rd_s+(y/2.0f);
2126         }else{
2127                 translate_x = x*(transform->xIni/100.0f)+(x/2.0f);
2128                 translate_y = y*(transform->yIni/100.0f)+(y/2.0f);
2129         }
2130         
2131         // Rotate
2132         rotate_radians = DEG2RADF(transform->rotIni);
2133
2134         transform_image(x,y, ibuf1, out, scale_x, scale_y, translate_x, translate_y, rotate_radians, transform->interpolation);
2135 }
2136
2137
2138 static struct ImBuf * do_transform_effect(
2139         SeqRenderData context, Sequence *seq,float UNUSED(cfra),
2140         float facf0, float UNUSED(facf1), 
2141         struct ImBuf *ibuf1, struct ImBuf *ibuf2, 
2142         struct ImBuf *ibuf3)
2143 {
2144         struct ImBuf * out = prepare_effect_imbufs(context,ibuf1, ibuf2, ibuf3);
2145
2146         do_transform(context.scene, seq, facf0, 
2147                      context.rectx, context.recty, ibuf1, out);
2148
2149         return out;
2150 }
2151
2152
2153 /* **********************************************************************
2154    GLOW
2155    ********************************************************************** */
2156
2157 static void RVBlurBitmap2_byte ( unsigned char* map, int width,int height,
2158                                  float blur,
2159                                  int quality)
2160 /*      MUUUCCH better than the previous blur. */
2161 /*      We do the blurring in two passes which is a whole lot faster. */
2162 /*      I changed the math arount to implement an actual Gaussian */
2163 /*      distribution. */
2164 /* */
2165 /*      Watch out though, it tends to misbehaven with large blur values on */
2166 /*      a small bitmap.  Avoid avoid avoid. */
2167 /*=============================== */
2168 {
2169         unsigned char*  temp=NULL,*swap;
2170         float   *filter=NULL;
2171         int     x,y,i,fx,fy;
2172         int     index, ix, halfWidth;
2173         float   fval, k, curColor[3], curColor2[3], weight=0;
2174
2175         /*      If we're not really blurring, bail out */
2176         if (blur<=0)
2177                 return;
2178
2179         /*      Allocate memory for the tempmap and the blur filter matrix */
2180         temp= MEM_mallocN( (width*height*4), "blurbitmaptemp");
2181         if (!temp)
2182                 return;
2183
2184         /*      Allocate memory for the filter elements */
2185         halfWidth = ((quality+1)*blur);
2186         filter = (float *)MEM_mallocN(sizeof(float)*halfWidth*2, "blurbitmapfilter");
2187         if (!filter){
2188                 MEM_freeN (temp);
2189                 return;
2190         }
2191
2192         /*      Apparently we're calculating a bell curve */
2193         /*      based on the standard deviation (or radius) */
2194         /*      This code is based on an example */
2195         /*      posted to comp.graphics.algorithms by */
2196         /*      Blancmange (bmange@airdmhor.gen.nz) */
2197
2198         k = -1.0f/(2.0f*(float)M_PI*blur*blur);
2199         for (ix = 0;ix< halfWidth;ix++){
2200                 weight = (float)exp(k*(ix*ix));
2201                 filter[halfWidth - ix] = weight;
2202                 filter[halfWidth + ix] = weight;
2203         }
2204         filter[0] = weight;
2205
2206         /*      Normalize the array */
2207         fval=0;
2208         for (ix = 0;ix< halfWidth*2;ix++)
2209                 fval+=filter[ix];
2210
2211         for (ix = 0;ix< halfWidth*2;ix++)
2212                 filter[ix]/=fval;
2213
2214         /*      Blur the rows */
2215         for (y=0;y<height;y++){
2216                 /*      Do the left & right strips */
2217                 for (x=0;x<halfWidth;x++){
2218                         index=(x+y*width)*4;
2219                         fx=0;
2220                         curColor[0]=curColor[1]=curColor[2]=0;
2221                         curColor2[0]=curColor2[1]=curColor2[2]=0;
2222
2223                         for (i=x-halfWidth;i<x+halfWidth;i++){
2224                                 if ((i>=0)&&(i<width)){
2225                                         curColor[0]+=map[(i+y*width)*4+GlowR]*filter[fx];
2226                                         curColor[1]+=map[(i+y*width)*4+GlowG]*filter[fx];
2227                                         curColor[2]+=map[(i+y*width)*4+GlowB]*filter[fx];
2228
2229                                         curColor2[0]+=map[(width-1-i+y*width)*4+GlowR] *
2230                                                 filter[fx];
2231                                         curColor2[1]+=map[(width-1-i+y*width)*4+GlowG] *
2232                                                 filter[fx];
2233                                         curColor2[2]+=map[(width-1-i+y*width)*4+GlowB] *
2234                                                 filter[fx];
2235                                 }
2236                                 fx++;
2237                         }
2238                         temp[index+GlowR]=curColor[0];
2239                         temp[index+GlowG]=curColor[1];
2240                         temp[index+GlowB]=curColor[2];
2241
2242                         temp[((width-1-x+y*width)*4)+GlowR]=curColor2[0];
2243                         temp[((width-1-x+y*width)*4)+GlowG]=curColor2[1];
2244                         temp[((width-1-x+y*width)*4)+GlowB]=curColor2[2];
2245
2246                 }
2247                 /*      Do the main body */
2248                 for (x=halfWidth;x<width-halfWidth;x++){
2249                         index=(x+y*width)*4;
2250                         fx=0;
2251                         curColor[0]=curColor[1]=curColor[2]=0;
2252                         for (i=x-halfWidth;i<x+halfWidth;i++){
2253                                 curColor[0]+=map[(i+y*width)*4+GlowR]*filter[fx];
2254                                 curColor[1]+=map[(i+y*width)*4+GlowG]*filter[fx];
2255                                 curColor[2]+=map[(i+y*width)*4+GlowB]*filter[fx];
2256                                 fx++;
2257                         }
2258                         temp[index+GlowR]=curColor[0];
2259                         temp[index+GlowG]=curColor[1];
2260                         temp[index+GlowB]=curColor[2];
2261                 }
2262         }
2263
2264         /*      Swap buffers */
2265         swap=temp;temp=map;map=swap;
2266
2267
2268         /*      Blur the columns */
2269         for (x=0;x<width;x++){
2270                 /*      Do the top & bottom strips */
2271                 for (y=0;y<halfWidth;y++){
2272                         index=(x+y*width)*4;
2273                         fy=0;
2274                         curColor[0]=curColor[1]=curColor[2]=0;
2275                         curColor2[0]=curColor2[1]=curColor2[2]=0;
2276                         for (i=y-halfWidth;i<y+halfWidth;i++){
2277                                 if ((i>=0)&&(i<height)){
2278                                         /*      Bottom */
2279                                         curColor[0]+=map[(x+i*width)*4+GlowR]*filter[fy];
2280                                         curColor[1]+=map[(x+i*width)*4+GlowG]*filter[fy];
2281                                         curColor[2]+=map[(x+i*width)*4+GlowB]*filter[fy];
2282
2283                                         /*      Top */
2284                                         curColor2[0]+=map[(x+(height-1-i)*width) *
2285                                                 4+GlowR]*filter[fy];
2286                                         curColor2[1]+=map[(x+(height-1-i)*width) *
2287                                                 4+GlowG]*filter[fy];
2288                                         curColor2[2]+=map[(x+(height-1-i)*width) *
2289                                                 4+GlowB]*filter[fy];
2290                                 }
2291                                 fy++;
2292                         }
2293                         temp[index+GlowR]=curColor[0];
2294                         temp[index+GlowG]=curColor[1];
2295                         temp[index+GlowB]=curColor[2];
2296                         temp[((x+(height-1-y)*width)*4)+GlowR]=curColor2[0];
2297                         temp[((x+(height-1-y)*width)*4)+GlowG]=curColor2[1];
2298                         temp[((x+(height-1-y)*width)*4)+GlowB]=curColor2[2];
2299                 }
2300                 /*      Do the main body */
2301                 for (y=halfWidth;y<height-halfWidth;y++){
2302                         index=(x+y*width)*4;
2303                         fy=0;
2304                         curColor[0]=curColor[1]=curColor[2]=0;
2305                         for (i=y-halfWidth;i<y+halfWidth;i++){
2306                                 curColor[0]+=map[(x+i*width)*4+GlowR]*filter[fy];
2307                                 curColor[1]+=map[(x+i*width)*4+GlowG]*filter[fy];
2308                                 curColor[2]+=map[(x+i*width)*4+GlowB]*filter[fy];
2309                                 fy++;
2310                         }
2311                         temp[index+GlowR]=curColor[0];
2312                         temp[index+GlowG]=curColor[1];
2313                         temp[index+GlowB]=curColor[2];
2314                 }
2315         }
2316
2317
2318         /*      Swap buffers */
2319         swap=temp;temp=map; /* map=swap; */ /* UNUSED */
2320
2321         /*      Tidy up  */
2322         MEM_freeN (filter);
2323         MEM_freeN (temp);
2324 }
2325
2326 static void RVBlurBitmap2_float ( float* map, int width,int height,
2327                                   float blur,
2328                                   int quality)
2329 /*      MUUUCCH better than the previous blur. */
2330 /*      We do the blurring in two passes which is a whole lot faster. */
2331 /*      I changed the math arount to implement an actual Gaussian */
2332 /*      distribution. */
2333 /* */
2334 /*      Watch out though, it tends to misbehaven with large blur values on */
2335 /*      a small bitmap.  Avoid avoid avoid. */
2336 /*=============================== */
2337 {
2338         float*  temp=NULL,*swap;
2339         float   *filter=NULL;
2340         int     x,y,i,fx,fy;
2341         int     index, ix, halfWidth;
2342         float   fval, k, curColor[3], curColor2[3], weight=0;
2343
2344         /*      If we're not really blurring, bail out */
2345         if (blur<=0)
2346                 return;
2347
2348         /*      Allocate memory for the tempmap and the blur filter matrix */
2349         temp= MEM_mallocN( (width*height*4*sizeof(float)), "blurbitmaptemp");
2350         if (!temp)
2351                 return;
2352
2353         /*      Allocate memory for the filter elements */
2354         halfWidth = ((quality+1)*blur);
2355         filter = (float *)MEM_mallocN(sizeof(float)*halfWidth*2, "blurbitmapfilter");
2356         if (!filter){
2357                 MEM_freeN (temp);
2358                 return;
2359         }
2360
2361         /*      Apparently we're calculating a bell curve */
2362         /*      based on the standard deviation (or radius) */
2363         /*      This code is based on an example */
2364         /*      posted to comp.graphics.algorithms by */
2365         /*      Blancmange (bmange@airdmhor.gen.nz) */
2366
2367         k = -1.0f/(2.0f*(float)M_PI*blur*blur);
2368
2369         for (ix = 0;ix< halfWidth;ix++){
2370                 weight = (float)exp(k*(ix*ix));
2371                 filter[halfWidth - ix] = weight;
2372                 filter[halfWidth + ix] = weight;
2373         }
2374         filter[0] = weight;
2375
2376         /*      Normalize the array */
2377         fval=0;
2378         for (ix = 0;ix< halfWidth*2;ix++)
2379                 fval+=filter[ix];
2380
2381         for (ix = 0;ix< halfWidth*2;ix++)
2382                 filter[ix]/=fval;
2383
2384         /*      Blur the rows */
2385         for (y=0;y<height;y++){
2386                 /*      Do the left & right strips */
2387                 for (x=0;x<halfWidth;x++){
2388                         index=(x+y*width)*4;
2389                         fx=0;
2390                         curColor[0]=curColor[1]=curColor[2]=0.0f;
2391                         curColor2[0]=curColor2[1]=curColor2[2]=0.0f;
2392
2393                         for (i=x-halfWidth;i<x+halfWidth;i++){
2394                                 if ((i>=0)&&(i<width)){
2395                                         curColor[0]+=map[(i+y*width)*4+GlowR]*filter[fx];
2396                                         curColor[1]+=map[(i+y*width)*4+GlowG]*filter[fx];
2397                                         curColor[2]+=map[(i+y*width)*4+GlowB]*filter[fx];
2398
2399                                         curColor2[0]+=map[(width-1-i+y*width)*4+GlowR] *
2400                                                 filter[fx];
2401                                         curColor2[1]+=map[(width-1-i+y*width)*4+GlowG] *
2402                                                 filter[fx];
2403                                         curColor2[2]+=map[(width-1-i+y*width)*4+GlowB] *
2404                                                 filter[fx];
2405                                 }
2406                                 fx++;
2407                         }
2408                         temp[index+GlowR]=curColor[0];
2409                         temp[index+GlowG]=curColor[1];
2410                         temp[index+GlowB]=curColor[2];
2411
2412                         temp[((width-1-x+y*width)*4)+GlowR]=curColor2[0];
2413                         temp[((width-1-x+y*width)*4)+GlowG]=curColor2[1];
2414                         temp[((width-1-x+y*width)*4)+GlowB]=curColor2[2];
2415
2416                 }
2417                 /*      Do the main body */
2418                 for (x=halfWidth;x<width-halfWidth;x++){
2419                         index=(x+y*width)*4;
2420                         fx=0;
2421                         curColor[0]=curColor[1]=curColor[2]=0;
2422                         for (i=x-halfWidth;i<x+halfWidth;i++){
2423                                 curColor[0]+=map[(i+y*width)*4+GlowR]*filter[fx];
2424                                 curColor[1]+=map[(i+y*width)*4+GlowG]*filter[fx];
2425                                 curColor[2]+=map[(i+y*width)*4+GlowB]*filter[fx];
2426                                 fx++;
2427                         }
2428                         temp[index+GlowR]=curColor[0];
2429                         temp[index+GlowG]=curColor[1];
2430                         temp[index+GlowB]=curColor[2];
2431                 }
2432         }
2433
2434         /*      Swap buffers */
2435         swap=temp;temp=map;map=swap;
2436
2437
2438         /*      Blur the columns */
2439         for (x=0;x<width;x++){
2440                 /*      Do the top & bottom strips */
2441                 for (y=0;y<halfWidth;y++){
2442                         index=(x+y*width)*4;
2443                         fy=0;
2444                         curColor[0]=curColor[1]=curColor[2]=0;
2445                         curColor2[0]=curColor2[1]=curColor2[2]=0;
2446                         for (i=y-halfWidth;i<y+halfWidth;i++){
2447                                 if ((i>=0)&&(i<height)){
2448                                         /*      Bottom */
2449                                         curColor[0]+=map[(x+i*width)*4+GlowR]*filter[fy];
2450                                         curColor[1]+=map[(x+i*width)*4+GlowG]*filter[fy];
2451                                         curColor[2]+=map[(x+i*width)*4+GlowB]*filter[fy];
2452
2453                                         /*      Top */
2454                                         curColor2[0]+=map[(x+(height-1-i)*width) *
2455                                                 4+GlowR]*filter[fy];
2456                                         curColor2[1]+=map[(x+(height-1-i)*width) *
2457                                                 4+GlowG]*filter[fy];
2458                                         curColor2[2]+=map[(x+(height-1-i)*width) *
2459                                                 4+GlowB]*filter[fy];
2460                                 }
2461                                 fy++;
2462                         }
2463                         temp[index+GlowR]=curColor[0];
2464                         temp[index+GlowG]=curColor[1];
2465                         temp[index+GlowB]=curColor[2];
2466                         temp[((x+(height-1-y)*width)*4)+GlowR]=curColor2[0];
2467                         temp[((x+(height-1-y)*width)*4)+GlowG]=curColor2[1];
2468                         temp[((x+(height-1-y)*width)*4)+GlowB]=curColor2[2];
2469                 }
2470                 /*      Do the main body */
2471                 for (y=halfWidth;y<height-halfWidth;y++){
2472                         index=(x+y*width)*4;
2473                         fy=0;
2474                         curColor[0]=curColor[1]=curColor[2]=0;
2475                         for (i=y-halfWidth;i<y+halfWidth;i++){
2476                                 curColor[0]+=map[(x+i*width)*4+GlowR]*filter[fy];
2477                                 curColor[1]+=map[(x+i*width)*4+GlowG]*filter[fy];
2478                                 curColor[2]+=map[(x+i*width)*4+GlowB]*filter[fy];
2479                                 fy++;
2480                         }
2481                         temp[index+GlowR]=curColor[0];
2482                         temp[index+GlowG]=curColor[1];
2483                         temp[index+GlowB]=curColor[2];
2484                 }
2485         }
2486
2487
2488         /*      Swap buffers */
2489         swap=temp;temp=map; /* map=swap; */ /* UNUSED */
2490
2491         /*      Tidy up  */
2492         MEM_freeN (filter);
2493         MEM_freeN (temp);
2494 }
2495
2496
2497 /*      Adds two bitmaps and puts the results into a third map. */
2498 /*      C must have been previously allocated but it may be A or B. */
2499 /*      We clamp values to 255 to prevent weirdness */
2500 /*=============================== */
2501 static void RVAddBitmaps_byte (unsigned char* a, unsigned char* b, unsigned char* c, int width, int height)
2502 {
2503         int     x,y,index;
2504
2505         for (y=0;y<height;y++){
2506                 for (x=0;x<width;x++){
2507                         index=(x+y*width)*4;
2508                         c[index+GlowR]=MIN2(255,a[index+GlowR]+b[index+GlowR]);
2509                         c[index+GlowG]=MIN2(255,a[index+GlowG]+b[index+GlowG]);
2510                         c[index+GlowB]=MIN2(255,a[index+GlowB]+b[index+GlowB]);
2511                         c[index+GlowA]=MIN2(255,a[index+GlowA]+b[index+GlowA]);
2512                 }
2513         }
2514 }
2515
2516 static void RVAddBitmaps_float (float* a, float* b, float* c, 
2517                                 int width, int height)
2518 {
2519         int     x,y,index;
2520
2521         for (y=0;y<height;y++){
2522                 for (x=0;x<width;x++){
2523                         index=(x+y*width)*4;
2524                         c[index+GlowR]= MIN2(1.0f, a[index+GlowR]+b[index+GlowR]);
2525                         c[index+GlowG]= MIN2(1.0f, a[index+GlowG]+b[index+GlowG]);
2526                         c[index+GlowB]= MIN2(1.0f, a[index+GlowB]+b[index+GlowB]);
2527                         c[index+GlowA]= MIN2(1.0f, a[index+GlowA]+b[index+GlowA]);
2528                 }
2529         }
2530 }
2531
2532 /*      For each pixel whose total luminance exceeds the threshold, */
2533 /*      Multiply it's value by BOOST and add it to the output map */
2534 static void RVIsolateHighlights_byte (unsigned char* in, unsigned char* out, 
2535                                           int width, int height, int threshold, 
2536                                           float boost, float clamp)
2537 {
2538         int x,y,index;
2539         int     intensity;
2540
2541
2542         for(y=0;y< height;y++) {
2543                 for (x=0;x< width;x++) {
2544                         index= (x+y*width)*4;
2545
2546                         /*      Isolate the intensity */
2547                         intensity=(in[index+GlowR]+in[index+GlowG]+in[index+GlowB]-threshold);
2548                         if (intensity>0){
2549                                 out[index+GlowR]=MIN2(255*clamp, (in[index+GlowR]*boost*intensity)/255);
2550                                 out[index+GlowG]=MIN2(255*clamp, (in[index+GlowG]*boost*intensity)/255);
2551                                 out[index+GlowB]=MIN2(255*clamp, (in[index+GlowB]*boost*intensity)/255);
2552                                 out[index+GlowA]=MIN2(255*clamp, (in[index+GlowA]*boost*intensity)/255);
2553                         } else{
2554                                 out[index+GlowR]=0;
2555                                 out[index+GlowG]=0;
2556                                 out[index+GlowB]=0;
2557                                 out[index+GlowA]=0;
2558                         }
2559                 }
2560         }
2561 }
2562
2563 static void RVIsolateHighlights_float (float* in, float* out, 
2564                                           int width, int height, float threshold, 
2565                                           float boost, float clamp)
2566 {
2567         int x,y,index;
2568         float   intensity;
2569
2570
2571         for(y=0;y< height;y++) {
2572                 for (x=0;x< width;x++) {
2573                         index= (x+y*width)*4;
2574
2575                         /*      Isolate the intensity */
2576                         intensity=(in[index+GlowR]+in[index+GlowG]+in[index+GlowB]-threshold);
2577                         if (intensity>0){
2578                                 out[index+GlowR]=MIN2(clamp, (in[index+GlowR]*boost*intensity));
2579                                 out[index+GlowG]=MIN2(clamp, (in[index+GlowG]*boost*intensity));
2580                                 out[index+GlowB]=MIN2(clamp, (in[index+GlowB]*boost*intensity));
2581                                 out[index+GlowA]=MIN2(clamp, (in[index+GlowA]*boost*intensity));
2582                         } else{
2583                                 out[index+GlowR]=0;
2584                                 out[index+GlowG]=0;
2585                                 out[index+GlowB]=0;
2586                                 out[index+GlowA]=0;
2587                         }
2588                 }
2589         }
2590 }
2591
2592 static void init_glow_effect(Sequence *seq)
2593 {
2594         GlowVars *glow;
2595
2596         if(seq->effectdata)MEM_freeN(seq->effectdata);
2597         seq->effectdata = MEM_callocN(sizeof(struct GlowVars), "glowvars");
2598
2599         glow = (GlowVars *)seq->effectdata;
2600         glow->fMini = 0.25;
2601         glow->fClamp = 1.0;
2602         glow->fBoost = 0.5;
2603         glow->dDist = 3.0;
2604         glow->dQuality = 3;
2605         glow->bNoComp = 0;
2606 }
2607
2608 static int num_inputs_glow(void)
2609 {
2610         return 1;
2611 }
2612
2613 static void free_glow_effect(Sequence *seq)
2614 {
2615         if(seq->effectdata)MEM_freeN(seq->effectdata);
2616         seq->effectdata = NULL;
2617 }
2618
2619 static void copy_glow_effect(Sequence *dst, Sequence *src)
2620 {
2621         dst->effectdata = MEM_dupallocN(src->effectdata);
2622 }
2623
2624 //void do_glow_effect(Cast *cast, float facf0, float facf1, int xo, int yo, ImBuf *ibuf1, ImBuf *ibuf2, ImBuf *outbuf, ImBuf *use)
2625 static void do_glow_effect_byte(Sequence *seq, int render_size, float facf0, float UNUSED(facf1), 
2626                                 int x, int y, char *rect1, 
2627                                 char *UNUSED(rect2), char *out)
2628 {
2629         unsigned char *outbuf=(unsigned char *)out;
2630         unsigned char *inbuf=(unsigned char *)rect1;
2631         GlowVars *glow = (GlowVars *)seq->effectdata;
2632         
2633         RVIsolateHighlights_byte(inbuf, outbuf , x, y, glow->fMini*765, glow->fBoost * facf0, glow->fClamp);
2634         RVBlurBitmap2_byte (outbuf, x, y, glow->dDist * (render_size / 100.0f),glow->dQuality);
2635         if (!glow->bNoComp)
2636                 RVAddBitmaps_byte (inbuf , outbuf, outbuf, x, y);
2637 }
2638
2639 static void do_glow_effect_float(Sequence *seq, int render_size, float facf0, float UNUSED(facf1), 
2640                                  int x, int y, 
2641                                  float *rect1, float *UNUSED(rect2), float *out)
2642 {
2643         float *outbuf = out;
2644         float *inbuf = rect1;
2645         GlowVars *glow = (GlowVars *)seq->effectdata;
2646
2647         RVIsolateHighlights_float(inbuf, outbuf , x, y, glow->fMini*3.0f, glow->fBoost * facf0, glow->fClamp);
2648         RVBlurBitmap2_float (outbuf, x, y, glow->dDist * (render_size / 100.0f),glow->dQuality);
2649         if (!glow->bNoComp)
2650                 RVAddBitmaps_float (inbuf , outbuf, outbuf, x, y);
2651 }
2652
2653 static struct ImBuf * do_glow_effect(
2654         SeqRenderData context, Sequence *seq, float UNUSED(cfra),
2655         float facf0, float facf1, 
2656         struct ImBuf *ibuf1, struct ImBuf *ibuf2, 
2657         struct ImBuf *ibuf3)
2658 {
2659         struct ImBuf * out = prepare_effect_imbufs(context,ibuf1, ibuf2, ibuf3);
2660
2661         int render_size = 100*context.rectx/context.scene->r.xsch;
2662
2663         if (out->rect_float) {
2664                 do_glow_effect_float(seq, render_size,
2665                                      facf0, facf1, 
2666                                      context.rectx, context.recty,
2667                                      ibuf1->rect_float, ibuf2->rect_float,
2668                                      out->rect_float);
2669         } else {
2670                 do_glow_effect_byte(seq, render_size,
2671                                     facf0, facf1, 
2672                                     context.rectx, context.recty,
2673                                     (char*) ibuf1->rect, (char*) ibuf2->rect,
2674                                     (char*) out->rect);
2675         }
2676
2677         return out;
2678 }
2679
2680 /* **********************************************************************
2681    SOLID COLOR
2682    ********************************************************************** */
2683
2684 static void init_solid_color(Sequence *seq)
2685 {
2686         SolidColorVars *cv;
2687         
2688         if(seq->effectdata)MEM_freeN(seq->effectdata);
2689         seq->effectdata = MEM_callocN(sizeof(struct SolidColorVars), "solidcolor");
2690         
2691         cv = (SolidColorVars *)seq->effectdata;
2692         cv->col[0] = cv->col[1] = cv->col[2] = 0.5;
2693 }
2694
2695 static int num_inputs_color(void)
2696 {
2697         return 0;
2698 }
2699
2700 static void free_solid_color(Sequence *seq)
2701 {
2702         if(seq->effectdata)MEM_freeN(seq->effectdata);
2703         seq->effectdata = NULL;
2704 }
2705
2706 static void copy_solid_color(Sequence *dst, Sequence *src)
2707 {
2708         dst->effectdata = MEM_dupallocN(src->effectdata);
2709 }
2710
2711 static int early_out_color(struct Sequence *UNUSED(seq),
2712                            float UNUSED(facf0), float UNUSED(facf1))
2713 {
2714         return -1;
2715 }
2716
2717 static struct ImBuf * do_solid_color(
2718         SeqRenderData context, Sequence *seq, float UNUSED(cfra),
2719         float facf0, float facf1, 
2720         struct ImBuf *ibuf1, struct ImBuf *ibuf2, 
2721         struct ImBuf *ibuf3)
2722 {
2723         struct ImBuf * out = prepare_effect_imbufs(context,ibuf1, ibuf2, ibuf3);
2724
2725         SolidColorVars *cv = (SolidColorVars *)seq->effectdata;
2726
2727         unsigned char *rect;
2728         float *rect_float;
2729         int x; /*= context.rectx;*/ /*UNUSED*/
2730         int y; /*= context.recty;*/ /*UNUSED*/
2731
2732         if (out->rect) {
2733                 unsigned char col0[3];
2734                 unsigned char col1[3];
2735
2736                 col0[0] = facf0 * cv->col[0] * 255;
2737                 col0[1] = facf0 * cv->col[1] * 255;
2738                 col0[2] = facf0 * cv->col[2] * 255;
2739
2740                 col1[0] = facf1 * cv->col[0] * 255;
2741                 col1[1] = facf1 * cv->col[1] * 255;
2742                 col1[2] = facf1 * cv->col[2] * 255;
2743
2744                 rect = (unsigned char *)out->rect;
2745                 
2746                 for(y=0; y<out->y; y++) {       
2747                         for(x=0; x<out->x; x++, rect+=4) {
2748                                 rect[0]= col0[0];
2749                                 rect[1]= col0[1];
2750                                 rect[2]= col0[2];
2751                                 rect[3]= 255;
2752                         }
2753                         y++;
2754                         if (y<out->y) {
2755                                 for(x=0; x<out->x; x++, rect+=4) {
2756                                         rect[0]= col1[0];
2757                                         rect[1]= col1[1];
2758                                         rect[2]= col1[2];
2759                                         rect[3]= 255;
2760                                 }       
2761                         }
2762                 }
2763
2764         } else if (out->rect_float) {
2765                 float col0[3];
2766                 float col1[3];
2767
2768                 col0[0] = facf0 * cv->col[0];
2769                 col0[1] = facf0 * cv->col[1];
2770                 col0[2] = facf0 * cv->col[2];
2771
2772                 col1[0] = facf1 * cv->col[0];
2773                 col1[1] = facf1 * cv->col[1];
2774                 col1[2] = facf1 * cv->col[2];
2775
2776                 rect_float = out->rect_float;
2777                 
2778                 for(y=0; y<out->y; y++) {       
2779                         for(x=0; x<out->x; x++, rect_float+=4) {
2780                                 rect_float[0]= col0[0];
2781                                 rect_float[1]= col0[1];
2782                                 rect_float[2]= col0[2];
2783                                 rect_float[3]= 1.0;
2784                         }
2785                         y++;
2786                         if (y<out->y) {
2787                                 for(x=0; x<out->x; x++, rect_float+=4) {
2788                                         rect_float[0]= col1[0];
2789                                         rect_float[1]= col1[1];
2790                                         rect_float[2]= col1[2];
2791                                         rect_float[3]= 1.0;
2792                                 }
2793                         }
2794                 }
2795         }
2796         return out;
2797 }
2798
2799 /* **********************************************************************
2800    MULTICAM
2801    ********************************************************************** */
2802
2803 /* no effect inputs for multicam, we use give_ibuf_seq */
2804 static int num_inputs_multicam(void)
2805 {
2806         return 0;
2807 }
2808
2809 static int early_out_multicam(struct Sequence *UNUSED(seq), float UNUSED(facf0), float UNUSED(facf1))
2810 {
2811         return -1;
2812 }
2813
2814 static struct ImBuf * do_multicam(
2815         SeqRenderData context, Sequence *seq, float cfra,
2816         float UNUSED(facf0), float UNUSED(facf1),
2817         struct ImBuf *UNUSED(ibuf1), struct ImBuf *UNUSED(ibuf2), 
2818         struct ImBuf *UNUSED(ibuf3))
2819 {
2820         struct ImBuf * i;
2821         struct ImBuf * out;
2822         Editing * ed;
2823         ListBase * seqbasep;
2824
2825         if (seq->multicam_source == 0 || seq->multicam_source >= seq->machine) {
2826                 return NULL;
2827         }
2828
2829         ed = context.scene->ed;
2830         if (!ed) {
2831                 return NULL;
2832         }
2833         seqbasep = seq_seqbase(&ed->seqbase, seq);
2834         if (!seqbasep) {
2835                 return NULL;
2836         }
2837
2838         i = give_ibuf_seqbase(context, cfra, seq->multicam_source, seqbasep);
2839         if (!i) {
2840                 return NULL;
2841         }
2842
2843         if (input_have_to_preprocess(context, seq, cfra)) {
2844                 out = IMB_dupImBuf(i);
2845                 IMB_freeImBuf(i);
2846         } else {
2847                 out = i;
2848         }
2849         
2850         return out;
2851 }
2852
2853 /* **********************************************************************
2854    ADJUSTMENT
2855    ********************************************************************** */
2856
2857 /* no effect inputs for adjustment, we use give_ibuf_seq */
2858 static int num_inputs_adjustment(void)
2859 {
2860         return 0;
2861 }
2862
2863 static int early_out_adjustment(struct Sequence *UNUSED(seq), float UNUSED(facf0), float UNUSED(facf1))
2864 {
2865         return -1;
2866 }
2867
2868 static struct ImBuf * do_adjustment_impl(SeqRenderData context, Sequence * seq,
2869                                          float cfra)
2870 {
2871         Editing * ed;
2872         ListBase * seqbasep;
2873         struct ImBuf * i= NULL;
2874
2875         ed = context.scene->ed;
2876
2877         seqbasep = seq_seqbase(&ed->seqbase, seq);
2878
2879         if (seq->machine > 0) {
2880                 i = give_ibuf_seqbase(context, cfra,
2881                                       seq->machine - 1, seqbasep);
2882         }
2883
2884         /* found nothing? so let's work the way up the metastrip stack, so
2885            that it is possible to group a bunch of adjustment strips into
2886            a metastrip and have that work on everything below the metastrip
2887         */
2888            
2889         if (!i) {
2890                 Sequence * meta;
2891
2892                 meta = seq_metastrip(&ed->seqbase, NULL, seq);
2893
2894                 if (meta) {
2895                         i = do_adjustment_impl(context, meta, cfra);
2896                 }
2897         }
2898
2899         return i;
2900 }
2901
2902 static struct ImBuf * do_adjustment(
2903         SeqRenderData context, Sequence *seq, float cfra,
2904         float UNUSED(facf0), float UNUSED(facf1),
2905         struct ImBuf *UNUSED(ibuf1), struct ImBuf *UNUSED(ibuf2), 
2906         struct ImBuf *UNUSED(ibuf3))
2907 {
2908         struct ImBuf * i = NULL;
2909         struct ImBuf * out;
2910         Editing * ed;
2911
2912         ed = context.scene->ed;
2913
2914         if (!ed) {
2915                 return NULL;
2916         }
2917
2918         i = do_adjustment_impl(context, seq, cfra);
2919
2920         if (input_have_to_preprocess(context, seq, cfra)) {
2921                 out = IMB_dupImBuf(i);
2922                 IMB_freeImBuf(i);
2923         } else {
2924                 out = i;
2925         }
2926         
2927         return out;
2928 }
2929
2930 /* **********************************************************************
2931    SPEED
2932    ********************************************************************** */
2933 static void init_speed_effect(Sequence *seq)
2934 {
2935         SpeedControlVars * v;
2936
2937         if(seq->effectdata) MEM_freeN(seq->effectdata);
2938         seq->effectdata = MEM_callocN(sizeof(struct SpeedControlVars), 
2939                                           "speedcontrolvars");
2940
2941         v = (SpeedControlVars *)seq->effectdata;
2942         v->globalSpeed = 1.0;
2943         v->frameMap = NULL;
2944         v->flags |= SEQ_SPEED_INTEGRATE; /* should be default behavior */
2945         v->length = 0;
2946 }
2947
2948 static void load_speed_effect(Sequence * seq)
2949 {
2950         SpeedControlVars * v = (SpeedControlVars *)seq->effectdata;
2951
2952         v->frameMap = NULL;
2953         v->length = 0;
2954 }
2955
2956 static int num_inputs_speed(void)
2957 {
2958         return 1;
2959 }
2960
2961 static void free_speed_effect(Sequence *seq)
2962 {
2963         SpeedControlVars * v = (SpeedControlVars *)seq->effectdata;
2964         if(v->frameMap) MEM_freeN(v->frameMap);
2965         if(seq->effectdata) MEM_freeN(seq->effectdata);
2966         seq->effectdata = NULL;
2967 }
2968
2969 static void copy_speed_effect(Sequence *dst, Sequence *src)
2970 {
2971         SpeedControlVars * v;
2972         dst->effectdata = MEM_dupallocN(src->effectdata);
2973         v = (SpeedControlVars *)dst->effectdata;
2974         v->frameMap = NULL;
2975         v->length = 0;
2976 }
2977
2978 static int early_out_speed(struct Sequence *UNUSED(seq),
2979                           float UNUSED(facf0), float UNUSED(facf1))
2980 {
2981         return 1;
2982 }
2983
2984 static void store_icu_yrange_speed(struct Sequence * seq,
2985                                    short UNUSED(adrcode), float * ymin, float * ymax)
2986 {
2987         SpeedControlVars * v = (SpeedControlVars *)seq->effectdata;
2988
2989         /* if not already done, load / initialize data */
2990         get_sequence_effect(seq);
2991
2992         if ((v->flags & SEQ_SPEED_INTEGRATE) != 0) {
2993                 *ymin = -100.0;
2994                 *ymax = 100.0;
2995         } else {
2996                 if (v->flags & SEQ_SPEED_COMPRESS_IPO_Y) {
2997                         *ymin = 0.0;
2998                         *ymax = 1.0;
2999                 } else {
3000                         *ymin = 0.0;
3001                         *ymax = seq->len;
3002                 }
3003         }       
3004 }
3005 void sequence_effect_speed_rebuild_map(Scene *scene, Sequence * seq, int force)
3006 {
3007         int cfra;
3008         float fallback_fac = 1.0f;
3009         SpeedControlVars * v = (SpeedControlVars *)seq->effectdata;
3010         FCurve *fcu= NULL;
3011         int flags = v->flags;
3012
3013         /* if not already done, load / initialize data */
3014         get_sequence_effect(seq);
3015
3016         if (    (force == FALSE) &&
3017                         (seq->len == v->length) &&
3018                         (v->frameMap != NULL)
3019         ) {
3020                 return;
3021         }
3022         if (    (seq->seq1 == NULL) ||
3023                 (seq->len < 1)
3024         ) { /* make coverity happy and check for (CID 598)
3025                                                  input strip ... */
3026                 return;
3027         }
3028
3029         /* XXX - new in 2.5x. should we use the animation system this way?
3030          * The fcurve is needed because many frames need evaluating at once - campbell */
3031         fcu= id_data_find_fcurve(&scene->id, seq, &RNA_Sequence, "speed_factor", 0, NULL);
3032
3033
3034         if (!v->frameMap || v->length != seq->len) {
3035                 if (v->frameMap) MEM_freeN(v->frameMap);
3036
3037                 v->length = seq->len;
3038
3039                 v->frameMap = MEM_callocN(sizeof(float) * v->length, 
3040                                           "speedcontrol frameMap");
3041         }
3042
3043         fallback_fac = 1.0;
3044
3045         if (seq->flag & SEQ_USE_EFFECT_DEFAULT_FADE) {
3046                 if (seq->seq1->enddisp != seq->seq1->start
3047                     && seq->seq1->len != 0) {
3048                         fallback_fac = (float) seq->seq1->len / 
3049                                 (float) (seq->seq1->enddisp - seq->seq1->start);
3050                         flags = SEQ_SPEED_INTEGRATE;
3051                         fcu = NULL;
3052                 }
3053         } else {
3054                 /* if there is no fcurve, use value as simple multiplier */
3055                 if (!fcu) {
3056                         fallback_fac = seq->speed_fader; /* same as speed_factor in rna*/
3057                 }
3058         }
3059
3060         if (flags & SEQ_SPEED_INTEGRATE) {
3061                 float cursor = 0;
3062                 float facf;
3063
3064                 v->frameMap[0] = 0;
3065                 v->lastValidFrame = 0;
3066
3067                 for (cfra = 1; cfra < v->length; cfra++) {
3068                         if(fcu) {
3069                                 facf = evaluate_fcurve(fcu, seq->startdisp + cfra);
3070                         } else {
3071                                 facf = fallback_fac;
3072                         }
3073                         facf *= v->globalSpeed;
3074
3075                         cursor += facf;
3076
3077                         if (cursor >= seq->seq1->len) {
3078                                 v->frameMap[cfra] = seq->seq1->len - 1;
3079                         } else {
3080                                 v->frameMap[cfra] = cursor;
3081                                 v->lastValidFrame = cfra;
3082                         }
3083                 }
3084         } else {
3085                 float facf;
3086
3087                 v->lastValidFrame = 0;
3088                 for (cfra = 0; cfra < v->length; cfra++) {
3089
3090                         if(fcu) {
3091                                 facf = evaluate_fcurve(fcu, seq->startdisp + cfra);
3092                         } else {
3093                                 facf = fallback_fac;
3094                         }
3095
3096                         if (flags & SEQ_SPEED_COMPRESS_IPO_Y) {
3097                                 facf *= seq->seq1->len;
3098                         }
3099                         facf *= v->globalSpeed;
3100                         
3101                         if (facf >= seq->seq1->len) {
3102                                 facf = seq->seq1->len - 1;
3103                         } else {
3104                                 v->lastValidFrame = cfra;
3105                         }
3106                         v->frameMap[cfra] = facf;
3107                 }
3108         }
3109 }
3110
3111 /* **********************************************************************
3112    sequence effect factory
3113    ********************************************************************** */
3114
3115
3116 static void init_noop(struct Sequence *UNUSED(seq))
3117 {
3118
3119 }
3120
3121 static void load_noop(struct Sequence *UNUSED(seq))
3122 {
3123
3124 }
3125
3126 static void init_plugin_noop(struct Sequence *UNUSED(seq), const char *UNUSED(fname))
3127 {
3128
3129 }
3130
3131 static void free_noop(struct Sequence *UNUSED(seq))
3132 {
3133
3134 }