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