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