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