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