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