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