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