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