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