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