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