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