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