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