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