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