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