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