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