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