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