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