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