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