== Sequencer ==
[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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, 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_sequence.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(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(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(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(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(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(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(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(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(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(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 *scale;
1957
1958         if(seq->effectdata)MEM_freeN(seq->effectdata);
1959         seq->effectdata = MEM_callocN(sizeof(struct TransformVars), "transformvars");
1960
1961         scale = (TransformVars *)seq->effectdata;
1962         scale->ScalexIni = 1;
1963         scale->ScaleyIni = 1;
1964         scale->ScalexFin = 1;
1965         scale->ScaleyFin = 1;
1966         
1967         scale->xIni=0;
1968         scale->xFin=0;
1969         scale->yIni=0;
1970         scale->yFin=0;
1971         
1972         scale->rotIni=0;
1973         scale->rotFin=0;
1974         
1975         scale->interpolation=1;
1976         scale->percent=1;
1977 }
1978
1979 static int num_inputs_transform()
1980 {
1981         return 1;
1982 }
1983
1984 static void free_transform_effect(Sequence *seq)
1985 {
1986         if(seq->effectdata)MEM_freeN(seq->effectdata);
1987         seq->effectdata = 0;
1988 }
1989
1990 static void copy_transform_effect(Sequence *dst, Sequence *src)
1991 {
1992         dst->effectdata = MEM_dupallocN(src->effectdata);
1993 }
1994
1995 static void do_transform(Sequence * seq,float facf0, int x, int y, 
1996                           struct ImBuf *ibuf1,struct ImBuf *out)
1997 {
1998         int xo, yo, xi, yi;
1999         float xs,ys,factxScale,factyScale,tx,ty,rad,s,c,xaux,yaux,factRot,px,py;
2000         TransformVars *scale;
2001         
2002         // XXX struct RenderData *rd = NULL; // 2.5 global: &G.scene->r;
2003
2004
2005         scale = (TransformVars *)seq->effectdata;
2006         xo = x;
2007         yo = y;
2008
2009         //factor scale
2010         factxScale = scale->ScalexIni + (scale->ScalexFin - scale->ScalexIni) * facf0;
2011         factyScale = scale->ScaleyIni + (scale->ScaleyFin - scale->ScaleyIni) * facf0;
2012
2013         //Factor translate
2014         if(!scale->percent){
2015                 float rd_s = 0.0f; // XXX 2.5 global: (rd->size / 100.0f);
2016
2017                 tx = scale->xIni * rd_s+(xo / 2.0f) + (scale->xFin * rd_s -(xo / 2.0f) - scale->xIni * rd_s +(xo / 2.0f)) * facf0;
2018                 ty = scale->yIni * rd_s+(yo / 2.0f) + (scale->yFin * rd_s -(yo / 2.0f) - scale->yIni * rd_s +(yo / 2.0f)) * facf0;
2019         }else{
2020                 tx = xo*(scale->xIni/100.0f)+(xo / 2.0f) + (xo*(scale->xFin/100.0f)-(xo / 2.0f) - xo*(scale->xIni/100.0f)+(xo / 2.0f)) * facf0;
2021                 ty = yo*(scale->yIni/100.0f)+(yo / 2.0f) + (yo*(scale->yFin/100.0f)-(yo / 2.0f) - yo*(scale->yIni/100.0f)+(yo / 2.0f)) * facf0;
2022         }
2023
2024         //factor Rotate
2025         factRot = scale->rotIni + (scale->rotFin - scale->rotIni) * facf0;
2026         rad = (M_PI * factRot) / 180.0f;
2027         s= sin(rad);
2028         c= cos(rad);
2029
2030
2031         for (yi = 0; yi < yo; yi++) {
2032                 for (xi = 0; xi < xo; xi++) {
2033                         //tranlate point
2034                         px = xi-tx;
2035                         py = yi-ty;
2036
2037                         //rotate point with center ref
2038                         xaux = c*px + py*s ;
2039                         yaux = -s*px + c*py;
2040
2041                         //scale point with center ref
2042                         xs = xaux / factxScale;
2043                         ys = yaux / factyScale;
2044
2045                         //undo reference center point 
2046                         xs += (xo / 2.0f);
2047                         ys += (yo / 2.0f);
2048
2049                         //interpolate
2050                         switch(scale->interpolation) {
2051                         case 0:
2052                                 neareast_interpolation(ibuf1,out, xs,ys,xi,yi);
2053                                 break;
2054                         case 1:
2055                                 bilinear_interpolation(ibuf1,out, xs,ys,xi,yi);
2056                                 break;
2057                         case 2:
2058                                 bicubic_interpolation(ibuf1,out, xs,ys,xi,yi);
2059                                 break;
2060                         }
2061                 }
2062         }       
2063
2064 }
2065 static void do_transform_effect(Sequence * seq,int cfra,
2066                            float facf0, float facf1, int x, int y, 
2067                            struct ImBuf *ibuf1, struct ImBuf *ibuf2, 
2068                            struct ImBuf *ibuf3, struct ImBuf *out)
2069 {
2070         do_transform(seq, facf0, x, y, ibuf1, out);
2071 }
2072
2073
2074 /* **********************************************************************
2075    GLOW
2076    ********************************************************************** */
2077
2078 static void RVBlurBitmap2_byte ( unsigned char* map, int width,int height,
2079                                  float blur,
2080                                  int quality)
2081 /*      MUUUCCH better than the previous blur. */
2082 /*      We do the blurring in two passes which is a whole lot faster. */
2083 /*      I changed the math arount to implement an actual Gaussian */
2084 /*      distribution. */
2085 /* */
2086 /*      Watch out though, it tends to misbehaven with large blur values on */
2087 /*      a small bitmap.  Avoid avoid avoid. */
2088 /*=============================== */
2089 {
2090         unsigned char*  temp=NULL,*swap;
2091         float   *filter=NULL;
2092         int     x,y,i,fx,fy;
2093         int     index, ix, halfWidth;
2094         float   fval, k, curColor[3], curColor2[3], weight=0;
2095
2096         /*      If we're not really blurring, bail out */
2097         if (blur<=0)
2098                 return;
2099
2100         /*      Allocate memory for the tempmap and the blur filter matrix */
2101         temp= MEM_mallocN( (width*height*4), "blurbitmaptemp");
2102         if (!temp)
2103                 return;
2104
2105         /*      Allocate memory for the filter elements */
2106         halfWidth = ((quality+1)*blur);
2107         filter = (float *)MEM_mallocN(sizeof(float)*halfWidth*2, "blurbitmapfilter");
2108         if (!filter){
2109                 MEM_freeN (temp);
2110                 return;
2111         }
2112
2113         /*      Apparently we're calculating a bell curve */
2114         /*      based on the standard deviation (or radius) */
2115         /*      This code is based on an example */
2116         /*      posted to comp.graphics.algorithms by */
2117         /*      Blancmange (bmange@airdmhor.gen.nz) */
2118
2119         k = -1.0/(2.0*3.14159*blur*blur);
2120         fval=0;
2121         for (ix = 0;ix< halfWidth;ix++){
2122                 weight = (float)exp(k*(ix*ix));
2123                 filter[halfWidth - ix] = weight;
2124                 filter[halfWidth + ix] = weight;
2125         }
2126         filter[0] = weight;
2127
2128         /*      Normalize the array */
2129         fval=0;
2130         for (ix = 0;ix< halfWidth*2;ix++)
2131                 fval+=filter[ix];
2132
2133         for (ix = 0;ix< halfWidth*2;ix++)
2134                 filter[ix]/=fval;
2135
2136         /*      Blur the rows */
2137         for (y=0;y<height;y++){
2138                 /*      Do the left & right strips */
2139                 for (x=0;x<halfWidth;x++){
2140                         index=(x+y*width)*4;
2141                         fx=0;
2142                         curColor[0]=curColor[1]=curColor[2]=0;
2143                         curColor2[0]=curColor2[1]=curColor2[2]=0;
2144
2145                         for (i=x-halfWidth;i<x+halfWidth;i++){
2146                                 if ((i>=0)&&(i<width)){
2147                                         curColor[0]+=map[(i+y*width)*4+GlowR]*filter[fx];
2148                                         curColor[1]+=map[(i+y*width)*4+GlowG]*filter[fx];
2149                                         curColor[2]+=map[(i+y*width)*4+GlowB]*filter[fx];
2150
2151                                         curColor2[0]+=map[(width-1-i+y*width)*4+GlowR] *
2152                                                 filter[fx];
2153                                         curColor2[1]+=map[(width-1-i+y*width)*4+GlowG] *
2154                                                 filter[fx];
2155                                         curColor2[2]+=map[(width-1-i+y*width)*4+GlowB] *
2156                                                 filter[fx];
2157                                 }
2158                                 fx++;
2159                         }
2160                         temp[index+GlowR]=curColor[0];
2161                         temp[index+GlowG]=curColor[1];
2162                         temp[index+GlowB]=curColor[2];
2163
2164                         temp[((width-1-x+y*width)*4)+GlowR]=curColor2[0];
2165                         temp[((width-1-x+y*width)*4)+GlowG]=curColor2[1];
2166                         temp[((width-1-x+y*width)*4)+GlowB]=curColor2[2];
2167
2168                 }
2169                 /*      Do the main body */
2170                 for (x=halfWidth;x<width-halfWidth;x++){
2171                         index=(x+y*width)*4;
2172                         fx=0;
2173                         curColor[0]=curColor[1]=curColor[2]=0;
2174                         for (i=x-halfWidth;i<x+halfWidth;i++){
2175                                 curColor[0]+=map[(i+y*width)*4+GlowR]*filter[fx];
2176                                 curColor[1]+=map[(i+y*width)*4+GlowG]*filter[fx];
2177                                 curColor[2]+=map[(i+y*width)*4+GlowB]*filter[fx];
2178                                 fx++;
2179                         }
2180                         temp[index+GlowR]=curColor[0];
2181                         temp[index+GlowG]=curColor[1];
2182                         temp[index+GlowB]=curColor[2];
2183                 }
2184         }
2185
2186         /*      Swap buffers */
2187         swap=temp;temp=map;map=swap;
2188
2189
2190         /*      Blur the columns */
2191         for (x=0;x<width;x++){
2192                 /*      Do the top & bottom strips */
2193                 for (y=0;y<halfWidth;y++){
2194                         index=(x+y*width)*4;
2195                         fy=0;
2196                         curColor[0]=curColor[1]=curColor[2]=0;
2197                         curColor2[0]=curColor2[1]=curColor2[2]=0;
2198                         for (i=y-halfWidth;i<y+halfWidth;i++){
2199                                 if ((i>=0)&&(i<height)){
2200                                         /*      Bottom */
2201                                         curColor[0]+=map[(x+i*width)*4+GlowR]*filter[fy];
2202                                         curColor[1]+=map[(x+i*width)*4+GlowG]*filter[fy];
2203                                         curColor[2]+=map[(x+i*width)*4+GlowB]*filter[fy];
2204
2205                                         /*      Top */
2206                                         curColor2[0]+=map[(x+(height-1-i)*width) *
2207                                                 4+GlowR]*filter[fy];
2208                                         curColor2[1]+=map[(x+(height-1-i)*width) *
2209                                                 4+GlowG]*filter[fy];
2210                                         curColor2[2]+=map[(x+(height-1-i)*width) *
2211                                                 4+GlowB]*filter[fy];
2212                                 }
2213                                 fy++;
2214                         }
2215                         temp[index+GlowR]=curColor[0];
2216                         temp[index+GlowG]=curColor[1];
2217                         temp[index+GlowB]=curColor[2];
2218                         temp[((x+(height-1-y)*width)*4)+GlowR]=curColor2[0];
2219                         temp[((x+(height-1-y)*width)*4)+GlowG]=curColor2[1];
2220                         temp[((x+(height-1-y)*width)*4)+GlowB]=curColor2[2];
2221                 }
2222                 /*      Do the main body */
2223                 for (y=halfWidth;y<height-halfWidth;y++){
2224                         index=(x+y*width)*4;
2225                         fy=0;
2226                         curColor[0]=curColor[1]=curColor[2]=0;
2227                         for (i=y-halfWidth;i<y+halfWidth;i++){
2228                                 curColor[0]+=map[(x+i*width)*4+GlowR]*filter[fy];
2229                                 curColor[1]+=map[(x+i*width)*4+GlowG]*filter[fy];
2230                                 curColor[2]+=map[(x+i*width)*4+GlowB]*filter[fy];
2231                                 fy++;
2232                         }
2233                         temp[index+GlowR]=curColor[0];
2234                         temp[index+GlowG]=curColor[1];
2235                         temp[index+GlowB]=curColor[2];
2236                 }
2237         }
2238
2239
2240         /*      Swap buffers */
2241         swap=temp;temp=map;map=swap;
2242
2243         /*      Tidy up  */
2244         MEM_freeN (filter);
2245         MEM_freeN (temp);
2246 }
2247
2248 static void RVBlurBitmap2_float ( float* map, int width,int height,
2249                                   float blur,
2250                                   int quality)
2251 /*      MUUUCCH better than the previous blur. */
2252 /*      We do the blurring in two passes which is a whole lot faster. */
2253 /*      I changed the math arount to implement an actual Gaussian */
2254 /*      distribution. */
2255 /* */
2256 /*      Watch out though, it tends to misbehaven with large blur values on */
2257 /*      a small bitmap.  Avoid avoid avoid. */
2258 /*=============================== */
2259 {
2260         float*  temp=NULL,*swap;
2261         float   *filter=NULL;
2262         int     x,y,i,fx,fy;
2263         int     index, ix, halfWidth;
2264         float   fval, k, curColor[3], curColor2[3], weight=0;
2265
2266         /*      If we're not really blurring, bail out */
2267         if (blur<=0)
2268                 return;
2269
2270         /*      Allocate memory for the tempmap and the blur filter matrix */
2271         temp= MEM_mallocN( (width*height*4*sizeof(float)), "blurbitmaptemp");
2272         if (!temp)
2273                 return;
2274
2275         /*      Allocate memory for the filter elements */
2276         halfWidth = ((quality+1)*blur);
2277         filter = (float *)MEM_mallocN(sizeof(float)*halfWidth*2, "blurbitmapfilter");
2278         if (!filter){
2279                 MEM_freeN (temp);
2280                 return;
2281         }
2282
2283         /*      Apparently we're calculating a bell curve */
2284         /*      based on the standard deviation (or radius) */
2285         /*      This code is based on an example */
2286         /*      posted to comp.graphics.algorithms by */
2287         /*      Blancmange (bmange@airdmhor.gen.nz) */
2288
2289         k = -1.0/(2.0*3.14159*blur*blur);
2290         fval=0;
2291         for (ix = 0;ix< halfWidth;ix++){
2292                 weight = (float)exp(k*(ix*ix));
2293                 filter[halfWidth - ix] = weight;
2294                 filter[halfWidth + ix] = weight;
2295         }
2296         filter[0] = weight;
2297
2298         /*      Normalize the array */
2299         fval=0;
2300         for (ix = 0;ix< halfWidth*2;ix++)
2301                 fval+=filter[ix];
2302
2303         for (ix = 0;ix< halfWidth*2;ix++)
2304                 filter[ix]/=fval;
2305
2306         /*      Blur the rows */
2307         for (y=0;y<height;y++){
2308                 /*      Do the left & right strips */
2309                 for (x=0;x<halfWidth;x++){
2310                         index=(x+y*width)*4;
2311                         fx=0;
2312                         curColor[0]=curColor[1]=curColor[2]=0.0f;
2313                         curColor2[0]=curColor2[1]=curColor2[2]=0.0f;
2314
2315                         for (i=x-halfWidth;i<x+halfWidth;i++){
2316                                 if ((i>=0)&&(i<width)){
2317                                         curColor[0]+=map[(i+y*width)*4+GlowR]*filter[fx];
2318                                         curColor[1]+=map[(i+y*width)*4+GlowG]*filter[fx];
2319                                         curColor[2]+=map[(i+y*width)*4+GlowB]*filter[fx];
2320
2321                                         curColor2[0]+=map[(width-1-i+y*width)*4+GlowR] *
2322                                                 filter[fx];
2323                                         curColor2[1]+=map[(width-1-i+y*width)*4+GlowG] *
2324                                                 filter[fx];
2325                                         curColor2[2]+=map[(width-1-i+y*width)*4+GlowB] *
2326                                                 filter[fx];
2327                                 }
2328                                 fx++;
2329                         }
2330                         temp[index+GlowR]=curColor[0];
2331                         temp[index+GlowG]=curColor[1];
2332                         temp[index+GlowB]=curColor[2];
2333
2334                         temp[((width-1-x+y*width)*4)+GlowR]=curColor2[0];
2335                         temp[((width-1-x+y*width)*4)+GlowG]=curColor2[1];
2336                         temp[((width-1-x+y*width)*4)+GlowB]=curColor2[2];
2337
2338                 }
2339                 /*      Do the main body */
2340                 for (x=halfWidth;x<width-halfWidth;x++){
2341                         index=(x+y*width)*4;
2342                         fx=0;
2343                         curColor[0]=curColor[1]=curColor[2]=0;
2344                         for (i=x-halfWidth;i<x+halfWidth;i++){
2345                                 curColor[0]+=map[(i+y*width)*4+GlowR]*filter[fx];
2346                                 curColor[1]+=map[(i+y*width)*4+GlowG]*filter[fx];
2347                                 curColor[2]+=map[(i+y*width)*4+GlowB]*filter[fx];
2348                                 fx++;
2349                         }
2350                         temp[index+GlowR]=curColor[0];
2351                         temp[index+GlowG]=curColor[1];
2352                         temp[index+GlowB]=curColor[2];
2353                 }
2354         }
2355
2356         /*      Swap buffers */
2357         swap=temp;temp=map;map=swap;
2358
2359
2360         /*      Blur the columns */
2361         for (x=0;x<width;x++){
2362                 /*      Do the top & bottom strips */
2363                 for (y=0;y<halfWidth;y++){
2364                         index=(x+y*width)*4;
2365                         fy=0;
2366                         curColor[0]=curColor[1]=curColor[2]=0;
2367                         curColor2[0]=curColor2[1]=curColor2[2]=0;
2368                         for (i=y-halfWidth;i<y+halfWidth;i++){
2369                                 if ((i>=0)&&(i<height)){
2370                                         /*      Bottom */
2371                                         curColor[0]+=map[(x+i*width)*4+GlowR]*filter[fy];
2372                                         curColor[1]+=map[(x+i*width)*4+GlowG]*filter[fy];
2373                                         curColor[2]+=map[(x+i*width)*4+GlowB]*filter[fy];
2374
2375                                         /*      Top */
2376                                         curColor2[0]+=map[(x+(height-1-i)*width) *
2377                                                 4+GlowR]*filter[fy];
2378                                         curColor2[1]+=map[(x+(height-1-i)*width) *
2379                                                 4+GlowG]*filter[fy];
2380                                         curColor2[2]+=map[(x+(height-1-i)*width) *
2381                                                 4+GlowB]*filter[fy];
2382                                 }
2383                                 fy++;
2384                         }
2385                         temp[index+GlowR]=curColor[0];
2386                         temp[index+GlowG]=curColor[1];
2387                         temp[index+GlowB]=curColor[2];
2388                         temp[((x+(height-1-y)*width)*4)+GlowR]=curColor2[0];
2389                         temp[((x+(height-1-y)*width)*4)+GlowG]=curColor2[1];
2390                         temp[((x+(height-1-y)*width)*4)+GlowB]=curColor2[2];
2391                 }
2392                 /*      Do the main body */
2393                 for (y=halfWidth;y<height-halfWidth;y++){
2394                         index=(x+y*width)*4;
2395                         fy=0;
2396                         curColor[0]=curColor[1]=curColor[2]=0;
2397                         for (i=y-halfWidth;i<y+halfWidth;i++){
2398                                 curColor[0]+=map[(x+i*width)*4+GlowR]*filter[fy];
2399                                 curColor[1]+=map[(x+i*width)*4+GlowG]*filter[fy];
2400                                 curColor[2]+=map[(x+i*width)*4+GlowB]*filter[fy];
2401                                 fy++;
2402                         }
2403                         temp[index+GlowR]=curColor[0];
2404                         temp[index+GlowG]=curColor[1];
2405                         temp[index+GlowB]=curColor[2];
2406                 }
2407         }
2408
2409
2410         /*      Swap buffers */
2411         swap=temp;temp=map;map=swap;
2412
2413         /*      Tidy up  */
2414         MEM_freeN (filter);
2415         MEM_freeN (temp);
2416 }
2417
2418
2419 /*      Adds two bitmaps and puts the results into a third map. */
2420 /*      C must have been previously allocated but it may be A or B. */
2421 /*      We clamp values to 255 to prevent weirdness */
2422 /*=============================== */
2423 static void RVAddBitmaps_byte (unsigned char* a, unsigned char* b, unsigned char* c, int width, int height)
2424 {
2425         int     x,y,index;
2426
2427         for (y=0;y<height;y++){
2428                 for (x=0;x<width;x++){
2429                         index=(x+y*width)*4;
2430                         c[index+GlowR]=MIN2(255,a[index+GlowR]+b[index+GlowR]);
2431                         c[index+GlowG]=MIN2(255,a[index+GlowG]+b[index+GlowG]);
2432                         c[index+GlowB]=MIN2(255,a[index+GlowB]+b[index+GlowB]);
2433                         c[index+GlowA]=MIN2(255,a[index+GlowA]+b[index+GlowA]);
2434                 }
2435         }
2436 }
2437
2438 static void RVAddBitmaps_float (float* a, float* b, float* c, 
2439                                 int width, int height)
2440 {
2441         int     x,y,index;
2442
2443         for (y=0;y<height;y++){
2444                 for (x=0;x<width;x++){
2445                         index=(x+y*width)*4;
2446                         c[index+GlowR]=MIN2(1.0,a[index+GlowR]+b[index+GlowR]);
2447                         c[index+GlowG]=MIN2(1.0,a[index+GlowG]+b[index+GlowG]);
2448                         c[index+GlowB]=MIN2(1.0,a[index+GlowB]+b[index+GlowB]);
2449                         c[index+GlowA]=MIN2(1.0,a[index+GlowA]+b[index+GlowA]);
2450                 }
2451         }
2452 }
2453
2454 /*      For each pixel whose total luminance exceeds the threshold, */
2455 /*      Multiply it's value by BOOST and add it to the output map */
2456 static void RVIsolateHighlights_byte (unsigned char* in, unsigned char* out, 
2457                                       int width, int height, int threshold, 
2458                                       float boost, float clamp)
2459 {
2460         int x,y,index;
2461         int     intensity;
2462
2463
2464         for(y=0;y< height;y++) {
2465                 for (x=0;x< width;x++) {
2466                         index= (x+y*width)*4;
2467
2468                         /*      Isolate the intensity */
2469                         intensity=(in[index+GlowR]+in[index+GlowG]+in[index+GlowB]-threshold);
2470                         if (intensity>0){
2471                                 out[index+GlowR]=MIN2(255*clamp, (in[index+GlowR]*boost*intensity)/255);
2472                                 out[index+GlowG]=MIN2(255*clamp, (in[index+GlowG]*boost*intensity)/255);
2473                                 out[index+GlowB]=MIN2(255*clamp, (in[index+GlowB]*boost*intensity)/255);
2474                                 out[index+GlowA]=MIN2(255*clamp, (in[index+GlowA]*boost*intensity)/255);
2475                         } else{
2476                                 out[index+GlowR]=0;
2477                                 out[index+GlowG]=0;
2478                                 out[index+GlowB]=0;
2479                                 out[index+GlowA]=0;
2480                         }
2481                 }
2482         }
2483 }
2484
2485 static void RVIsolateHighlights_float (float* in, float* out, 
2486                                       int width, int height, float threshold, 
2487                                       float boost, float clamp)
2488 {
2489         int x,y,index;
2490         float   intensity;
2491
2492
2493         for(y=0;y< height;y++) {
2494                 for (x=0;x< width;x++) {
2495                         index= (x+y*width)*4;
2496
2497                         /*      Isolate the intensity */
2498                         intensity=(in[index+GlowR]+in[index+GlowG]+in[index+GlowB]-threshold);
2499                         if (intensity>0){
2500                                 out[index+GlowR]=MIN2(clamp, (in[index+GlowR]*boost*intensity));
2501                                 out[index+GlowG]=MIN2(clamp, (in[index+GlowG]*boost*intensity));
2502                                 out[index+GlowB]=MIN2(clamp, (in[index+GlowB]*boost*intensity));
2503                                 out[index+GlowA]=MIN2(clamp, (in[index+GlowA]*boost*intensity));
2504                         } else{
2505                                 out[index+GlowR]=0;
2506                                 out[index+GlowG]=0;
2507                                 out[index+GlowB]=0;
2508                                 out[index+GlowA]=0;
2509                         }
2510                 }
2511         }
2512 }
2513
2514 static void init_glow_effect(Sequence *seq)
2515 {
2516         GlowVars *glow;
2517
2518         if(seq->effectdata)MEM_freeN(seq->effectdata);
2519         seq->effectdata = MEM_callocN(sizeof(struct GlowVars), "glowvars");
2520
2521         glow = (GlowVars *)seq->effectdata;
2522         glow->fMini = 0.25;
2523         glow->fClamp = 1.0;
2524         glow->fBoost = 0.5;
2525         glow->dDist = 3.0;
2526         glow->dQuality = 3;
2527         glow->bNoComp = 0;
2528 }
2529
2530 static int num_inputs_glow()
2531 {
2532         return 1;
2533 }
2534
2535 static void free_glow_effect(Sequence *seq)
2536 {
2537         if(seq->effectdata)MEM_freeN(seq->effectdata);
2538         seq->effectdata = 0;
2539 }
2540
2541 static void copy_glow_effect(Sequence *dst, Sequence *src)
2542 {
2543         dst->effectdata = MEM_dupallocN(src->effectdata);
2544 }
2545
2546 //void do_glow_effect(Cast *cast, float facf0, float facf1, int xo, int yo, ImBuf *ibuf1, ImBuf *ibuf2, ImBuf *outbuf, ImBuf *use)
2547 static void do_glow_effect_byte(Sequence *seq, float facf0, float facf1, 
2548                                 int x, int y, char *rect1, 
2549                                 char *rect2, char *out)
2550 {
2551         unsigned char *outbuf=(unsigned char *)out;
2552         unsigned char *inbuf=(unsigned char *)rect1;
2553         GlowVars *glow = (GlowVars *)seq->effectdata;
2554         int size= 100; // renderdata XXX
2555         
2556         RVIsolateHighlights_byte(inbuf, outbuf , x, y, glow->fMini*765, glow->fBoost * facf0, glow->fClamp);
2557         RVBlurBitmap2_byte (outbuf, x, y, glow->dDist * (size / 100.0f),glow->dQuality);
2558         if (!glow->bNoComp)
2559                 RVAddBitmaps_byte (inbuf , outbuf, outbuf, x, y);
2560 }
2561
2562 static void do_glow_effect_float(Sequence *seq, float facf0, float facf1, 
2563                                  int x, int y, 
2564                                  float *rect1, float *rect2, float *out)
2565 {
2566         float *outbuf = out;
2567         float *inbuf = rect1;
2568         GlowVars *glow = (GlowVars *)seq->effectdata;
2569         int size= 100; // renderdata XXX
2570
2571         RVIsolateHighlights_float(inbuf, outbuf , x, y, glow->fMini*3.0f, glow->fBoost * facf0, glow->fClamp);
2572         RVBlurBitmap2_float (outbuf, x, y, glow->dDist * (size / 100.0f),glow->dQuality);
2573         if (!glow->bNoComp)
2574                 RVAddBitmaps_float (inbuf , outbuf, outbuf, x, y);
2575 }
2576
2577 static void do_glow_effect(Sequence * seq,int cfra,
2578                            float facf0, float facf1, int x, int y, 
2579                            struct ImBuf *ibuf1, struct ImBuf *ibuf2, 
2580                            struct ImBuf *ibuf3, struct ImBuf *out)
2581 {
2582         if (out->rect_float) {
2583                 do_glow_effect_float(seq,
2584                                      facf0, facf1, x, y,
2585                                      ibuf1->rect_float, ibuf2->rect_float,
2586                                      out->rect_float);
2587         } else {
2588                 do_glow_effect_byte(seq,
2589                                     facf0, facf1, x, y,
2590                                     (char*) ibuf1->rect, (char*) ibuf2->rect,
2591                                     (char*) out->rect);
2592         }
2593 }
2594
2595 /* **********************************************************************
2596    SOLID COLOR
2597    ********************************************************************** */
2598
2599 static void init_solid_color(Sequence *seq)
2600 {
2601         SolidColorVars *cv;
2602         
2603         if(seq->effectdata)MEM_freeN(seq->effectdata);
2604         seq->effectdata = MEM_callocN(sizeof(struct SolidColorVars), "solidcolor");
2605         
2606         cv = (SolidColorVars *)seq->effectdata;
2607         cv->col[0] = cv->col[1] = cv->col[2] = 0.5;
2608 }
2609
2610 static int num_inputs_color()
2611 {
2612         return 0;
2613 }
2614
2615 static void free_solid_color(Sequence *seq)
2616 {
2617         if(seq->effectdata)MEM_freeN(seq->effectdata);
2618         seq->effectdata = 0;
2619 }
2620
2621 static void copy_solid_color(Sequence *dst, Sequence *src)
2622 {
2623         dst->effectdata = MEM_dupallocN(src->effectdata);
2624 }
2625
2626 static int early_out_color(struct Sequence *seq,
2627                            float facf0, float facf1)
2628 {
2629         return -1;
2630 }
2631
2632 static void do_solid_color(Sequence * seq,int cfra,
2633                            float facf0, float facf1, int x, int y, 
2634                            struct ImBuf *ibuf1, struct ImBuf *ibuf2, 
2635                            struct ImBuf *ibuf3, struct ImBuf *out)
2636 {
2637         SolidColorVars *cv = (SolidColorVars *)seq->effectdata;
2638
2639         unsigned char *rect;
2640         float *rect_float;
2641
2642         if (out->rect) {
2643                 unsigned char col0[3];
2644                 unsigned char col1[3];
2645
2646                 col0[0] = facf0 * cv->col[0] * 255;
2647                 col0[1] = facf0 * cv->col[1] * 255;
2648                 col0[2] = facf0 * cv->col[2] * 255;
2649
2650                 col1[0] = facf1 * cv->col[0] * 255;
2651                 col1[1] = facf1 * cv->col[1] * 255;
2652                 col1[2] = facf1 * cv->col[2] * 255;
2653
2654                 rect = (unsigned char *)out->rect;
2655                 
2656                 for(y=0; y<out->y; y++) {       
2657                         for(x=0; x<out->x; x++, rect+=4) {
2658                                 rect[0]= col0[0];
2659                                 rect[1]= col0[1];
2660                                 rect[2]= col0[2];
2661                                 rect[3]= 255;
2662                         }
2663                         y++;
2664                         if (y<out->y) {
2665                                 for(x=0; x<out->x; x++, rect+=4) {
2666                                         rect[0]= col1[0];
2667                                         rect[1]= col1[1];
2668                                         rect[2]= col1[2];
2669                                         rect[3]= 255;
2670                                 }       
2671                         }
2672                 }
2673
2674         } else if (out->rect_float) {
2675                 float col0[3];
2676                 float col1[3];
2677
2678                 col0[0] = facf0 * cv->col[0];
2679                 col0[1] = facf0 * cv->col[1];
2680                 col0[2] = facf0 * cv->col[2];
2681
2682                 col1[0] = facf1 * cv->col[0];
2683                 col1[1] = facf1 * cv->col[1];
2684                 col1[2] = facf1 * cv->col[2];
2685
2686                 rect_float = out->rect_float;
2687                 
2688                 for(y=0; y<out->y; y++) {       
2689                         for(x=0; x<out->x; x++, rect_float+=4) {
2690                                 rect_float[0]= col0[0];
2691                                 rect_float[1]= col0[1];
2692                                 rect_float[2]= col0[2];
2693                                 rect_float[3]= 1.0;
2694                         }
2695                         y++;
2696                         if (y<out->y) {
2697                                 for(x=0; x<out->x; x++, rect_float+=4) {
2698                                         rect_float[0]= col1[0];
2699                                         rect_float[1]= col1[1];
2700                                         rect_float[2]= col1[2];
2701                                         rect_float[3]= 1.0;
2702                                 }
2703                         }
2704                 }
2705         }
2706 }
2707
2708 /* **********************************************************************
2709    SPEED
2710    ********************************************************************** */
2711 static void init_speed_effect(Sequence *seq)
2712 {
2713         SpeedControlVars * v;
2714
2715         if(seq->effectdata) MEM_freeN(seq->effectdata);
2716         seq->effectdata = MEM_callocN(sizeof(struct SpeedControlVars), 
2717                                       "speedcontrolvars");
2718
2719         v = (SpeedControlVars *)seq->effectdata;
2720         v->globalSpeed = 1.0;
2721         v->frameMap = 0;
2722         v->flags = SEQ_SPEED_COMPRESS_IPO_Y;
2723         v->length = 0;
2724 }
2725
2726 static void load_speed_effect(Sequence * seq)
2727 {
2728         SpeedControlVars * v = (SpeedControlVars *)seq->effectdata;
2729
2730         v->frameMap = 0;
2731         v->length = 0;
2732 }
2733
2734 static int num_inputs_speed()
2735 {
2736         return 1;
2737 }
2738
2739 static void free_speed_effect(Sequence *seq)
2740 {
2741         SpeedControlVars * v = (SpeedControlVars *)seq->effectdata;
2742         if(v->frameMap) MEM_freeN(v->frameMap);
2743         if(seq->effectdata) MEM_freeN(seq->effectdata);
2744         seq->effectdata = 0;
2745 }
2746
2747 static void copy_speed_effect(Sequence *dst, Sequence *src)
2748 {
2749         SpeedControlVars * v;
2750         dst->effectdata = MEM_dupallocN(src->effectdata);
2751         v = (SpeedControlVars *)dst->effectdata;
2752         v->frameMap = 0;
2753         v->length = 0;
2754 }
2755
2756 static int early_out_speed(struct Sequence *seq,
2757                           float facf0, float facf1)
2758 {
2759         return 1;
2760 }
2761
2762 static void store_icu_yrange_speed(struct Sequence * seq,
2763                                    short adrcode, float * ymin, float * ymax)
2764 {
2765         SpeedControlVars * v = (SpeedControlVars *)seq->effectdata;
2766
2767         /* if not already done, load / initialize data */
2768         get_sequence_effect(seq);
2769
2770         if ((v->flags & SEQ_SPEED_INTEGRATE) != 0) {
2771                 *ymin = -100.0;
2772                 *ymax = 100.0;
2773         } else {
2774                 if (v->flags & SEQ_SPEED_COMPRESS_IPO_Y) {
2775                         *ymin = 0.0;
2776                         *ymax = 1.0;
2777                 } else {
2778                         *ymin = 0.0;
2779                         *ymax = seq->len;
2780                 }
2781         }       
2782 }
2783 void sequence_effect_speed_rebuild_map(Scene *scene, Sequence * seq, int force)
2784 {
2785         float ctime, div;
2786         int cfra;
2787         float fallback_fac;
2788         SpeedControlVars * v = (SpeedControlVars *)seq->effectdata;
2789         FCurve *fcu= NULL;
2790
2791         /* if not already done, load / initialize data */
2792         get_sequence_effect(seq);
2793
2794         if (!(force || seq->len != v->length || !v->frameMap)) {
2795                 return;
2796         }
2797         if (!seq->seq1) { /* make coverity happy and check for (CID 598)
2798                              input strip ... */
2799                 return;
2800         }
2801
2802         /* XXX - new in 2.5x. should we use the animation system this way?
2803          * The fcurve is needed because many frames need evaluating at once - campbell */
2804         fcu= id_data_find_fcurve(&scene->id, seq, &RNA_Sequence, "speed_fader", 0);
2805
2806
2807         if (!v->frameMap || v->length != seq->len) {
2808                 if (v->frameMap) MEM_freeN(v->frameMap);
2809
2810                 v->length = seq->len;
2811
2812                 v->frameMap = MEM_callocN(sizeof(float) * v->length, 
2813                                           "speedcontrol frameMap");
2814         }
2815
2816         fallback_fac = 1.0;
2817         
2818         /* if there is no IPO, try to make retiming easy by stretching the
2819            strip */
2820         // XXX old animation system - seq
2821         if (!fcu && seq->seq1->enddisp != seq->seq1->start && seq->seq1->len != 0) {
2822                 fallback_fac = (float) seq->seq1->len / 
2823                         (float) (seq->seq1->enddisp - seq->seq1->start);
2824                 /* FIXME: this strip stretching gets screwed by stripdata
2825                    handling one layer up.
2826                    
2827                    So it currently works by enlarging, never by shrinking!
2828
2829                    (IPOs still work, if used correctly)
2830                 */
2831                 if (fallback_fac > 1.0) {
2832                         fallback_fac = 1.0;
2833                 }
2834         }
2835
2836         if ((v->flags & SEQ_SPEED_INTEGRATE) != 0) {
2837                 float cursor = 0;
2838                 float facf;
2839
2840                 v->frameMap[0] = 0;
2841                 v->lastValidFrame = 0;
2842
2843                 for (cfra = 1; cfra < v->length; cfra++) {
2844                         if(fcu) {
2845                                if((seq->flag & SEQ_IPO_FRAME_LOCKED) != 0) {
2846                                        ctime = seq->startdisp + cfra;
2847                                        div = 1.0;
2848                                } else {
2849                                        ctime= cfra;
2850                                        div= v->length / 100.0f;
2851                                        if(div==0.0) return;
2852                                }
2853                                
2854                                facf = evaluate_fcurve(fcu, ctime/div);
2855                         } else {
2856                                 facf = fallback_fac;
2857                         }
2858                         facf *= v->globalSpeed;
2859
2860                         cursor += facf;
2861
2862                         if (cursor >= v->length) {
2863                                 v->frameMap[cfra] = v->length - 1;
2864                         } else {
2865                                 v->frameMap[cfra] = cursor;
2866                                 v->lastValidFrame = cfra;
2867                         }
2868                 }
2869         } else {
2870                 float facf;
2871
2872                 v->lastValidFrame = 0;
2873                 for (cfra = 0; cfra < v->length; cfra++) {
2874
2875                         if(fcu) {
2876                                if((seq->flag & SEQ_IPO_FRAME_LOCKED) != 0) {
2877                                        ctime = seq->startdisp + cfra;
2878                                        div = 1.0;
2879                                } else {
2880                                        ctime= cfra;
2881                                        div= v->length / 100.0f;
2882                                        if(div==0.0) return;
2883                                }
2884                 
2885                                facf = evaluate_fcurve(fcu, ctime / div);
2886                                if (v->flags & SEQ_SPEED_COMPRESS_IPO_Y) {
2887                                        facf *= v->length;
2888                                }
2889                         }
2890                         
2891                         if (!fcu) {
2892                                 facf = (float) cfra * fallback_fac;
2893                         }
2894                         facf *= v->globalSpeed;
2895                         if (facf >= v->length) {
2896                                 facf = v->length - 1;
2897                         } else {
2898                                 v->lastValidFrame = cfra;
2899                         }
2900                         v->frameMap[cfra] = facf;
2901                 }
2902         }
2903 }
2904
2905 /*
2906   simply reuse do_cross_effect for blending...
2907
2908 static void do_speed_effect(Sequence * seq,int cfra,
2909                            float facf0, float facf1, int x, int y, 
2910                            struct ImBuf *ibuf1, struct ImBuf *ibuf2, 
2911                            struct ImBuf *ibuf3, struct ImBuf *out)
2912 {
2913
2914 }
2915 */
2916
2917
2918 /* **********************************************************************
2919    sequence effect factory
2920    ********************************************************************** */
2921
2922
2923 static void init_noop(struct Sequence *seq)
2924 {
2925
2926 }
2927
2928 static void load_noop(struct Sequence *seq)
2929 {
2930
2931 }
2932
2933 static void init_plugin_noop(struct Sequence *seq, const char * fname)
2934 {
2935
2936 }
2937
2938 static void free_noop(struct Sequence *seq)
2939 {
2940
2941 }
2942
2943 static int num_inputs_default()
2944 {
2945         return 2;
2946 }
2947
2948 static int early_out_noop(struct Sequence *seq,
2949                           float facf0, float facf1)
2950 {
2951         return 0;
2952 }
2953
2954 static int early_out_fade(struct Sequence *seq,
2955                           float facf0, float facf1)
2956 {
2957         if (facf0 == 0.0 && facf1 == 0.0) {
2958                 return 1;
2959         } else if (facf0 == 1.0 && facf1 == 1.0) {
2960                 return 2;
2961         }
2962         return 0;
2963 }
2964
2965 static int early_out_mul_input2(struct Sequence *seq,
2966                                 float facf0, float facf1)
2967 {
2968         if (facf0 == 0.0 && facf1 == 0.0) {
2969                 return 1;
2970         }
2971         return 0;
2972 }
2973
2974 static void store_icu_yrange_noop(struct Sequence * seq,
2975                                   short adrcode, float * ymin, float * ymax)
2976 {
2977         /* defaults are fine */
2978 }
2979
2980 static void get_default_fac_noop(struct Sequence *seq, int cfra,
2981                                  float * facf0, float * facf1)
2982 {
2983         *facf0 = *facf1 = 1.0;
2984 }
2985
2986 static void get_default_fac_fade(struct Sequence *seq, int cfra,
2987                                  float * facf0, float * facf1)
2988 {
2989         *facf0 = (float)(cfra - seq->startdisp);
2990         *facf1 = (float)(*facf0 + 0.5);
2991         *facf0 /= seq->len;
2992         *facf1 /= seq->len;
2993 }
2994
2995 static void do_overdrop_effect(struct Sequence * seq, int cfra,
2996                                float fac, float facf, 
2997                                int x, int y, struct ImBuf * ibuf1, 
2998                                struct ImBuf * ibuf2, 
2999                                struct ImBuf * ibuf3, 
3000                                struct ImBuf * out)
3001 {
3002         do_drop_effect(seq, cfra, fac, facf, x, y, 
3003                        ibuf1, ibuf2, ibuf3, out);
3004         do_alphaover_effect(seq, cfra, fac, facf, x, y, 
3005                             ibuf1, ibuf2, ibuf3, out);
3006 }
3007
3008 static struct SeqEffectHandle get_sequence_effect_impl(int seq_type)
3009 {
3010         struct SeqEffectHandle rval;
3011         int sequence_type = seq_type;
3012
3013         rval.init = init_noop;
3014         rval.init_plugin = init_plugin_noop;
3015         rval.num_inputs = num_inputs_default;
3016         rval.load = load_noop;
3017         rval.free = free_noop;
3018         rval.early_out = early_out_noop;
3019         rval.get_default_fac = get_default_fac_noop;
3020         rval.store_icu_yrange = store_icu_yrange_noop;
3021         rval.execute = NULL;
3022         rval.copy = NULL;
3023
3024         switch (sequence_type) {
3025         case SEQ_CROSS:
3026                 rval.execute = do_cross_effect;
3027                 rval.early_out = early_out_fade;
3028                 rval.get_default_fac = get_default_fac_fade;
3029                 break;
3030         case SEQ_GAMCROSS:
3031                 rval.init = init_gammacross;
3032                 rval.load = load_gammacross;
3033                 rval.free = free_gammacross;
3034                 rval.early_out = early_out_fade;
3035                 rval.get_default_fac = get_default_fac_fade;
3036                 rval.execute = do_gammacross_effect;
3037                 break;
3038         case SEQ_ADD:
3039                 rval.execute = do_add_effect;
3040                 rval.early_out = early_out_mul_input2;
3041                 break;
3042         case SEQ_SUB:
3043                 rval.execute = do_sub_effect;
3044                 rval.early_out = early_out_mul_input2;
3045                 break;
3046         case SEQ_MUL:
3047                 rval.execute = do_mul_effect;
3048                 rval.early_out = early_out_mul_input2;
3049                 break;
3050         case SEQ_ALPHAOVER:
3051                 rval.init = init_alpha_over_or_under;
3052                 rval.execute = do_alphaover_effect;
3053                 break;
3054         case SEQ_OVERDROP:
3055                 rval.execute = do_overdrop_effect;
3056                 break;
3057         case SEQ_ALPHAUNDER:
3058                 rval.init = init_alpha_over_or_under;
3059                 rval.execute = do_alphaunder_effect;
3060                 break;
3061         case SEQ_WIPE:
3062                 rval.init = init_wipe_effect;
3063                 rval.num_inputs = num_inputs_wipe;
3064                 rval.free = free_wipe_effect;
3065                 rval.copy = copy_wipe_effect;
3066                 rval.early_out = early_out_fade;
3067                 rval.get_default_fac = get_default_fac_fade;
3068                 rval.execute = do_wipe_effect;
3069                 break;
3070         case SEQ_GLOW:
3071                 rval.init = init_glow_effect;
3072                 rval.num_inputs = num_inputs_glow;
3073                 rval.free = free_glow_effect;
3074                 rval.copy = copy_glow_effect;
3075                 rval.execute = do_glow_effect;
3076                 break;
3077         case SEQ_TRANSFORM:
3078                 rval.init = init_transform_effect;
3079                 rval.num_inputs = num_inputs_transform;
3080                 rval.free = free_transform_effect;
3081                 rval.copy = copy_transform_effect;
3082                 rval.execute = do_transform_effect;
3083                 break;
3084         case SEQ_SPEED:
3085                 rval.init = init_speed_effect;
3086                 rval.num_inputs = num_inputs_speed;
3087                 rval.load = load_speed_effect;
3088                 rval.free = free_speed_effect;
3089                 rval.copy = copy_speed_effect;
3090                 rval.execute = do_cross_effect;
3091                 rval.early_out = early_out_speed;
3092                 rval.store_icu_yrange = store_icu_yrange_speed;
3093                 break;
3094         case SEQ_COLOR:
3095                 rval.init = init_solid_color;
3096                 rval.num_inputs = num_inputs_color;
3097                 rval.early_out = early_out_color;
3098