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