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