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