style cleanup: seqeffects
[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
64 #define INT 96
65 #define FLO 128
66
67 /* **** XXX **** */
68
69 /* Glow effect */
70 enum {
71         GlowR = 0,
72         GlowG = 1,
73         GlowB = 2,
74         GlowA = 3
75 };
76
77 static struct ImBuf *prepare_effect_imbufs(
78     SeqRenderData context,
79     struct ImBuf *ibuf1, struct ImBuf *ibuf2,
80     struct ImBuf *ibuf3){
81         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         {
93                 /* if any inputs are rectfloat, output is float too */
94
95                 out = IMB_allocImBuf((short)x, (short)y, 32, IB_rectfloat);
96         }
97         else {
98                 out = IMB_allocImBuf((short)x, (short)y, 32, IB_rect);
99         }
100         
101         if (ibuf1 && !ibuf1->rect_float && out->rect_float) {
102                 IMB_float_from_rect_simple(ibuf1);
103         }
104         if (ibuf2 && !ibuf2->rect_float && out->rect_float) {
105                 IMB_float_from_rect_simple(ibuf2);
106         }
107         if (ibuf3 && !ibuf3->rect_float && out->rect_float) {
108                 IMB_float_from_rect_simple(ibuf3);
109         }
110         
111         if (ibuf1 && !ibuf1->rect && !out->rect_float) {
112                 IMB_rect_from_float(ibuf1);
113         }
114         if (ibuf2 && !ibuf2->rect && !out->rect_float) {
115                 IMB_rect_from_float(ibuf2);
116         }
117         if (ibuf3 && !ibuf3->rect && !out->rect_float) {
118                 IMB_rect_from_float(ibuf3);
119         }
120                         
121         return out;
122 }
123
124 /* **********************************************************************
125  * PLUGINS
126  * ********************************************************************** */
127
128 static void open_plugin_seq(PluginSeq *pis, const char *seqname)
129 {
130         int (*version)(void);
131         void * (*alloc_private)(void);
132         char *cp;
133
134         /* to be sure: (is tested for) */
135         pis->doit = NULL;
136         pis->pname = NULL;
137         pis->varstr = NULL;
138         pis->cfra = NULL;
139         pis->version = 0;
140         pis->instance_private_data = NULL;
141
142         /* clear the error list */
143         BLI_dynlib_get_error_as_string(NULL);
144
145         /* if (pis->handle) BLI_dynlib_close(pis->handle); */
146         /* pis->handle= 0; */
147
148         /* open the needed object */
149         pis->handle = BLI_dynlib_open(pis->name);
150         if (test_dlerr(pis->name, pis->name)) return;
151
152         if (pis->handle != NULL) {
153                 /* find the address of the version function */
154                 version = (int (*)(void))BLI_dynlib_find_symbol(pis->handle, "plugin_seq_getversion");
155                 if (test_dlerr(pis->name, "plugin_seq_getversion")) return;
156
157                 if (version != NULL) {
158                         pis->version = version();
159                         if (pis->version >= 2 && pis->version <= 6) {
160                                 int (*info_func)(PluginInfo *);
161                                 PluginInfo *info = (PluginInfo *) MEM_mallocN(sizeof(PluginInfo), "plugin_info");
162
163                                 info_func = (int (*)(PluginInfo *))BLI_dynlib_find_symbol(pis->handle, "plugin_getinfo");
164
165                                 if (info_func == NULL) error("No info func");
166                                 else {
167                                         info_func(info);
168
169                                         pis->pname = info->name;
170                                         pis->vars = info->nvars;
171                                         pis->cfra = info->cfra;
172
173                                         pis->varstr = info->varstr;
174
175                                         pis->doit = (void (*)(void))info->seq_doit;
176                                         if (info->init)
177                                                 info->init();
178                                 }
179                                 MEM_freeN(info);
180
181                                 cp = BLI_dynlib_find_symbol(pis->handle, "seqname");
182                                 if (cp) BLI_strncpy(cp, seqname, SEQ_NAME_MAXSTR);
183                         }
184                         else {
185                                 printf("Plugin returned unrecognized version number\n");
186                                 return;
187                         }
188                 }
189                 alloc_private = (void * (*)(void))BLI_dynlib_find_symbol(
190                     pis->handle, "plugin_seq_alloc_private_data");
191                 if (alloc_private) {
192                         pis->instance_private_data = alloc_private();
193                 }
194                 
195                 pis->current_private_data = (void **)
196                         BLI_dynlib_find_symbol(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         struct ImBuf *out = prepare_effect_imbufs(context, ibuf1, ibuf2, ibuf3);
1243
1244         if (out->rect_float) {
1245                 do_add_effect_float(
1246                         facf0, facf1, context.rectx, context.recty,
1247                         ibuf1->rect_float, ibuf2->rect_float,
1248                         out->rect_float);
1249         }
1250         else {
1251                 do_add_effect_byte(
1252                         facf0, facf1, context.rectx, context.recty,
1253                         (unsigned char *) ibuf1->rect, (unsigned char *) ibuf2->rect,
1254                         (unsigned char *) out->rect);
1255         }
1256         return out;
1257 }
1258
1259
1260 /* **********************************************************************
1261  * SUB
1262  * ********************************************************************** */
1263
1264 static void do_sub_effect_byte(float facf0, float facf1, 
1265                                int x, int y,
1266                                char *rect1, char *rect2, char *out)
1267 {
1268         int col, xo, fac1, fac3;
1269         char *rt1, *rt2, *rt;
1270
1271         xo = x;
1272         rt1 = (char *)rect1;
1273         rt2 = (char *)rect2;
1274         rt = (char *)out;
1275
1276         fac1 = (int)(256.0f * facf0);
1277         fac3 = (int)(256.0f * facf1);
1278
1279         while (y--) {
1280
1281                 x = xo;
1282                 while (x--) {
1283
1284                         col = rt1[0] - ((fac1 * rt2[0]) >> 8);
1285                         if (col < 0) rt[0] = 0; else rt[0] = col;
1286                         col = rt1[1] - ((fac1 * rt2[1]) >> 8);
1287                         if (col < 0) rt[1] = 0; else rt[1] = col;
1288                         col = rt1[2] - ((fac1 * rt2[2]) >> 8);
1289                         if (col < 0) rt[2] = 0; else rt[2] = col;
1290                         col = rt1[3] - ((fac1 * rt2[3]) >> 8);
1291                         if (col < 0) rt[3] = 0; else rt[3] = col;
1292
1293                         rt1 += 4; rt2 += 4; rt += 4;
1294                 }
1295
1296                 if (y == 0) break;
1297                 y--;
1298
1299                 x = xo;
1300                 while (x--) {
1301
1302                         col = rt1[0] - ((fac3 * rt2[0]) >> 8);
1303                         if (col < 0) rt[0] = 0; else rt[0] = col;
1304                         col = rt1[1] - ((fac3 * rt2[1]) >> 8);
1305                         if (col < 0) rt[1] = 0; else rt[1] = col;
1306                         col = rt1[2] - ((fac3 * rt2[2]) >> 8);
1307                         if (col < 0) rt[2] = 0; else rt[2] = col;
1308                         col = rt1[3] - ((fac3 * rt2[3]) >> 8);
1309                         if (col < 0) rt[3] = 0; else rt[3] = col;
1310
1311                         rt1 += 4; rt2 += 4; rt += 4;
1312                 }
1313         }
1314 }
1315
1316 static void do_sub_effect_float(float facf0, float facf1, int x, int y, 
1317                                 float *rect1, float *rect2,
1318                                 float *out)
1319 {
1320         int xo;
1321         float fac1, fac3;
1322         float *rt1, *rt2, *rt;
1323
1324         xo = x;
1325         rt1 = rect1;
1326         rt2 = rect2;
1327         rt = out;
1328
1329         fac1 = facf0;
1330         fac3 = facf1;
1331
1332         while (y--) {
1333
1334                 x = xo * 4;
1335                 while (x--) {
1336                         *rt = *rt1 - fac1 * (*rt2);
1337
1338                         rt1++; rt2++; rt++;
1339                 }
1340
1341                 if (y == 0) break;
1342                 y--;
1343
1344                 x = xo * 4;
1345                 while (x--) {
1346                         *rt = *rt1 - fac3 * (*rt2);
1347
1348                         rt1++; rt2++; rt++;
1349                 }
1350         }
1351 }
1352
1353 static struct ImBuf *do_sub_effect(
1354     SeqRenderData context, Sequence *UNUSED(seq), float UNUSED(cfra),
1355     float facf0, float facf1,
1356     struct ImBuf *ibuf1, struct ImBuf *ibuf2,
1357     struct ImBuf *ibuf3){
1358         struct ImBuf *out = prepare_effect_imbufs(context, ibuf1, ibuf2, ibuf3);
1359
1360         if (out->rect_float) {
1361                 do_sub_effect_float(
1362                     facf0, facf1, context.rectx, context.recty,
1363                     ibuf1->rect_float, ibuf2->rect_float,
1364                     out->rect_float);
1365         }
1366         else {
1367                 do_sub_effect_byte(
1368                     facf0, facf1, context.rectx, context.recty,
1369                     (char *) ibuf1->rect, (char *) ibuf2->rect,
1370                     (char *) out->rect);
1371         }
1372         return out;
1373 }
1374
1375 /* **********************************************************************
1376  * DROP
1377  * ********************************************************************** */
1378
1379 /* Must be > 0 or add precopy, etc to the function */
1380 #define XOFF    8
1381 #define YOFF    8
1382
1383 static void do_drop_effect_byte(float facf0, float facf1, int x, int y, 
1384                                 char *rect2i, char *rect1i,
1385                                 char *outi)
1386 {
1387         int height, width, temp, fac, fac1, fac2;
1388         char *rt1, *rt2, *out;
1389         int field = 1;
1390
1391         width = x;
1392         height = y;
1393
1394         fac1 = (int)(70.0f * facf0);
1395         fac2 = (int)(70.0f * facf1);
1396
1397         rt2 = (char *) (rect2i + YOFF * width);
1398         rt1 = (char *) rect1i;
1399         out = (char *) outi;
1400         for (y = 0; y < height - YOFF; y++) {
1401                 if (field) fac = fac1;
1402                 else fac = fac2;
1403                 field = !field;
1404
1405                 memcpy(out, rt1, sizeof(int) * XOFF);
1406                 rt1 += XOFF * 4;
1407                 out += XOFF * 4;
1408
1409                 for (x = XOFF; x < width; x++) {
1410                         temp = ((fac * rt2[3]) >> 8);
1411
1412                         *(out++) = MAX2(0, *rt1 - temp); rt1++;
1413                         *(out++) = MAX2(0, *rt1 - temp); rt1++;
1414                         *(out++) = MAX2(0, *rt1 - temp); rt1++;
1415                         *(out++) = MAX2(0, *rt1 - temp); rt1++;
1416                         rt2 += 4;
1417                 }
1418                 rt2 += XOFF * 4;
1419         }
1420         memcpy(out, rt1, sizeof(int) * YOFF * width);
1421 }
1422
1423 static void do_drop_effect_float(float facf0, float facf1, int x, int y, 
1424                                  float *rect2i, float *rect1i,
1425                                  float *outi)
1426 {
1427         int height, width;
1428         float temp, fac, fac1, fac2;
1429         float *rt1, *rt2, *out;
1430         int field = 1;
1431
1432         width = x;
1433         height = y;
1434
1435         fac1 = 70.0f * facf0;
1436         fac2 = 70.0f * facf1;
1437
1438         rt2 =  (rect2i + YOFF * width);
1439         rt1 =  rect1i;
1440         out =  outi;
1441         for (y = 0; y < height - YOFF; y++) {
1442                 if (field) fac = fac1;
1443                 else fac = fac2;
1444                 field = !field;
1445
1446                 memcpy(out, rt1, 4 * sizeof(float) * XOFF);
1447                 rt1 += XOFF * 4;
1448                 out += XOFF * 4;
1449
1450                 for (x = XOFF; x < width; x++) {
1451                         temp = fac * rt2[3];
1452
1453                         *(out++) = MAX2(0.0f, *rt1 - temp); rt1++;
1454                         *(out++) = MAX2(0.0f, *rt1 - temp); rt1++;
1455                         *(out++) = MAX2(0.0f, *rt1 - temp); rt1++;
1456                         *(out++) = MAX2(0.0f, *rt1 - temp); rt1++;
1457                         rt2 += 4;
1458                 }
1459                 rt2 += XOFF * 4;
1460         }
1461         memcpy(out, rt1, 4 * sizeof(float) * YOFF * width);
1462 }
1463
1464 /* **********************************************************************
1465  * MUL
1466  * ********************************************************************** */
1467
1468 static void do_mul_effect_byte(float facf0, float facf1, int x, int y, 
1469                                unsigned char *rect1, unsigned char *rect2,
1470                                unsigned char *out)
1471 {
1472         int xo, fac1, fac3;
1473         char *rt1, *rt2, *rt;
1474
1475         xo = x;
1476         rt1 = (char *)rect1;
1477         rt2 = (char *)rect2;
1478         rt = (char *)out;
1479
1480         fac1 = (int)(256.0f * facf0);
1481         fac3 = (int)(256.0f * facf1);
1482
1483         /* formula:
1484          *              fac*(a*b) + (1-fac)*a  => fac*a*(b-1)+axaux= c*px + py*s ;//+centx
1485          *              yaux= -s*px + c*py;//+centy
1486          */
1487
1488         while (y--) {
1489
1490                 x = xo;
1491                 while (x--) {
1492
1493                         rt[0] = rt1[0] + ((fac1 * rt1[0] * (rt2[0] - 256)) >> 16);
1494                         rt[1] = rt1[1] + ((fac1 * rt1[1] * (rt2[1] - 256)) >> 16);
1495                         rt[2] = rt1[2] + ((fac1 * rt1[2] * (rt2[2] - 256)) >> 16);
1496                         rt[3] = rt1[3] + ((fac1 * rt1[3] * (rt2[3] - 256)) >> 16);
1497
1498                         rt1 += 4; rt2 += 4; rt += 4;
1499                 }
1500
1501                 if (y == 0) break;
1502                 y--;
1503
1504                 x = xo;
1505                 while (x--) {
1506
1507                         rt[0] = rt1[0] + ((fac3 * rt1[0] * (rt2[0] - 256)) >> 16);
1508                         rt[1] = rt1[1] + ((fac3 * rt1[1] * (rt2[1] - 256)) >> 16);
1509                         rt[2] = rt1[2] + ((fac3 * rt1[2] * (rt2[2] - 256)) >> 16);
1510                         rt[3] = rt1[3] + ((fac3 * rt1[3] * (rt2[3] - 256)) >> 16);
1511
1512                         rt1 += 4; rt2 += 4; rt += 4;
1513                 }
1514         }
1515 }
1516
1517 static void do_mul_effect_float(float facf0, float facf1, int x, int y, 
1518                                 float *rect1, float *rect2,
1519                                 float *out)
1520 {
1521         int xo;
1522         float fac1, fac3;
1523         float *rt1, *rt2, *rt;
1524
1525         xo = x;
1526         rt1 = rect1;
1527         rt2 = rect2;
1528         rt = out;
1529
1530         fac1 = facf0;
1531         fac3 = facf1;
1532
1533         /* formula:
1534          *              fac*(a*b) + (1-fac)*a  => fac*a*(b-1)+a
1535          */
1536
1537         while (y--) {
1538
1539                 x = xo;
1540                 while (x--) {
1541
1542                         rt[0] = rt1[0] + fac1 * rt1[0] * (rt2[0] - 1.0f);
1543                         rt[1] = rt1[1] + fac1 * rt1[1] * (rt2[1] - 1.0f);
1544                         rt[2] = rt1[2] + fac1 * rt1[2] * (rt2[2] - 1.0f);
1545                         rt[3] = rt1[3] + fac1 * rt1[3] * (rt2[3] - 1.0f);
1546
1547                         rt1 += 4; rt2 += 4; rt += 4;
1548                 }
1549
1550                 if (y == 0) break;
1551                 y--;
1552
1553                 x = xo;
1554                 while (x--) {
1555
1556                         rt[0] = rt1[0] + fac3 * rt1[0] * (rt2[0] - 1.0f);
1557                         rt[1] = rt1[1] + fac3 * rt1[1] * (rt2[1] - 1.0f);
1558                         rt[2] = rt1[2] + fac3 * rt1[2] * (rt2[2] - 1.0f);
1559                         rt[3] = rt1[3] + fac3 * rt1[3] * (rt2[3] - 1.0f);
1560
1561                         rt1 += 4; rt2 += 4; rt += 4;
1562                 }
1563         }
1564 }
1565
1566 static struct ImBuf *do_mul_effect(
1567         SeqRenderData context, Sequence *UNUSED(seq), float UNUSED(cfra),
1568         float facf0, float facf1,
1569         struct ImBuf *ibuf1, struct ImBuf *ibuf2,
1570         struct ImBuf *ibuf3)
1571 {
1572         struct ImBuf *out = prepare_effect_imbufs(context, ibuf1, ibuf2, ibuf3);
1573
1574         if (out->rect_float) {
1575                 do_mul_effect_float(
1576                         facf0, facf1, context.rectx, context.recty,
1577                         ibuf1->rect_float, ibuf2->rect_float,
1578                         out->rect_float);
1579         }
1580         else {
1581                 do_mul_effect_byte(
1582                         facf0, facf1, context.rectx, context.recty,
1583                         (unsigned char *) ibuf1->rect, (unsigned char *) ibuf2->rect,
1584                         (unsigned char *) out->rect);
1585         }
1586
1587         return out;
1588 }
1589
1590 /* **********************************************************************
1591  * WIPE
1592  * ********************************************************************** */
1593
1594 typedef struct WipeZone {
1595         float angle;
1596         int flip;
1597         int xo, yo;
1598         int width;
1599         float pythangle;
1600 } WipeZone;
1601
1602 static void precalc_wipe_zone(WipeZone *wipezone, WipeVars *wipe, int xo, int yo)
1603 {
1604         wipezone->flip = (wipe->angle < 0);
1605         wipezone->angle = tanf(DEG2RADF(fabsf(wipe->angle)));
1606         wipezone->xo = xo;
1607         wipezone->yo = yo;
1608         wipezone->width = (int)(wipe->edgeWidth * ((xo + yo) / 2.0f));
1609         wipezone->pythangle = 1.0f / sqrtf(wipezone->angle * wipezone->angle + 1.0f);
1610 }
1611
1612 // This function calculates the blur band for the wipe effects
1613 static float in_band(float width, float dist, int side, int dir)
1614 {
1615         float alpha;
1616
1617         if (width == 0)
1618                 return (float)side;
1619
1620         if (width < dist)
1621                 return (float)side;
1622
1623         if (side == 1)
1624                 alpha = (dist + 0.5f * width) / (width);
1625         else
1626                 alpha = (0.5f * width - dist) / (width);
1627
1628         if (dir == 0)
1629                 alpha = 1 - alpha;
1630
1631         return alpha;
1632 }
1633
1634 static float check_zone(WipeZone *wipezone, int x, int y,
1635                         Sequence *seq, float facf0)
1636 {
1637         float posx, posy, hyp, hyp2, angle, hwidth, b1, b2, b3, pointdist;
1638         /* some future stuff */
1639         // float hyp3, hyp4, b4, b5
1640         float temp1, temp2, temp3, temp4; //some placeholder variables
1641         int xo = wipezone->xo;
1642         int yo = wipezone->yo;
1643         float halfx = xo * 0.5f;
1644         float halfy = yo * 0.5f;
1645         float widthf, output = 0;
1646         WipeVars *wipe = (WipeVars *)seq->effectdata;
1647         int width;
1648
1649         if (wipezone->flip) x = xo - x;
1650         angle = wipezone->angle;
1651
1652         if (wipe->forward) {
1653                 posx = facf0 * xo;
1654                 posy = facf0 * yo;
1655         }
1656         else {
1657                 posx = xo - facf0 * xo;
1658                 posy = yo - facf0 * yo;
1659         }
1660
1661         switch (wipe->wipetype) {
1662                 case DO_SINGLE_WIPE:
1663                         width = wipezone->width;
1664
1665                         if (angle == 0.0f) {
1666                                 b1 = posy;
1667                                 b2 = y;
1668                                 hyp = fabs(y - posy);
1669                         }
1670                         else {
1671                                 b1 = posy - (-angle) * posx;
1672                                 b2 = y - (-angle) * x;
1673                                 hyp = fabsf(angle * x + y + (-posy - angle * posx)) * wipezone->pythangle;
1674                         }
1675
1676                         if (angle < 0) {
1677                                 temp1 = b1;
1678                                 b1 = b2;
1679                                 b2 = temp1;
1680                         }
1681
1682                         if (wipe->forward) {
1683                                 if (b1 < b2)
1684                                         output = in_band(width, hyp, 1, 1);
1685                                 else
1686                                         output = in_band(width, hyp, 0, 1);
1687                         }
1688                         else {
1689                                 if (b1 < b2)
1690                                         output = in_band(width, hyp, 0, 1);
1691                                 else
1692                                         output = in_band(width, hyp, 1, 1);
1693                         }
1694                         break;
1695
1696                 case DO_DOUBLE_WIPE:
1697                         if (!wipe->forward)
1698                                 facf0 = 1.0f - facf0;  // Go the other direction
1699
1700                         width = wipezone->width;  // calculate the blur width
1701                         hwidth = width * 0.5f;
1702                         if (angle == 0) {
1703                                 b1 = posy * 0.5f;
1704                                 b3 = yo - posy * 0.5f;
1705                                 b2 = y;
1706
1707                                 hyp = abs(y - posy * 0.5f);
1708                                 hyp2 = abs(y - (yo - posy * 0.5f));
1709                         }
1710                         else {
1711                                 b1 = posy * 0.5f - (-angle) * posx * 0.5f;
1712                                 b3 = (yo - posy * 0.5f) - (-angle) * (xo - posx * 0.5f);
1713                                 b2 = y - (-angle) * x;
1714
1715                                 hyp = fabsf(angle * x + y + (-posy * 0.5f - angle * posx * 0.5f)) * wipezone->pythangle;
1716                                 hyp2 = fabsf(angle * x + y + (-(yo - posy * 0.5f) - angle * (xo - posx * 0.5f))) * wipezone->pythangle;
1717                         }
1718
1719                         hwidth = minf(hwidth, fabsf(b3 - b1) / 2.0f);
1720
1721                         if (b2 < b1 && b2 < b3) {
1722                                 output = in_band(hwidth, hyp, 0, 1);
1723                         }
1724                         else if (b2 > b1 && b2 > b3) {
1725                                 output = in_band(hwidth, hyp2, 0, 1);
1726                         }
1727                         else {
1728                                 if (hyp < hwidth && hyp2 > hwidth)
1729                                         output = in_band(hwidth, hyp, 1, 1);
1730                                 else if (hyp > hwidth && hyp2 < hwidth)
1731                                         output = in_band(hwidth, hyp2, 1, 1);
1732                                 else
1733                                         output = in_band(hwidth, hyp2, 1, 1) * in_band(hwidth, hyp, 1, 1);
1734                         }
1735                         if (!wipe->forward) output = 1 - output;
1736                         break;
1737                 case DO_CLOCK_WIPE:
1738                         /*
1739                          *  temp1: angle of effect center in rads
1740                          *  temp2: angle of line through (halfx, halfy) and (x, y) in rads
1741                          *  temp3: angle of low side of blur
1742                          *  temp4: angle of high side of blur
1743                          */
1744                         output = 1.0f - facf0;
1745                         widthf = wipe->edgeWidth * 2.0f * (float)M_PI;
1746                         temp1 = 2.0f * (float)M_PI * facf0;
1747
1748                         if (wipe->forward) {
1749                                 temp1 = 2.0f * (float)M_PI - temp1;
1750                         }
1751
1752                         x = x - halfx;
1753                         y = y - halfy;
1754
1755                         temp2 = asin(abs(y) / sqrt(x * x + y * y));
1756                         if (x <= 0 && y >= 0) temp2 = (float)M_PI - temp2;
1757                         else if (x <= 0 && y <= 0) temp2 += (float)M_PI;
1758                         else if (x >= 0 && y <= 0) temp2 = 2.0f * (float)M_PI - temp2;
1759
1760                         if (wipe->forward) {
1761                                 temp3 = temp1 - (widthf * 0.5f) * facf0;
1762                                 temp4 = temp1 + (widthf * 0.5f) * (1 - facf0);
1763                         }
1764                         else {
1765                                 temp3 = temp1 - (widthf * 0.5f) * (1 - facf0);
1766                                 temp4 = temp1 + (widthf * 0.5f) * facf0;
1767                         }
1768                         if (temp3 < 0) temp3 = 0;
1769                         if (temp4 > 2.0f * (float)M_PI) temp4 = 2.0f * (float)M_PI;
1770
1771
1772                         if (temp2 < temp3) output = 0;
1773                         else if (temp2 > temp4) output = 1;
1774                         else output = (temp2 - temp3) / (temp4 - temp3);
1775                         if (x == 0 && y == 0) output = 1;
1776                         if (output != output) output = 1;
1777                         if (wipe->forward) output = 1 - output;
1778                         break;
1779                         /* BOX WIPE IS NOT WORKING YET */
1780                         /* case DO_CROSS_WIPE: */
1781                         /* BOX WIPE IS NOT WORKING YET */
1782 #if 0
1783                 case DO_BOX_WIPE: 
1784                         if (invert) facf0 = 1 - facf0;
1785
1786                         width = (int)(wipe->edgeWidth * ((xo + yo) / 2.0));
1787                         hwidth = (float)width / 2.0;
1788                         if (angle == 0) angle = 0.000001;
1789                         b1 = posy / 2 - (-angle) * posx / 2;
1790                         b3 = (yo - posy / 2) - (-angle) * (xo - posx / 2);
1791                         b2 = y - (-angle) * x;
1792
1793                         hyp = abs(angle * x + y + (-posy / 2 - angle * posx / 2)) * wipezone->pythangle;
1794                         hyp2 = abs(angle * x + y + (-(yo - posy / 2) - angle * (xo - posx / 2))) * wipezone->pythangle;
1795
1796                         temp1 = xo * (1 - facf0 / 2) - xo * facf0 / 2;
1797                         temp2 = yo * (1 - facf0 / 2) - yo * facf0 / 2;
1798                         pointdist = sqrt(temp1 * temp1 + temp2 * temp2);
1799
1800                         if (b2 < b1 && b2 < b3) {
1801                                 if (hwidth < pointdist)
1802                                         output = in_band(wipezone, hwidth, hyp, facf0, 0, 1);
1803                         }
1804                         else if (b2 > b1 && b2 > b3) {
1805                                 if (hwidth < pointdist)
1806                                         output = in_band(wipezone, hwidth, hyp2, facf0, 0, 1);
1807                         }
1808                         else {
1809                                 if (hyp < hwidth && hyp2 > hwidth)
1810                                         output = in_band(wipezone, hwidth, hyp, facf0, 1, 1);
1811                                 else if (hyp > hwidth && hyp2 < hwidth)
1812                                         output = in_band(wipezone, hwidth, hyp2, facf0, 1, 1);
1813                                 else
1814                                         output = in_band(wipezone, hwidth, hyp2, facf0, 1, 1) * in_band(wipezone, hwidth, hyp, facf0, 1, 1);
1815                         }
1816
1817                         if (invert) facf0 = 1 - facf0;
1818                         angle = -1 / angle;
1819                         b1 = posy / 2 - (-angle) * posx / 2;
1820                         b3 = (yo - posy / 2) - (-angle) * (xo - posx / 2);
1821                         b2 = y - (-angle) * x;
1822
1823                         hyp = abs(angle * x + y + (-posy / 2 - angle * posx / 2)) * wipezone->pythangle;
1824                         hyp2 = abs(angle * x + y + (-(yo - posy / 2) - angle * (xo - posx / 2))) * wipezone->pythangle;
1825
1826                         if (b2 < b1 && b2 < b3) {
1827                                 if (hwidth < pointdist)
1828                                         output *= in_band(wipezone, hwidth, hyp, facf0, 0, 1);
1829                         }
1830                         else if (b2 > b1 && b2 > b3) {
1831                                 if (hwidth < pointdist)
1832                                         output *= in_band(wipezone, hwidth, hyp2, facf0, 0, 1);
1833                         }
1834                         else {
1835                                 if (hyp < hwidth && hyp2 > hwidth)
1836                                         output *= in_band(wipezone, hwidth, hyp, facf0, 1, 1);
1837                                 else if (hyp > hwidth && hyp2 < hwidth)
1838                                         output *= in_band(wipezone, hwidth, hyp2, facf0, 1, 1);
1839                                 else
1840                                         output *= in_band(wipezone, hwidth, hyp2, facf0, 1, 1) * in_band(wipezone, hwidth, hyp, facf0, 1, 1);
1841                         }
1842
1843                         break;
1844 #endif
1845                 case DO_IRIS_WIPE:
1846                         if (xo > yo) yo = xo;
1847                         else xo = yo;
1848
1849                         if (!wipe->forward) facf0 = 1 - facf0;
1850
1851                         width = wipezone->width;
1852                         hwidth = width * 0.5f;
1853
1854                         temp1 = (halfx - (halfx) * facf0);
1855                         pointdist = sqrt(temp1 * temp1 + temp1 * temp1);
1856
1857                         temp2 = sqrt((halfx - x) * (halfx - x) + (halfy - y) * (halfy - y));
1858                         if (temp2 > pointdist) output = in_band(hwidth, fabs(temp2 - pointdist), 0, 1);
1859                         else output = in_band(hwidth, fabs(temp2 - pointdist), 1, 1);
1860
1861                         if (!wipe->forward) output = 1 - output;
1862                         
1863                         break;
1864         }
1865         if (output < 0) output = 0;
1866         else if (output > 1) output = 1;
1867         return output;
1868 }
1869
1870 static void init_wipe_effect(Sequence *seq)
1871 {
1872         if (seq->effectdata) MEM_freeN(seq->effectdata);
1873         seq->effectdata = MEM_callocN(sizeof(struct WipeVars), "wipevars");
1874 }
1875
1876 static int num_inputs_wipe(void)
1877 {
1878         return 1;
1879 }
1880
1881 static void free_wipe_effect(Sequence *seq)
1882 {
1883         if (seq->effectdata) MEM_freeN(seq->effectdata);
1884         seq->effectdata = NULL;
1885 }
1886
1887 static void copy_wipe_effect(Sequence *dst, Sequence *src)
1888 {
1889         dst->effectdata = MEM_dupallocN(src->effectdata);
1890 }
1891
1892 static void do_wipe_effect_byte(Sequence *seq, float facf0, float UNUSED(facf1), 
1893                                 int x, int y,
1894                                 unsigned char *rect1,
1895                                 unsigned char *rect2, unsigned char *out)
1896 {
1897         WipeZone wipezone;
1898         WipeVars *wipe = (WipeVars *)seq->effectdata;
1899         int xo, yo;
1900         char *rt1, *rt2, *rt;
1901
1902         precalc_wipe_zone(&wipezone, wipe, x, y);
1903
1904         rt1 = (char *)rect1;
1905         rt2 = (char *)rect2;
1906         rt = (char *)out;
1907
1908         xo = x;
1909         yo = y;
1910         for (y = 0; y < yo; y++) {
1911                 for (x = 0; x < xo; x++) {
1912                         float check = check_zone(&wipezone, x, y, seq, facf0);
1913                         if (check) {
1914                                 if (rt1) {
1915                                         rt[0] = (int)(rt1[0] * check) + (int)(rt2[0] * (1 - check));
1916                                         rt[1] = (int)(rt1[1] * check) + (int)(rt2[1] * (1 - check));
1917                                         rt[2] = (int)(rt1[2] * check) + (int)(rt2[2] * (1 - check));
1918                                         rt[3] = (int)(rt1[3] * check) + (int)(rt2[3] * (1 - check));
1919                                 }
1920                                 else {
1921                                         rt[0] = 0;
1922                                         rt[1] = 0;
1923                                         rt[2] = 0;
1924                                         rt[3] = 255;
1925                                 }
1926                         }
1927                         else {
1928                                 if (rt2) {
1929                                         rt[0] = rt2[0];
1930                                         rt[1] = rt2[1];
1931                                         rt[2] = rt2[2];
1932                                         rt[3] = rt2[3];
1933                                 }
1934                                 else {
1935                                         rt[0] = 0;
1936                                         rt[1] = 0;
1937                                         rt[2] = 0;
1938                                         rt[3] = 255;
1939                                 }
1940                         }
1941
1942                         rt += 4;
1943                         if (rt1 != NULL) {
1944                                 rt1 += 4;
1945                         }
1946                         if (rt2 != NULL) {
1947                                 rt2 += 4;
1948                         }
1949                 }
1950         }
1951 }
1952
1953 static void do_wipe_effect_float(Sequence *seq, float facf0, float UNUSED(facf1), 
1954                                  int x, int y,
1955                                  float *rect1,
1956                                  float *rect2, float *out)
1957 {
1958         WipeZone wipezone;
1959         WipeVars *wipe = (WipeVars *)seq->effectdata;
1960         int xo, yo;
1961         float *rt1, *rt2, *rt;
1962
1963         precalc_wipe_zone(&wipezone, wipe, x, y);
1964
1965         rt1 = rect1;
1966         rt2 = rect2;
1967         rt = out;
1968
1969         xo = x;
1970         yo = y;
1971         for (y = 0; y < yo; y++) {
1972                 for (x = 0; x < xo; x++) {
1973                         float check = check_zone(&wipezone, x, y, seq, facf0);
1974                         if (check) {
1975                                 if (rt1) {
1976                                         rt[0] = rt1[0] * check + rt2[0] * (1 - check);
1977                                         rt[1] = rt1[1] * check + rt2[1] * (1 - check);
1978                                         rt[2] = rt1[2] * check + rt2[2] * (1 - check);
1979                                         rt[3] = rt1[3] * check + rt2[3] * (1 - check);
1980                                 }
1981                                 else {
1982                                         rt[0] = 0;
1983                                         rt[1] = 0;
1984                                         rt[2] = 0;
1985                                         rt[3] = 1.0;
1986                                 }
1987                         }
1988                         else {
1989                                 if (rt2) {
1990                                         rt[0] = rt2[0];
1991                                         rt[1] = rt2[1];
1992                                         rt[2] = rt2[2];
1993                                         rt[3] = rt2[3];
1994                                 }
1995                                 else {
1996                                         rt[0] = 0;
1997                                         rt[1] = 0;
1998                                         rt[2] = 0;
1999                                         rt[3] = 1.0;
2000                                 }
2001                         }
2002
2003                         rt += 4;
2004                         if (rt1 != NULL) {
2005                                 rt1 += 4;
2006                         }
2007                         if (rt2 != NULL) {
2008                                 rt2 += 4;
2009                         }
2010                 }
2011         }
2012 }
2013
2014 static struct ImBuf *do_wipe_effect(
2015     SeqRenderData context, Sequence *seq, float UNUSED(cfra),
2016     float facf0, float facf1,
2017     struct ImBuf *ibuf1, struct ImBuf *ibuf2,
2018     struct ImBuf *ibuf3){
2019         struct ImBuf *out = prepare_effect_imbufs(context, ibuf1, ibuf2, ibuf3);
2020
2021         if (out->rect_float) {
2022                 do_wipe_effect_float(seq,
2023                                      facf0, facf1, context.rectx, context.recty,
2024                                      ibuf1->rect_float, ibuf2->rect_float,
2025                                      out->rect_float);
2026         }
2027         else {
2028                 do_wipe_effect_byte(seq,
2029                                     facf0, facf1, context.rectx, context.recty,
2030                                     (unsigned char *) ibuf1->rect, (unsigned char *) ibuf2->rect,
2031                                     (unsigned char *) out->rect);
2032         }
2033
2034         return out;
2035 }
2036 /* **********************************************************************
2037  * TRANSFORM
2038  * ********************************************************************** */
2039 static void init_transform_effect(Sequence *seq)
2040 {
2041         TransformVars *transform;
2042
2043         if (seq->effectdata) MEM_freeN(seq->effectdata);
2044         seq->effectdata = MEM_callocN(sizeof(struct TransformVars), "transformvars");
2045
2046         transform = (TransformVars *)seq->effectdata;
2047
2048         transform->ScalexIni = 1.0f;
2049         transform->ScaleyIni = 1.0f;
2050
2051         transform->xIni = 0.0f;
2052         transform->yIni = 0.0f;
2053
2054         transform->rotIni = 0.0f;
2055         
2056         transform->interpolation = 1;
2057         transform->percent = 1;
2058         transform->uniform_scale = 0;
2059 }
2060
2061 static int num_inputs_transform(void)
2062 {
2063         return 1;
2064 }
2065
2066 static void free_transform_effect(Sequence *seq)
2067 {
2068         if (seq->effectdata) MEM_freeN(seq->effectdata);
2069         seq->effectdata = NULL;
2070 }
2071
2072 static void copy_transform_effect(Sequence *dst, Sequence *src)
2073 {
2074         dst->effectdata = MEM_dupallocN(src->effectdata);
2075 }
2076
2077 static void transform_image(int x, int y, struct ImBuf *ibuf1, struct ImBuf *out, 
2078                             float scale_x, float scale_y, float translate_x, float translate_y,
2079                             float rotate, int interpolation)
2080 {
2081         int xo, yo, xi, yi;
2082         float xt, yt, xr, yr;
2083         float s, c;
2084
2085         xo = x;
2086         yo = y;
2087         
2088         // Rotate
2089         s = sin(rotate);
2090         c = cos(rotate);
2091
2092         for (yi = 0; yi < yo; yi++) {
2093                 for (xi = 0; xi < xo; xi++) {
2094
2095                         //translate point
2096                         xt = xi - translate_x;
2097                         yt = yi - translate_y;
2098
2099                         //rotate point with center ref
2100                         xr =  c * xt + s * yt;
2101                         yr = -s * xt + c * yt;
2102
2103                         //scale point with center ref
2104                         xt = xr / scale_x;
2105                         yt = yr / scale_y;
2106
2107                         //undo reference center point 
2108                         xt += (xo / 2.0f);
2109                         yt += (yo / 2.0f);
2110
2111                         //interpolate
2112                         switch (interpolation) {
2113                                 case 0:
2114                                         neareast_interpolation(ibuf1, out, xt, yt, xi, yi);
2115                                         break;
2116                                 case 1:
2117                                         bilinear_interpolation(ibuf1, out, xt, yt, xi, yi);
2118                                         break;
2119                                 case 2:
2120                                         bicubic_interpolation(ibuf1, out, xt, yt, xi, yi);
2121                                         break;
2122                         }
2123                 }
2124         }
2125 }
2126
2127 static void do_transform(Scene *scene, Sequence *seq, float UNUSED(facf0), int x, int y, 
2128                          struct ImBuf *ibuf1, struct ImBuf *out)
2129 {
2130         TransformVars *transform = (TransformVars *)seq->effectdata;
2131         float scale_x, scale_y, translate_x, translate_y, rotate_radians;
2132         
2133         // Scale
2134         if (transform->uniform_scale) {
2135                 scale_x = scale_y = transform->ScalexIni;
2136         }
2137         else {
2138                 scale_x = transform->ScalexIni;
2139                 scale_y = transform->ScaleyIni;
2140         }
2141
2142         // Translate
2143         if (!transform->percent) {
2144                 float rd_s = (scene->r.size / 100.0f);
2145
2146                 translate_x = transform->xIni * rd_s + (x / 2.0f);
2147                 translate_y = transform->yIni * rd_s + (y / 2.0f);
2148         }
2149         else {
2150                 translate_x = x * (transform->xIni / 100.0f) + (x / 2.0f);
2151                 translate_y = y * (transform->yIni / 100.0f) + (y / 2.0f);
2152         }
2153         
2154         // Rotate
2155         rotate_radians = DEG2RADF(transform->rotIni);
2156
2157         transform_image(x, y, ibuf1, out, scale_x, scale_y, translate_x, translate_y, rotate_radians, transform->interpolation);
2158 }
2159
2160
2161 static struct ImBuf *do_transform_effect(
2162     SeqRenderData context, Sequence *seq, float UNUSED(cfra),
2163     float facf0, float UNUSED(facf1),
2164     struct ImBuf *ibuf1, struct ImBuf *ibuf2,
2165     struct ImBuf *ibuf3){
2166         struct ImBuf *out = prepare_effect_imbufs(context, ibuf1, ibuf2, ibuf3);
2167
2168         do_transform(context.scene, seq, facf0, 
2169                      context.rectx, context.recty, ibuf1, out);
2170
2171         return out;
2172 }
2173
2174
2175 /* **********************************************************************
2176  * GLOW
2177  * ********************************************************************** */
2178
2179 static void RVBlurBitmap2_byte(unsigned char *map, int width, int height,
2180                                float blur,
2181                                int quality)
2182 /*      MUUUCCH better than the previous blur. */
2183 /*      We do the blurring in two passes which is a whole lot faster. */
2184 /*      I changed the math arount to implement an actual Gaussian */
2185 /*      distribution. */
2186 /* */
2187 /*      Watch out though, it tends to misbehaven with large blur values on */
2188 /*      a small bitmap.  Avoid avoid avoid. */
2189 /*=============================== */
2190 {
2191         unsigned char *temp = NULL, *swap;
2192         float   *filter = NULL;
2193         int x, y, i, fx, fy;
2194         int index, ix, halfWidth;
2195         float fval, k, curColor[3], curColor2[3], weight = 0;
2196
2197         /*      If we're not really blurring, bail out */
2198         if (blur <= 0)
2199                 return;
2200
2201         /*      Allocate memory for the tempmap and the blur filter matrix */
2202         temp = MEM_mallocN((width * height * 4), "blurbitmaptemp");
2203         if (!temp)
2204                 return;
2205
2206         /*      Allocate memory for the filter elements */
2207         halfWidth = ((quality + 1) * blur);
2208         filter = (float *)MEM_mallocN(sizeof(float) * halfWidth * 2, "blurbitmapfilter");
2209         if (!filter) {
2210                 MEM_freeN(temp);
2211                 return;
2212         }
2213
2214         /*      Apparently we're calculating a bell curve */
2215         /*      based on the standard deviation (or radius) */
2216         /*      This code is based on an example */
2217         /*      posted to comp.graphics.algorithms by */
2218         /*      Blancmange (bmange@airdmhor.gen.nz) */
2219
2220         k = -1.0f / (2.0f * (float)M_PI * blur * blur);
2221         for (ix = 0; ix < halfWidth; ix++) {
2222                 weight = (float)exp(k * (ix * ix));
2223                 filter[halfWidth - ix] = weight;
2224                 filter[halfWidth + ix] = weight;
2225         }
2226         filter[0] = weight;
2227
2228         /*      Normalize the array */
2229         fval = 0;
2230         for (ix = 0; ix < halfWidth * 2; ix++)
2231                 fval += filter[ix];
2232
2233         for (ix = 0; ix < halfWidth * 2; ix++)
2234                 filter[ix] /= fval;
2235
2236         /*      Blur the rows */
2237         for (y = 0; y < height; y++) {
2238                 /*      Do the left & right strips */
2239                 for (x = 0; x < halfWidth; x++) {
2240                         index = (x + y * width) * 4;
2241                         fx = 0;
2242                         zero_v3(curColor);
2243                         zero_v3(curColor2);
2244
2245                         for (i = x - halfWidth; i < x + halfWidth; i++) {
2246                                 if ((i >= 0) && (i < width)) {
2247                                         curColor[0] += map[(i + y * width) * 4 + GlowR] * filter[fx];
2248                                         curColor[1] += map[(i + y * width) * 4 + GlowG] * filter[fx];
2249                                         curColor[2] += map[(i + y * width) * 4 + GlowB] * filter[fx];
2250
2251                                         curColor2[0] += map[(width - 1 - i + y * width) * 4 + GlowR] *
2252                                                         filter[fx];
2253                                         curColor2[1] += map[(width - 1 - i + y * width) * 4 + GlowG] *
2254                                                         filter[fx];
2255                                         curColor2[2] += map[(width - 1 - i + y * width) * 4 + GlowB] *
2256                                                         filter[fx];
2257                                 }
2258                                 fx++;
2259                         }
2260                         temp[index + GlowR] = curColor[0];
2261                         temp[index + GlowG] = curColor[1];
2262                         temp[index + GlowB] = curColor[2];
2263
2264                         temp[((width - 1 - x + y * width) * 4) + GlowR] = curColor2[0];
2265                         temp[((width - 1 - x + y * width) * 4) + GlowG] = curColor2[1];
2266                         temp[((width - 1 - x + y * width) * 4) + GlowB] = curColor2[2];
2267
2268                 }
2269                 /*      Do the main body */
2270                 for (x = halfWidth; x < width - halfWidth; x++) {
2271                         index = (x + y * width) * 4;
2272                         fx = 0;
2273                         zero_v3(curColor);
2274                         for (i = x - halfWidth; i < x + halfWidth; i++) {
2275                                 curColor[0] += map[(i + y * width) * 4 + GlowR] * filter[fx];
2276                                 curColor[1] += map[(i + y * width) * 4 + GlowG] * filter[fx];
2277                                 curColor[2] += map[(i + y * width) * 4 + GlowB] * filter[fx];
2278                                 fx++;
2279                         }
2280                         temp[index + GlowR] = curColor[0];
2281                         temp[index + GlowG] = curColor[1];
2282                         temp[index + GlowB] = curColor[2];
2283                 }
2284         }
2285
2286         /*      Swap buffers */
2287         swap = temp; temp = map; map = swap;
2288
2289
2290         /*      Blur the columns */
2291         for (x = 0; x < width; x++) {
2292                 /*      Do the top & bottom strips */
2293                 for (y = 0; y < halfWidth; y++) {
2294                         index = (x + y * width) * 4;
2295                         fy = 0;
2296                         zero_v3(curColor);
2297                         zero_v3(curColor2);
2298                         for (i = y - halfWidth; i < y + halfWidth; i++) {
2299                                 if ((i >= 0) && (i < height)) {
2300                                         /*      Bottom */
2301                                         curColor[0] += map[(x + i * width) * 4 + GlowR] * filter[fy];
2302                                         curColor[1] += map[(x + i * width) * 4 + GlowG] * filter[fy];
2303                                         curColor[2] += map[(x + i * width) * 4 + GlowB] * filter[fy];
2304
2305                                         /*      Top */
2306                                         curColor2[0] += map[(x + (height - 1 - i) * width) *
2307                                                             4 + GlowR] * filter[fy];
2308                                         curColor2[1] += map[(x + (height - 1 - i) * width) *
2309                                                             4 + GlowG] * filter[fy];
2310                                         curColor2[2] += map[(x + (height - 1 - i) * width) *
2311                                                             4 + GlowB] * filter[fy];
2312                                 }
2313                                 fy++;
2314                         }
2315                         temp[index + GlowR] = curColor[0];
2316                         temp[index + GlowG] = curColor[1];
2317                         temp[index + GlowB] = curColor[2];
2318                         temp[((x + (height - 1 - y) * width) * 4) + GlowR] = curColor2[0];
2319                         temp[((x + (height - 1 - y) * width) * 4) + GlowG] = curColor2[1];
2320                         temp[((x + (height - 1 - y) * width) * 4) + GlowB] = curColor2[2];
2321                 }
2322                 /*      Do the main body */
2323                 for (y = halfWidth; y < height - halfWidth; y++) {
2324                         index = (x + y * width) * 4;
2325                         fy = 0;
2326                         zero_v3(curColor);
2327                         for (i = y - halfWidth; i < y + halfWidth; i++) {
2328                                 curColor[0] += map[(x + i * width) * 4 + GlowR] * filter[fy];
2329                                 curColor[1] += map[(x + i * width) * 4 + GlowG] * filter[fy];
2330                                 curColor[2] += map[(x + i * width) * 4 + GlowB] * filter[fy];
2331                                 fy++;
2332                         }
2333                         temp[index + GlowR] = curColor[0];
2334                         temp[index + GlowG] = curColor[1];
2335                         temp[index + GlowB] = curColor[2];
2336                 }
2337         }
2338
2339
2340         /*      Swap buffers */
2341         swap = temp; temp = map; /* map=swap; */ /* UNUSED */
2342
2343         /*      Tidy up  */
2344         MEM_freeN(filter);
2345         MEM_freeN(temp);
2346 }
2347
2348 static void RVBlurBitmap2_float(float *map, int width, int height,
2349                                 float blur,
2350                                 int quality)
2351 /*      MUUUCCH better than the previous blur. */
2352 /*      We do the blurring in two passes which is a whole lot faster. */
2353 /*      I changed the math arount to implement an actual Gaussian */
2354 /*      distribution. */
2355 /* */
2356 /*      Watch out though, it tends to misbehaven with large blur values on */
2357 /*      a small bitmap.  Avoid avoid avoid. */
2358 /*=============================== */
2359 {
2360         float *temp = NULL, *swap;
2361         float   *filter = NULL;
2362         int x, y, i, fx, fy;
2363         int index, ix, halfWidth;
2364         float fval, k, curColor[3], curColor2[3], weight = 0;
2365
2366         /*      If we're not really blurring, bail out */
2367         if (blur <= 0)
2368                 return;
2369
2370         /*      Allocate memory for the tempmap and the blur filter matrix */
2371         temp = MEM_mallocN((width * height * 4 * sizeof(float)), "blurbitmaptemp");
2372         if (!temp)
2373                 return;
2374
2375         /*      Allocate memory for the filter elements */
2376         halfWidth = ((quality + 1) * blur);
2377         filter = (float *)MEM_mallocN(sizeof(float) * halfWidth * 2, "blurbitmapfilter");
2378         if (!filter) {
2379                 MEM_freeN(temp);
2380                 return;
2381         }
2382
2383         /*      Apparently we're calculating a bell curve */
2384         /*      based on the standard deviation (or radius) */
2385         /*      This code is based on an example */
2386         /*      posted to comp.graphics.algorithms by */
2387         /*      Blancmange (bmange@airdmhor.gen.nz) */
2388
2389         k = -1.0f / (2.0f * (float)M_PI * blur * blur);
2390
2391         for (ix = 0; ix < halfWidth; ix++) {
2392                 weight = (float)exp(k * (ix * ix));
2393                 filter[halfWidth - ix] = weight;
2394                 filter[halfWidth + ix] = weight;
2395         }
2396         filter[0] = weight;
2397
2398         /*      Normalize the array */
2399         fval = 0;
2400         for (ix = 0; ix < halfWidth * 2; ix++)
2401                 fval += filter[ix];
2402
2403         for (ix = 0; ix < halfWidth * 2; ix++)
2404                 filter[ix] /= fval;
2405
2406         /*      Blur the rows */
2407         for (y = 0; y < height; y++) {
2408                 /*      Do the left & right strips */
2409                 for (x = 0; x < halfWidth; x++) {
2410                         index = (x + y * width) * 4;
2411                         fx = 0;
2412                         curColor[0] = curColor[1] = curColor[2] = 0.0f;
2413                         curColor2[0] = curColor2[1] = curColor2[2] = 0.0f;
2414
2415                         for (i = x - halfWidth; i < x + halfWidth; i++) {
2416                                 if ((i >= 0) && (i < width)) {
2417                                         curColor[0] += map[(i + y * width) * 4 + GlowR] * filter[fx];
2418                                         curColor[1] += map[(i + y * width) * 4 + GlowG] * filter[fx];
2419                                         curColor[2] += map[(i + y * width) * 4 + GlowB] * filter[fx];
2420
2421                                         curColor2[0] += map[(width - 1 - i + y * width) * 4 + GlowR] *
2422                                                         filter[fx];
2423                                         curColor2[1] += map[(width - 1 - i + y * width) * 4 + GlowG] *
2424                                                         filter[fx];
2425                                         curColor2[2] += map[(width - 1 - i + y * width) * 4 + GlowB] *
2426                                                         filter[fx];
2427                                 }
2428                                 fx++;
2429                         }
2430                         temp[index + GlowR] = curColor[0];
2431                         temp[index + GlowG] = curColor[1];
2432                         temp[index + GlowB] = curColor[2];
2433
2434                         temp[((width - 1 - x + y * width) * 4) + GlowR] = curColor2[0];
2435                         temp[((width - 1 - x + y * width) * 4) + GlowG] = curColor2[1];
2436                         temp[((width - 1 - x + y * width) * 4) + GlowB] = curColor2[2];
2437
2438                 }
2439                 /*      Do the main body */
2440                 for (x = halfWidth; x < width - halfWidth; x++) {
2441                         index = (x + y * width) * 4;
2442                         fx = 0;
2443                         zero_v3(curColor);
2444                         for (i = x - halfWidth; i < x + halfWidth; i++) {
2445                                 curColor[0] += map[(i + y * width) * 4 + GlowR] * filter[fx];
2446                                 curColor[1] += map[(i + y * width) * 4 + GlowG] * filter[fx];
2447                                 curColor[2] += map[(i + y * width) * 4 + GlowB] * filter[fx];
2448                                 fx++;
2449                         }
2450                         temp[index + GlowR] = curColor[0];
2451                         temp[index + GlowG] = curColor[1];
2452                         temp[index + GlowB] = curColor[2];
2453                 }
2454         }
2455
2456         /*      Swap buffers */
2457         swap = temp; temp = map; map = swap;
2458
2459
2460         /*      Blur the columns */
2461         for (x = 0; x < width; x++) {
2462                 /*      Do the top & bottom strips */
2463                 for (y = 0; y < halfWidth; y++) {
2464                         index = (x + y * width) * 4;
2465                         fy = 0;
2466                         zero_v3(curColor);
2467                         zero_v3(curColor2);
2468                         for (i = y - halfWidth; i < y + halfWidth; i++) {
2469                                 if ((i >= 0) && (i < height)) {
2470                                         /*      Bottom */
2471                                         curColor[0] += map[(x + i * width) * 4 + GlowR] * filter[fy];
2472                                         curColor[1] += map[(x + i * width) * 4 + GlowG] * filter[fy];
2473                                         curColor[2] += map[(x + i * width) * 4 + GlowB] * filter[fy];
2474
2475                                         /*      Top */
2476                                         curColor2[0] += map[(x + (height - 1 - i) * width) *
2477                                                             4 + GlowR] * filter[fy];
2478                                         curColor2[1] += map[(x + (height - 1 - i) * width) *
2479                                                             4 + GlowG] * filter[fy];
2480                                         curColor2[2] += map[(x + (height - 1 - i) * width) *
2481                                                             4 + GlowB] * filter[fy];
2482                                 }
2483                                 fy++;
2484                         }
2485                         temp[index + GlowR] = curColor[0];
2486                         temp[index + GlowG] = curColor[1];
2487                         temp[index + GlowB] = curColor[2];
2488                         temp[((x + (height - 1 - y) * width) * 4) + GlowR] = curColor2[0];
2489                         temp[((x + (height - 1 - y) * width) * 4) + GlowG] = curColor2[1];
2490                         temp[((x + (height - 1 - y) * width) * 4) + GlowB] = curColor2[2];
2491                 }
2492                 /*      Do the main body */
2493                 for (y = halfWidth; y < height - halfWidth; y++) {
2494                         index = (x + y * width) * 4;
2495                         fy = 0;
2496                         zero_v3(curColor);
2497                         for (i = y - halfWidth; i < y + halfWidth; i++) {
2498                                 curColor[0] += map[(x + i * width) * 4 + GlowR] * filter[fy];
2499                                 curColor[1] += map[(x + i * width) * 4 + GlowG] * filter[fy];
2500                                 curColor[2] += map[(x + i * width) * 4 + GlowB] * filter[fy];
2501                                 fy++;
2502                         }
2503                         temp[index + GlowR] = curColor[0];
2504                         temp[index + GlowG] = curColor[1];
2505                         temp[index + GlowB] = curColor[2];
2506                 }
2507         }
2508
2509
2510         /*      Swap buffers */
2511         swap = temp; temp = map; /* map=swap; */ /* UNUSED */
2512
2513         /*      Tidy up  */
2514         MEM_freeN(filter);
2515         MEM_freeN(temp);
2516 }
2517
2518
2519 /*      Adds two bitmaps and puts the results into a third map. */
2520 /*      C must have been previously allocated but it may be A or B. */
2521 /*      We clamp values to 255 to prevent weirdness */
2522 /*=============================== */
2523 static void RVAddBitmaps_byte(unsigned char *a, unsigned char *b, unsigned char *c, int width, int height)
2524 {
2525         int x, y, index;
2526
2527         for (y = 0; y < height; y++) {
2528                 for (x = 0; x < width; x++) {
2529                         index = (x + y * width) * 4;
2530                         c[index + GlowR] = MIN2(255, a[index + GlowR] + b[index + GlowR]);
2531                         c[index + GlowG] = MIN2(255, a[index + GlowG] + b[index + GlowG]);
2532                         c[index + GlowB] = MIN2(255, a[index + GlowB] + b[index + GlowB]);
2533                         c[index + GlowA] = MIN2(255, a[index + GlowA] + b[index + GlowA]);
2534                 }
2535         }
2536 }
2537
2538 static void RVAddBitmaps_float(float *a, float *b, float *c,
2539                                int width, int height)
2540 {
2541         int x, y, index;
2542
2543         for (y = 0; y < height; y++) {
2544                 for (x = 0; x < width; x++) {
2545                         index = (x + y * width) * 4;
2546                         c[index + GlowR] = MIN2(1.0f, a[index + GlowR] + b[index + GlowR]);
2547                         c[index + GlowG] = MIN2(1.0f, a[index + GlowG] + b[index + GlowG]);
2548                         c[index + GlowB] = MIN2(1.0f, a[index + GlowB] + b[index + GlowB]);
2549                         c[index + GlowA] = MIN2(1.0f, a[index + GlowA] + b[index + GlowA]);
2550                 }
2551         }
2552 }
2553
2554 /*      For each pixel whose total luminance exceeds the threshold, */
2555 /*      Multiply it's value by BOOST and add it to the output map */
2556 static void RVIsolateHighlights_byte(unsigned char *in, unsigned char *out,
2557                                      int width, int height, int threshold,
2558                                      float boost, float clamp)
2559 {
2560         int x, y, index;
2561         int intensity;
2562
2563
2564         for (y = 0; y < height; y++) {
2565                 for (x = 0; x < width; x++) {
2566                         index = (x + y * width) * 4;
2567
2568                         /*      Isolate the intensity */
2569                         intensity = (in[index + GlowR] + in[index + GlowG] + in[index + GlowB] - threshold);
2570                         if (intensity > 0) {
2571                                 out[index + GlowR] = MIN2(255 * clamp, (in[index + GlowR] * boost * intensity) / 255);
2572                                 out[index + GlowG] = MIN2(255 * clamp, (in[index + GlowG] * boost * intensity) / 255);
2573                                 out[index + GlowB] = MIN2(255 * clamp, (in[index + GlowB] * boost * intensity) / 255);
2574                                 out[index + GlowA] = MIN2(255 * clamp, (in[index + GlowA] * boost * intensity) / 255);
2575                         }
2576                         else {
2577                                 out[index + GlowR] = 0;
2578                                 out[index + GlowG] = 0;
2579                                 out[index + GlowB] = 0;
2580                                 out[index + GlowA] = 0;
2581                         }
2582                 }
2583         }
2584 }
2585
2586 static void RVIsolateHighlights_float(float *in, float *out,
2587                                       int width, int height, float threshold,
2588                                       float boost, float clamp)
2589 {
2590         int x, y, index;
2591         float intensity;
2592
2593
2594         for (y = 0; y < height; y++) {
2595                 for (x = 0; x < width; x++) {
2596                         index = (x + y * width) * 4;
2597
2598                         /*      Isolate the intensity */
2599                         intensity = (in[index + GlowR] + in[index + GlowG] + in[index + GlowB] - threshold);
2600                         if (intensity > 0) {
2601                                 out[index + GlowR] = MIN2(clamp, (in[index + GlowR] * boost * intensity));
2602                                 out[index + GlowG] = MIN2(clamp, (in[index + GlowG] * boost * intensity));
2603                                 out[index + GlowB] = MIN2(clamp, (in[index + GlowB] * boost * intensity));
2604                                 out[index + GlowA] = MIN2(clamp, (in[index + GlowA] * boost * intensity));
2605                         }
2606                         else {
2607                                 out[index + GlowR] = 0;
2608                                 out[index + GlowG] = 0;
2609                                 out[index + GlowB] = 0;
2610                                 out[index + GlowA] = 0;
2611                         }
2612                 }
2613         }
2614 }
2615
2616 static void init_glow_effect(Sequence *seq)
2617 {
2618         GlowVars *glow;
2619
2620         if (seq->effectdata) MEM_freeN(seq->effectdata);
2621         seq->effectdata = MEM_callocN(sizeof(struct GlowVars), "glowvars");
2622
2623         glow = (GlowVars *)seq->effectdata;
2624         glow->fMini = 0.25;
2625         glow->fClamp = 1.0;
2626         glow->fBoost = 0.5;
2627         glow->dDist = 3.0;
2628         glow->dQuality = 3;
2629         glow->bNoComp = 0;
2630 }
2631
2632 static int num_inputs_glow(void)
2633 {
2634         return 1;
2635 }
2636
2637 static void free_glow_effect(Sequence *seq)
2638 {
2639         if (seq->effectdata) MEM_freeN(seq->effectdata);
2640         seq->effectdata = NULL;
2641 }
2642
2643 static void copy_glow_effect(Sequence *dst, Sequence *src)
2644 {
2645         dst->effectdata = MEM_dupallocN(src->effectdata);
2646 }
2647
2648 //void do_glow_effect(Cast *cast, float facf0, float facf1, int xo, int yo, ImBuf *ibuf1, ImBuf *ibuf2, ImBuf *outbuf, ImBuf *use)
2649 static void do_glow_effect_byte(Sequence *seq, int render_size, float facf0, float UNUSED(facf1), 
2650                                 int x, int y, char *rect1,
2651                                 char *UNUSED(rect2), char *out)
2652 {
2653         unsigned char *outbuf = (unsigned char *)out;
2654         unsigned char *inbuf = (unsigned char *)rect1;
2655         GlowVars *glow = (GlowVars *)seq->effectdata;
2656         
2657         RVIsolateHighlights_byte(inbuf, outbuf, x, y, glow->fMini * 765, glow->fBoost * facf0, glow->fClamp);
2658         RVBlurBitmap2_byte(outbuf, x, y, glow->dDist * (render_size / 100.0f), glow->dQuality);
2659         if (!glow->bNoComp)
2660                 RVAddBitmaps_byte(inbuf, outbuf, outbuf, x, y);
2661 }
2662
2663 static void do_glow_effect_float(Sequence *seq, int render_size, float facf0, float UNUSED(facf1), 
2664                                  int x, int y,
2665                                  float *rect1, float *UNUSED(rect2), float *out)
2666 {
2667         float *outbuf = out;
2668         float *inbuf = rect1;
2669         GlowVars *glow = (GlowVars *)seq->effectdata;
2670
2671         RVIsolateHighlights_float(inbuf, outbuf, x, y, glow->fMini * 3.0f, glow->fBoost * facf0, glow->fClamp);
2672         RVBlurBitmap2_float(outbuf, x, y, glow->dDist * (render_size / 100.0f), glow->dQuality);
2673         if (!glow->bNoComp)
2674                 RVAddBitmaps_float(inbuf, outbuf, outbuf, x, y);
2675 }
2676
2677 static struct ImBuf *do_glow_effect(
2678         SeqRenderData context, Sequence *seq, float UNUSED(cfra),
2679         float facf0, float facf1,
2680         struct ImBuf *ibuf1, struct ImBuf *ibuf2,
2681         struct ImBuf *ibuf3)
2682 {
2683         struct ImBuf *out = prepare_effect_imbufs(context, ibuf1, ibuf2, ibuf3);
2684
2685         int render_size = 100 * context.rectx / context.scene->r.xsch;
2686
2687         if (out->rect_float) {
2688                 do_glow_effect_float(seq, render_size,
2689                                      facf0, facf1,
2690                                      context.rectx, context.recty,
2691                                      ibuf1->rect_float, ibuf2->rect_float,
2692                                      out->rect_float);
2693         }
2694         else {
2695                 do_glow_effect_byte(seq, render_size,
2696                                     facf0, facf1,
2697                                     context.rectx, context.recty,
2698                                     (char *) ibuf1->rect, (char *) ibuf2->rect,
2699                                     (char *) out->rect);
2700         }
2701
2702         return out;
2703 }
2704
2705 /* **********************************************************************
2706  * SOLID COLOR
2707  * ********************************************************************** */
2708
2709 static void init_solid_color(Sequence *seq)
2710 {
2711         SolidColorVars *cv;
2712         
2713         if (seq->effectdata) MEM_freeN(seq->effectdata);
2714         seq->effectdata = MEM_callocN(sizeof(struct SolidColorVars), "solidcolor");
2715         
2716         cv = (SolidColorVars *)seq->effectdata;
2717         cv->col[0] = cv->col[1] = cv->col[2] = 0.5;
2718 }
2719
2720 static int num_inputs_color(void)
2721 {
2722         return 0;
2723 }
2724
2725 static void free_solid_color(Sequence *seq)
2726 {
2727         if (seq->effectdata) MEM_freeN(seq->effectdata);
2728         seq->effectdata = NULL;
2729 }
2730
2731 static void copy_solid_color(Sequence *dst, Sequence *src)
2732 {
2733         dst->effectdata = MEM_dupallocN(src->effectdata);
2734 }
2735
2736 static int early_out_color(struct Sequence *UNUSED(seq),
2737                            float UNUSED(facf0), float UNUSED(facf1))
2738 {
2739         return -1;
2740 }
2741
2742 static struct ImBuf *do_solid_color(
2743     SeqRenderData context, Sequence *seq, float UNUSED(cfra),
2744     float facf0, float facf1,
2745     struct ImBuf *ibuf1, struct ImBuf *ibuf2,
2746     struct ImBuf *ibuf3){
2747         struct ImBuf *out = prepare_effect_imbufs(context, ibuf1, ibuf2, ibuf3);
2748
2749         SolidColorVars *cv = (SolidColorVars *)seq->effectdata;
2750
2751         unsigned char *rect;
2752         float *rect_float;
2753         int x; /*= context.rectx;*/ /*UNUSED*/
2754         int y; /*= context.recty;*/ /*UNUSED*/
2755
2756         if (out->rect) {
2757                 unsigned char col0[3];
2758                 unsigned char col1[3];
2759
2760                 col0[0] = facf0 * cv->col[0] * 255;
2761                 col0[1] = facf0 * cv->col[1] * 255;
2762                 col0[2] = facf0 * cv->col[2] * 255;
2763
2764                 col1[0] = facf1 * cv->col[0] * 255;
2765                 col1[1] = facf1 * cv->col[1] * 255;
2766                 col1[2] = facf1 * cv->col[2] * 255;
2767
2768                 rect = (unsigned char *)out->rect;
2769                 
2770                 for (y = 0; y < out->y; y++) {
2771                         for (x = 0; x < out->x; x++, rect += 4) {
2772                                 rect[0] = col0[0];
2773                                 rect[1] = col0[1];
2774                                 rect[2] = col0[2];
2775                                 rect[3] = 255;
2776                         }
2777                         y++;
2778                         if (y < out->y) {
2779                                 for (x = 0; x < out->x; x++, rect += 4) {
2780                                         rect[0] = col1[0];
2781                                         rect[1] = col1[1];
2782                                         rect[2] = col1[2];
2783                                         rect[3] = 255;
2784                                 }       
2785                         }
2786                 }
2787
2788         }
2789         else if (out->rect_float) {
2790                 float col0[3];
2791                 float col1[3];
2792
2793                 col0[0] = facf0 * cv->col[0];
2794                 col0[1] = facf0 * cv->col[1];
2795                 col0[2] = facf0 * cv->col[2];
2796
2797                 col1[0] = facf1 * cv->col[0];
2798                 col1[1] = facf1 * cv->col[1];
2799                 col1[2] = facf1 * cv->col[2];
2800
2801                 rect_float = out->rect_float;
2802                 
2803                 for (y = 0; y < out->y; y++) {
2804                         for (x = 0; x < out->x; x++, rect_float += 4) {
2805                                 rect_float[0] = col0[0];
2806                                 rect_float[1] = col0[1];
2807                                 rect_float[2] = col0[2];
2808                                 rect_float[3] = 1.0;
2809                         }
2810                         y++;
2811                         if (y < out->y) {
2812                                 for (x = 0; x < out->x; x++, rect_float += 4) {
2813                                         rect_float[0] = col1[0];
2814                                         rect_float[1] = col1[1];
2815                                         rect_float[2] = col1[2];
2816                                         rect_float[3] = 1.0;
2817                                 }
2818                         }
2819                 }
2820         }
2821         return out;
2822 }
2823
2824 /* **********************************************************************
2825  * MULTICAM
2826  * ********************************************************************** */
2827
2828 /* no effect inputs for multicam, we use give_ibuf_seq */
2829 static int num_inputs_multicam(void)
2830 {
2831         return 0;
2832 }
2833
2834 static int early_out_multicam(struct Sequence *UNUSED(seq), float UNUSED(facf0), float UNUSED(facf1))
2835 {
2836         return -1;
2837 }
2838
2839 static struct ImBuf *do_multicam(
2840     SeqRenderData context, Sequence *seq, float cfra,
2841     float UNUSED(facf0), float UNUSED(facf1),
2842     struct ImBuf *UNUSED(ibuf1), struct ImBuf *UNUSED(ibuf2),
2843     struct ImBuf *UNUSED(ibuf3)){
2844         struct ImBuf *i;
2845         struct ImBuf *out;
2846         Editing *ed;
2847         ListBase *seqbasep;
2848
2849         if (seq->multicam_source == 0 || seq->multicam_source >= seq->machine) {
2850                 return NULL;
2851         }
2852
2853         ed = context.scene->ed;
2854         if (!ed) {
2855                 return NULL;
2856         }
2857         seqbasep = seq_seqbase(&ed->seqbase, seq);
2858         if (!seqbasep) {
2859                 return NULL;
2860         }
2861
2862         i = give_ibuf_seqbase(context, cfra, seq->multicam_source, seqbasep);
2863         if (!i) {
2864                 return NULL;
2865         }
2866
2867         if (input_have_to_preprocess(context, seq, cfra)) {
2868                 out = IMB_dupImBuf(i);
2869                 IMB_freeImBuf(i);
2870         }
2871         else {
2872                 out = i;
2873         }
2874         
2875         return out;
2876 }
2877
2878 /* **********************************************************************
2879  * ADJUSTMENT
2880  * ********************************************************************** */
2881
2882 /* no effect inputs for adjustment, we use give_ibuf_seq */
2883 static int num_inputs_adjustment(void)
2884 {
2885         return 0;
2886 }
2887
2888 static int early_out_adjustment(struct Sequence *UNUSED(seq), float UNUSED(facf0), float UNUSED(facf1))
2889 {
2890         return -1;
2891 }
2892
2893 static struct ImBuf *do_adjustment_impl(SeqRenderData context, Sequence *seq,
2894                                         float cfra){
2895         Editing *ed;
2896         ListBase *seqbasep;
2897         struct ImBuf *i = NULL;
2898
2899         ed = context.scene->ed;
2900
2901         seqbasep = seq_seqbase(&ed->seqbase, seq);
2902
2903         if (seq->machine > 0) {
2904                 i = give_ibuf_seqbase(context, cfra,
2905                                       seq->machine - 1, seqbasep);
2906         }
2907
2908         /* found nothing? so let's work the way up the metastrip stack, so
2909          *  that it is possible to group a bunch of adjustment strips into
2910          *  a metastrip and have that work on everything below the metastrip
2911          */
2912
2913         if (!i) {
2914                 Sequence *meta;
2915
2916                 meta = seq_metastrip(&ed->seqbase, NULL, seq);
2917
2918                 if (meta) {
2919                         i = do_adjustment_impl(context, meta, cfra);
2920                 }
2921         }
2922
2923         return i;
2924 }
2925
2926 static struct ImBuf *do_adjustment(
2927     SeqRenderData context, Sequence *seq, float cfra,
2928     float UNUSED(facf0), float UNUSED(facf1),
2929     struct ImBuf *UNUSED(ibuf1), struct ImBuf *UNUSED(ibuf2),
2930     struct ImBuf *UNUSED(ibuf3)){
2931         struct ImBuf *i = NULL;
2932         struct ImBuf *out;
2933         Editing *ed;
2934
2935         ed = context.scene->ed;
2936
2937         if (!ed) {
2938                 return NULL;
2939         }
2940
2941         i = do_adjustment_impl(context, seq, cfra);
2942
2943         if (input_have_to_preprocess(context, seq, cfra)) {
2944                 out = IMB_dupImBuf(i);
2945                 IMB_freeImBuf(i);
2946         }
2947         else {
2948                 out = i;
2949         }
2950         
2951         return out;
2952 }
2953
2954 /* **********************************************************************
2955  * SPEED
2956  * ********************************************************************** */
2957 static void init_speed_effect(Sequence *seq)
2958 {
2959         SpeedControlVars *v;
2960
2961         if (seq->effectdata) MEM_freeN(seq->effectdata);
2962         seq->effectdata = MEM_callocN(sizeof(struct SpeedControlVars), 
2963                                       "speedcontrolvars");
2964
2965         v = (SpeedControlVars *)seq->effectdata;
2966         v->globalSpeed = 1.0;
2967         v->frameMap = NULL;
2968         v->flags |= SEQ_SPEED_INTEGRATE; /* should be default behavior */
2969         v->length = 0;
2970 }
2971
2972 static void load_speed_effect(Sequence *seq)
2973 {
2974         SpeedControlVars *v = (SpeedControlVars *)seq->effectdata;
2975
2976         v->frameMap = NULL;
2977         v->length = 0;
2978 }
2979
2980 static int num_inputs_speed(void)
2981 {
2982         return 1;
2983 }
2984
2985 static void free_speed_effect(Sequence *seq)
2986 {
2987         SpeedControlVars *v = (SpeedControlVars *)seq->effectdata;
2988         if (v->frameMap) MEM_freeN(v->frameMap);
2989         if (seq->effectdata) MEM_freeN(seq->effectdata);
2990         seq->effectdata = NULL;
2991 }
2992
2993 static void copy_speed_effect(Sequence *dst, Sequence *src)
2994 {
2995         SpeedControlVars *v;
2996         dst->effectdata = MEM_dupallocN(src->effectdata);
2997         v = (SpeedControlVars *)dst->effectdata;
2998         v->frameMap = NULL;
2999         v->length = 0;
3000 }
3001
3002 static int early_out_speed(struct Sequence *UNUSED(seq),
3003                            float UNUSED(facf0), float UNUSED(facf1))
3004 {
3005         return 1;
3006 }
3007
3008 static void store_icu_yrange_speed(struct Sequence *seq,
3009                                    short UNUSED(adrcode), float *ymin, float *ymax)
3010 {
3011         SpeedControlVars *v = (SpeedControlVars *)seq->effectdata;
3012
3013         /* if not already done, load / initialize data */
3014         get_sequence_effect(seq);
3015
3016         if ((v->flags & SEQ_SPEED_INTEGRATE) != 0) {
3017                 *ymin = -100.0;
3018                 *ymax = 100.0;
3019         }
3020         else {
3021                 if (v->flags & SEQ_SPEED_COMPRESS_IPO_Y) {
3022                         *ymin = 0.0;
3023                         *ymax = 1.0;
3024                 }
3025                 else {
3026                         *ymin = 0.0;
3027                         *ymax = seq->len;
3028                 }
3029         }       
3030 }
3031 void sequence_effect_speed_rebuild_map(Scene *scene, Sequence *seq, int force)
3032 {
3033         int cfra;
3034         float fallback_fac = 1.0f;
3035         SpeedControlVars *v = (SpeedControlVars *)seq->effectdata;
3036         FCurve *fcu = NULL;
3037         int flags = v->flags;
3038
3039         /* if not already done, load / initialize data */
3040         get_sequence_effect(seq);
3041
3042         if ((force == FALSE) &&
3043             (seq->len == v->length) &&
3044             (v->frameMap != NULL))
3045         {
3046                 return;
3047         }
3048         if ((seq->seq1 == NULL) || (seq->len < 1)) {
3049                 /* make coverity happy and check for (CID 598) input strip ... */
3050                 return;
3051         }
3052
3053         /* XXX - new in 2.5x. should we use the animation system this way?
3054          * The fcurve is needed because many frames need evaluating at once - campbell */
3055         fcu = id_data_find_fcurve(&scene->id, seq, &RNA_Sequence, "speed_factor", 0, NULL);
3056
3057
3058         if (!v->frameMap || v->length != seq->len) {
3059                 if (v->frameMap) MEM_freeN(v->frameMap);
3060
3061                 v->length = seq->len;
3062
3063                 v->frameMap = MEM_callocN(sizeof(float) * v->length, 
3064                                           "speedcontrol frameMap");
3065         }
3066
3067         fallback_fac = 1.0;
3068
3069         if (seq->flag & SEQ_USE_EFFECT_DEFAULT_FADE) {
3070                 if ((seq->seq1->enddisp != seq->seq1->start) &&
3071                     (seq->seq1->len != 0))
3072                 {
3073                         fallback_fac = (float) seq->seq1->len / 
3074                                        (float) (seq->seq1->enddisp&nb