Spelling fixes in comments and descriptions, patch by luzpaz.
[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       /* BOX WIPE IS NOT WORKING YET */
1771                         /* case DO_CROSS_WIPE: */
1772                         /* BOX WIPE IS NOT WORKING YET */
1773 #if 0
1774                 case DO_BOX_WIPE:
1775                         if (!wipe->forward) {
1776                                 facf0 = 1.0f - facf0;  /* Go the other direction */
1777                         }
1778
1779                         width = (int)(wipe->edgeWidth * ((xo + yo) / 2.0));
1780                         hwidth = (float)width / 2.0;
1781                         if (angle == 0) angle = 0.000001;
1782                         b1 = posy / 2 - (-angle) * posx / 2;
1783                         b3 = (yo - posy / 2) - (-angle) * (xo - posx / 2);
1784                         b2 = y - (-angle) * x;
1785
1786                         hyp = abs(angle * x + y + (-posy / 2 - angle * posx / 2)) * wipezone->pythangle;
1787                         hyp2 = abs(angle * x + y + (-(yo - posy / 2) - angle * (xo - posx / 2))) * wipezone->pythangle;
1788
1789                         temp1 = xo * (1 - facf0 / 2) - xo * facf0 / 2;
1790                         temp2 = yo * (1 - facf0 / 2) - yo * facf0 / 2;
1791                         pointdist = hypot(temp1, temp2);
1792
1793                         if (b2 < b1 && b2 < b3) {
1794                                 if (hwidth < pointdist)
1795                                         output = in_band(hwidth, hyp, 0, 1);
1796                         }
1797                         else if (b2 > b1 && b2 > b3) {
1798                                 if (hwidth < pointdist)
1799                                         output = in_band(hwidth, hyp2, 0, 1);
1800                         }
1801                         else {
1802                                 if (hyp < hwidth && hyp2 > hwidth)
1803                                         output = in_band(hwidth, hyp, 1, 1);
1804                                 else if (hyp > hwidth && hyp2 < hwidth)
1805                                         output = in_band(hwidth, hyp2, 1, 1);
1806                                 else
1807                                         output = in_band(hwidth, hyp2, 1, 1) * in_band(hwidth, hyp, 1, 1);
1808                         }
1809
1810                         if (!wipe->forward) {
1811                                 facf0 = 1.0f - facf0;  /* Go the other direction */
1812                         }
1813                         angle = -1 / angle;
1814                         b1 = posy / 2 - (-angle) * posx / 2;
1815                         b3 = (yo - posy / 2) - (-angle) * (xo - posx / 2);
1816                         b2 = y - (-angle) * x;
1817
1818                         hyp = abs(angle * x + y + (-posy / 2 - angle * posx / 2)) * wipezone->pythangle;
1819                         hyp2 = abs(angle * x + y + (-(yo - posy / 2) - angle * (xo - posx / 2))) * wipezone->pythangle;
1820
1821                         if (b2 < b1 && b2 < b3) {
1822                                 if (hwidth < pointdist)
1823                                         output *= in_band(hwidth, hyp, 0, 1);
1824                         }
1825                         else if (b2 > b1 && b2 > b3) {
1826                                 if (hwidth < pointdist)
1827                                         output *= in_band(hwidth, hyp2, 0, 1);
1828                         }
1829                         else {
1830                                 if (hyp < hwidth && hyp2 > hwidth)
1831                                         output *= in_band(hwidth, hyp, 1, 1);
1832                                 else if (hyp > hwidth && hyp2 < hwidth)
1833                                         output *= in_band(hwidth, hyp2, 1, 1);
1834                                 else
1835                                         output *= in_band(hwidth, hyp2, 1, 1) * in_band(hwidth, hyp, 1, 1);
1836                         }
1837
1838                         break;
1839 #endif
1840                 case DO_IRIS_WIPE:
1841                         if (xo > yo) yo = xo;
1842                         else xo = yo;
1843
1844                         if (!wipe->forward) facf0 = 1 - facf0;
1845
1846                         width = wipezone->width;
1847                         hwidth = width * 0.5f;
1848
1849                         temp1 = (halfx - (halfx) * facf0);
1850                         pointdist = hypotf(temp1, temp1);
1851
1852                         temp2 = hypotf(halfx - x, halfy - y);
1853                         if (temp2 > pointdist) output = in_band(hwidth, fabsf(temp2 - pointdist), 0, 1);
1854                         else output = in_band(hwidth, fabsf(temp2 - pointdist), 1, 1);
1855
1856                         if (!wipe->forward) output = 1 - output;
1857
1858                         break;
1859         }
1860         if (output < 0) output = 0;
1861         else if (output > 1) output = 1;
1862         return output;
1863 }
1864
1865 static void init_wipe_effect(Sequence *seq)
1866 {
1867         if (seq->effectdata)
1868                 MEM_freeN(seq->effectdata);
1869
1870         seq->effectdata = MEM_callocN(sizeof(WipeVars), "wipevars");
1871 }
1872
1873 static int num_inputs_wipe(void)
1874 {
1875         return 2;
1876 }
1877
1878 static void free_wipe_effect(Sequence *seq)
1879 {
1880         if (seq->effectdata)
1881                 MEM_freeN(seq->effectdata);
1882
1883         seq->effectdata = NULL;
1884 }
1885
1886 static void copy_wipe_effect(Sequence *dst, Sequence *src)
1887 {
1888         dst->effectdata = MEM_dupallocN(src->effectdata);
1889 }
1890
1891 static void do_wipe_effect_byte(
1892         Sequence *seq, float facf0, float UNUSED(facf1), int x, int y,
1893         unsigned char *rect1, unsigned char *rect2, unsigned char *out)
1894 {
1895         WipeZone wipezone;
1896         WipeVars *wipe = (WipeVars *)seq->effectdata;
1897         int xo, yo;
1898         unsigned char *cp1, *cp2, *rt;
1899
1900         precalc_wipe_zone(&wipezone, wipe, x, y);
1901
1902         cp1 = rect1;
1903         cp2 = rect2;
1904         rt = out;
1905
1906         xo = x;
1907         yo = y;
1908         for (y = 0; y < yo; y++) {
1909                 for (x = 0; x < xo; x++) {
1910                         float check = check_zone(&wipezone, x, y, seq, facf0);
1911                         if (check) {
1912                                 if (cp1) {
1913                                         float rt1[4], rt2[4], tempc[4];
1914
1915                                         straight_uchar_to_premul_float(rt1, cp1);
1916                                         straight_uchar_to_premul_float(rt2, cp2);
1917
1918                                         tempc[0] = rt1[0] * check + rt2[0] * (1 - check);
1919                                         tempc[1] = rt1[1] * check + rt2[1] * (1 - check);
1920                                         tempc[2] = rt1[2] * check + rt2[2] * (1 - check);
1921                                         tempc[3] = rt1[3] * check + rt2[3] * (1 - check);
1922
1923                                         premul_float_to_straight_uchar(rt, tempc);
1924                                 }
1925                                 else {
1926                                         rt[0] = 0;
1927                                         rt[1] = 0;
1928                                         rt[2] = 0;
1929                                         rt[3] = 255;
1930                                 }
1931                         }
1932                         else {
1933                                 if (cp2) {
1934                                         rt[0] = cp2[0];
1935                                         rt[1] = cp2[1];
1936                                         rt[2] = cp2[2];
1937                                         rt[3] = cp2[3];
1938                                 }
1939                                 else {
1940                                         rt[0] = 0;
1941                                         rt[1] = 0;
1942                                         rt[2] = 0;
1943                                         rt[3] = 255;
1944                                 }
1945                         }
1946
1947                         rt += 4;
1948                         if (cp1 != NULL) {
1949                                 cp1 += 4;
1950                         }
1951                         if (cp2 != NULL) {
1952                                 cp2 += 4;
1953                         }
1954                 }
1955         }
1956 }
1957
1958 static void do_wipe_effect_float(
1959         Sequence *seq, float facf0, float UNUSED(facf1), int x, int y,
1960         float *rect1, float *rect2, float *out)
1961 {
1962         WipeZone wipezone;
1963         WipeVars *wipe = (WipeVars *)seq->effectdata;
1964         int xo, yo;
1965         float *rt1, *rt2, *rt;
1966
1967         precalc_wipe_zone(&wipezone, wipe, x, y);
1968
1969         rt1 = rect1;
1970         rt2 = rect2;
1971         rt = out;
1972
1973         xo = x;
1974         yo = y;
1975         for (y = 0; y < yo; y++) {
1976                 for (x = 0; x < xo; x++) {
1977                         float check = check_zone(&wipezone, x, y, seq, facf0);
1978                         if (check) {
1979                                 if (rt1) {
1980                                         rt[0] = rt1[0] * check + rt2[0] * (1 - check);
1981                                         rt[1] = rt1[1] * check + rt2[1] * (1 - check);
1982                                         rt[2] = rt1[2] * check + rt2[2] * (1 - check);
1983                                         rt[3] = rt1[3] * check + rt2[3] * (1 - check);
1984                                 }
1985                                 else {
1986                                         rt[0] = 0;
1987                                         rt[1] = 0;
1988                                         rt[2] = 0;
1989                                         rt[3] = 1.0;
1990                                 }
1991                         }
1992                         else {
1993                                 if (rt2) {
1994                                         rt[0] = rt2[0];
1995                                         rt[1] = rt2[1];
1996                                         rt[2] = rt2[2];
1997                                         rt[3] = rt2[3];
1998                                 }
1999                                 else {
2000                                         rt[0] = 0;
2001                                         rt[1] = 0;
2002                                         rt[2] = 0;
2003                                         rt[3] = 1.0;
2004                                 }
2005                         }
2006
2007                         rt += 4;
2008                         if (rt1 != NULL) {
2009                                 rt1 += 4;
2010                         }
2011                         if (rt2 != NULL) {
2012                                 rt2 += 4;
2013                         }
2014                 }
2015         }
2016 }
2017
2018 static ImBuf *do_wipe_effect(
2019         const SeqRenderData *context, Sequence *seq, float UNUSED(cfra), float facf0, float facf1,
2020         ImBuf *ibuf1, ImBuf *ibuf2, ImBuf *ibuf3)
2021 {
2022         ImBuf *out = prepare_effect_imbufs(context, ibuf1, ibuf2, ibuf3);
2023
2024         if (out->rect_float) {
2025                 do_wipe_effect_float(
2026                         seq, facf0, facf1, context->rectx, context->recty, ibuf1->rect_float,
2027                         ibuf2->rect_float, out->rect_float);
2028         }
2029         else {
2030                 do_wipe_effect_byte(
2031                         seq, facf0, facf1, context->rectx, context->recty, (unsigned char *) ibuf1->rect,
2032                         (unsigned char *) ibuf2->rect, (unsigned char *) out->rect);
2033         }
2034
2035         return out;
2036 }
2037
2038 /*********************** Transform *************************/
2039
2040 static void init_transform_effect(Sequence *seq)
2041 {
2042         TransformVars *transform;
2043
2044         if (seq->effectdata)
2045                 MEM_freeN(seq->effectdata);
2046
2047         seq->effectdata = MEM_callocN(sizeof(TransformVars), "transformvars");
2048
2049         transform = (TransformVars *) seq->effectdata;
2050
2051         transform->ScalexIni = 1.0f;
2052         transform->ScaleyIni = 1.0f;
2053
2054         transform->xIni = 0.0f;
2055         transform->yIni = 0.0f;
2056
2057         transform->rotIni = 0.0f;
2058
2059         transform->interpolation = 1;
2060         transform->percent = 1;
2061         transform->uniform_scale = 0;
2062 }
2063
2064 static int num_inputs_transform(void)
2065 {
2066         return 1;
2067 }
2068
2069 static void free_transform_effect(Sequence *seq)
2070 {
2071         if (seq->effectdata) MEM_freeN(seq->effectdata);
2072         seq->effectdata = NULL;
2073 }
2074
2075 static void copy_transform_effect(Sequence *dst, Sequence *src)
2076 {
2077         dst->effectdata = MEM_dupallocN(src->effectdata);
2078 }
2079
2080 static void transform_image(
2081         int x, int y, ImBuf *ibuf1, ImBuf *out,  float scale_x, float scale_y,
2082         float translate_x, float translate_y, float rotate, int interpolation)
2083 {
2084         int xo, yo, xi, yi;
2085         float xt, yt, xr, yr;
2086         float s, c;
2087
2088         xo = x;
2089         yo = y;
2090
2091         /* Rotate */
2092         s = sinf(rotate);
2093         c = cosf(rotate);
2094
2095         for (yi = 0; yi < yo; yi++) {
2096                 for (xi = 0; xi < xo; xi++) {
2097                         /* translate point */
2098                         xt = xi - translate_x;
2099                         yt = yi - translate_y;
2100
2101                         /* rotate point with center ref */
2102                         xr =  c * xt + s * yt;
2103                         yr = -s * xt + c * yt;
2104
2105                         /* scale point with center ref */
2106                         xt = xr / scale_x;
2107                         yt = yr / scale_y;
2108
2109                         /* undo reference center point  */
2110                         xt += (xo / 2.0f);
2111                         yt += (yo / 2.0f);
2112
2113                         /* interpolate */
2114                         switch (interpolation) {
2115                                 case 0:
2116                                         nearest_interpolation(ibuf1, out, xt, yt, xi, yi);
2117                                         break;
2118                                 case 1:
2119                                         bilinear_interpolation(ibuf1, out, xt, yt, xi, yi);
2120                                         break;
2121                                 case 2:
2122                                         bicubic_interpolation(ibuf1, out, xt, yt, xi, yi);
2123                                         break;
2124                         }
2125                 }
2126         }
2127 }
2128
2129 static void do_transform(Scene *scene, Sequence *seq, float UNUSED(facf0), int x, int y,  ImBuf *ibuf1, ImBuf *out)
2130 {
2131         TransformVars *transform = (TransformVars *) seq->effectdata;
2132         float scale_x, scale_y, translate_x, translate_y, rotate_radians;
2133
2134         /* Scale */
2135         if (transform->uniform_scale) {
2136                 scale_x = scale_y = transform->ScalexIni;
2137         }
2138         else {
2139                 scale_x = transform->ScalexIni;
2140                 scale_y = transform->ScaleyIni;
2141         }
2142
2143         /* Translate */
2144         if (!transform->percent) {
2145                 float rd_s = (scene->r.size / 100.0f);
2146
2147                 translate_x = transform->xIni * rd_s + (x / 2.0f);
2148                 translate_y = transform->yIni * rd_s + (y / 2.0f);
2149         }
2150         else {
2151                 translate_x = x * (transform->xIni / 100.0f) + (x / 2.0f);
2152                 translate_y = y * (transform->yIni / 100.0f) + (y / 2.0f);
2153         }
2154
2155         /* Rotate */
2156         rotate_radians = DEG2RADF(transform->rotIni);
2157
2158         transform_image(x, y, ibuf1, out, scale_x, scale_y, translate_x, translate_y, rotate_radians, transform->interpolation);
2159 }
2160
2161
2162 static ImBuf *do_transform_effect(
2163         const SeqRenderData *context, Sequence *seq, float UNUSED(cfra), float facf0,
2164         float UNUSED(facf1), ImBuf *ibuf1, ImBuf *ibuf2, ImBuf *ibuf3)
2165 {
2166         ImBuf *out = prepare_effect_imbufs(context, ibuf1, ibuf2, ibuf3);
2167
2168         do_transform(context->scene, seq, facf0, context->rectx, context->recty, ibuf1, out);
2169
2170         return out;
2171 }
2172
2173 /*********************** Glow *************************/
2174
2175 static void RVBlurBitmap2_float(float *map, int width, int height, float blur, int quality)
2176 /*      MUUUCCH better than the previous blur. */
2177 /*      We do the blurring in two passes which is a whole lot faster. */
2178 /*      I changed the math around to implement an actual Gaussian */
2179 /*      distribution. */
2180 /* */
2181 /*      Watch out though, it tends to misbehaven with large blur values on */
2182 /*      a small bitmap.  Avoid avoid avoid. */
2183 /*=============================== */
2184 {
2185         float *temp = NULL, *swap;
2186         float *filter = NULL;
2187         int x, y, i, fx, fy;
2188         int index, ix, halfWidth;
2189         float fval, k, curColor[4], curColor2[4], weight = 0;
2190
2191         /* If we're not really blurring, bail out */
2192         if (blur <= 0)
2193                 return;
2194
2195         /* Allocate memory for the tempmap and the blur filter matrix */
2196         temp = MEM_mallocN((width * height * 4 * sizeof(float)), "blurbitmaptemp");
2197         if (!temp)
2198                 return;
2199
2200         /* Allocate memory for the filter elements */
2201         halfWidth = ((quality + 1) * blur);
2202         filter = (float *)MEM_mallocN(sizeof(float) * halfWidth * 2, "blurbitmapfilter");
2203         if (!filter) {
2204                 MEM_freeN(temp);
2205                 return;
2206         }
2207
2208         /* Apparently we're calculating a bell curve based on the standard deviation (or radius)
2209          * This code is based on an example posted to comp.graphics.algorithms by
2210          * Blancmange (bmange@airdmhor.gen.nz)
2211          */
2212
2213         k = -1.0f / (2.0f * (float)M_PI * blur * blur);
2214
2215         for (ix = 0; ix < halfWidth; ix++) {
2216                 weight = (float)exp(k * (ix * ix));
2217                 filter[halfWidth - ix] = weight;
2218                 filter[halfWidth + ix] = weight;
2219         }
2220         filter[0] = weight;
2221
2222         /* Normalize the array */
2223         fval = 0;
2224         for (ix = 0; ix < halfWidth * 2; ix++)
2225                 fval += filter[ix];
2226
2227         for (ix = 0; ix < halfWidth * 2; ix++)
2228                 filter[ix] /= fval;
2229
2230         /* Blur the rows */
2231         for (y = 0; y < height; y++) {
2232                 /* Do the left & right strips */
2233                 for (x = 0; x < halfWidth; x++) {
2234                         fx = 0;
2235                         zero_v4(curColor);
2236                         zero_v4(curColor2);
2237
2238                         for (i = x - halfWidth; i < x + halfWidth; i++) {
2239                                 if ((i >= 0) && (i < width)) {
2240                                         index = (i + y * width) * 4;
2241                                         madd_v4_v4fl(curColor, map + index, filter[fx]);
2242
2243                                         index = (width - 1 - i + y * width) * 4;
2244                                         madd_v4_v4fl(curColor2, map + index, filter[fx]);
2245                                 }
2246                                 fx++;
2247                         }
2248                         index = (x + y * width) * 4;
2249                         copy_v4_v4(temp + index, curColor);
2250
2251                         index = (width - 1 - x + y * width) * 4;
2252                         copy_v4_v4(temp + index, curColor2);
2253                 }
2254
2255                 /* Do the main body */
2256                 for (x = halfWidth; x < width - halfWidth; x++) {
2257                         fx = 0;
2258                         zero_v4(curColor);
2259                         for (i = x - halfWidth; i < x + halfWidth; i++) {
2260                                 index = (i + y * width) * 4;
2261                                 madd_v4_v4fl(curColor, map + index, filter[fx]);
2262                                 fx++;
2263                         }
2264                         index = (x + y * width) * 4;
2265                         copy_v4_v4(temp + index, curColor);
2266                 }
2267         }
2268
2269         /* Swap buffers */
2270         swap = temp; temp = map; map = swap;
2271
2272         /* Blur the columns */
2273         for (x = 0; x < width; x++) {
2274                 /* Do the top & bottom strips */
2275                 for (y = 0; y < halfWidth; y++) {
2276                         fy = 0;
2277                         zero_v4(curColor);
2278                         zero_v4(curColor2);
2279                         for (i = y - halfWidth; i < y + halfWidth; i++) {
2280                                 if ((i >= 0) && (i < height)) {
2281                                         /* Bottom */
2282                                         index = (x + i * width) * 4;
2283                                         madd_v4_v4fl(curColor, map + index, filter[fy]);
2284
2285                                         /* Top */
2286                                         index = (x + (height - 1 - i) * width) * 4;
2287                                         madd_v4_v4fl(curColor2, map + index, filter[fy]);
2288                                 }
2289                                 fy++;
2290                         }
2291                         index = (x + y * width) * 4;
2292                         copy_v4_v4(temp + index, curColor);
2293
2294                         index = (x + (height - 1 - y) * width) * 4;
2295                         copy_v4_v4(temp + index, curColor2);
2296                 }
2297
2298                 /* Do the main body */
2299                 for (y = halfWidth; y < height - halfWidth; y++) {
2300                         fy = 0;
2301                         zero_v4(curColor);
2302                         for (i = y - halfWidth; i < y + halfWidth; i++) {
2303                                 index = (x + i * width) * 4;
2304                                 madd_v4_v4fl(curColor, map + index, filter[fy]);
2305                                 fy++;
2306                         }
2307                         index = (x + y * width) * 4;
2308                         copy_v4_v4(temp + index, curColor);
2309                 }
2310         }
2311
2312         /* Swap buffers */
2313         swap = temp; temp = map; /* map = swap; */ /* UNUSED */
2314
2315         /* Tidy up       */
2316         MEM_freeN(filter);
2317         MEM_freeN(temp);
2318 }
2319
2320 static void RVAddBitmaps_float(float *a, float *b, float *c, int width, int height)
2321 {
2322         int x, y, index;
2323
2324         for (y = 0; y < height; y++) {
2325                 for (x = 0; x < width; x++) {
2326                         index = (x + y * width) * 4;
2327                         c[index + GlowR] = min_ff(1.0f, a[index + GlowR] + b[index + GlowR]);
2328                         c[index + GlowG] = min_ff(1.0f, a[index + GlowG] + b[index + GlowG]);
2329                         c[index + GlowB] = min_ff(1.0f, a[index + GlowB] + b[index + GlowB]);
2330                         c[index + GlowA] = min_ff(1.0f, a[index + GlowA] + b[index + GlowA]);
2331                 }
2332         }
2333 }
2334
2335 static void RVIsolateHighlights_float(
2336         float *in, float *out, int width, int height,
2337         float threshold, float boost, float clamp)
2338 {
2339         int x, y, index;
2340         float intensity;
2341
2342         for (y = 0; y < height; y++) {
2343                 for (x = 0; x < width; x++) {
2344                         index = (x + y * width) * 4;
2345
2346                         /* Isolate the intensity */
2347                         intensity = (in[index + GlowR] + in[index + GlowG] + in[index + GlowB] - threshold);
2348                         if (intensity > 0) {
2349                                 out[index + GlowR] = min_ff(clamp, (in[index + GlowR] * boost * intensity));
2350                                 out[index + GlowG] = min_ff(clamp, (in[index + GlowG] * boost * intensity));
2351                                 out[index + GlowB] = min_ff(clamp, (in[index + GlowB] * boost * intensity));
2352                                 out[index + GlowA] = min_ff(clamp, (in[index + GlowA] * boost * intensity));
2353                         }
2354                         else {
2355                                 out[index + GlowR] = 0;
2356                                 out[index + GlowG] = 0;
2357                                 out[index + GlowB] = 0;
2358                                 out[index + GlowA] = 0;
2359                         }
2360                 }
2361         }
2362 }
2363
2364 static void init_glow_effect(Sequence *seq)
2365 {
2366         GlowVars *glow;
2367
2368         if (seq->effectdata)
2369                 MEM_freeN(seq->effectdata);
2370
2371         seq->effectdata = MEM_callocN(sizeof(GlowVars), "glowvars");
2372
2373         glow = (GlowVars *)seq->effectdata;
2374         glow->fMini = 0.25;
2375         glow->fClamp = 1.0;
2376         glow->fBoost = 0.5;
2377         glow->dDist = 3.0;
2378         glow->dQuality = 3;
2379         glow->bNoComp = 0;
2380 }
2381
2382 static int num_inputs_glow(void)
2383 {
2384         return 1;
2385 }
2386
2387 static void free_glow_effect(Sequence *seq)
2388 {
2389         if (seq->effectdata)
2390                 MEM_freeN(seq->effectdata);
2391
2392         seq->effectdata = NULL;
2393 }
2394
2395 static void copy_glow_effect(Sequence *dst, Sequence *src)
2396 {
2397         dst->effectdata = MEM_dupallocN(src->effectdata);
2398 }
2399
2400 static void do_glow_effect_byte(
2401         Sequence *seq, int render_size, float facf0, float UNUSED(facf1), int x, int y,
2402         unsigned char *rect1, unsigned char *UNUSED(rect2), unsigned char *out)
2403 {
2404         float *outbuf, *inbuf;
2405         GlowVars *glow = (GlowVars *)seq->effectdata;
2406
2407         inbuf = MEM_mallocN(4 * sizeof(float) * x * y, "glow effect input");
2408         outbuf = MEM_mallocN(4 * sizeof(float) * x * y, "glow effect output");
2409
2410         IMB_buffer_float_from_byte(inbuf, rect1, IB_PROFILE_SRGB, IB_PROFILE_SRGB, false, x, y, x, x);
2411         IMB_buffer_float_premultiply(inbuf, x, y);
2412
2413         RVIsolateHighlights_float(inbuf, outbuf, x, y, glow->fMini * 3.0f, glow->fBoost * facf0, glow->fClamp);
2414         RVBlurBitmap2_float(outbuf, x, y, glow->dDist * (render_size / 100.0f), glow->dQuality);
2415         if (!glow->bNoComp)
2416                 RVAddBitmaps_float(inbuf, outbuf, outbuf, x, y);
2417
2418         IMB_buffer_float_unpremultiply(outbuf, x, y);
2419         IMB_buffer_byte_from_float(out, outbuf, 4, 0.0f, IB_PROFILE_SRGB, IB_PROFILE_SRGB, false, x, y, x, x);
2420
2421         MEM_freeN(inbuf);
2422         MEM_freeN(outbuf);
2423 }
2424
2425 static void do_glow_effect_float(
2426         Sequence *seq, int render_size, float facf0, float UNUSED(facf1), int x, int y,
2427         float *rect1, float *UNUSED(rect2), float *out)
2428 {
2429         float *outbuf = out;
2430         float *inbuf = rect1;
2431         GlowVars *glow = (GlowVars *)seq->effectdata;
2432
2433         RVIsolateHighlights_float(inbuf, outbuf, x, y, glow->fMini * 3.0f, glow->fBoost * facf0, glow->fClamp);
2434         RVBlurBitmap2_float(outbuf, x, y, glow->dDist * (render_size / 100.0f), glow->dQuality);
2435         if (!glow->bNoComp)
2436                 RVAddBitmaps_float(inbuf, outbuf, outbuf, x, y);
2437 }
2438
2439 static ImBuf *do_glow_effect(
2440         const SeqRenderData *context, Sequence *seq, float UNUSED(cfra), float facf0, float facf1,
2441         ImBuf *ibuf1, ImBuf *ibuf2, ImBuf *ibuf3)
2442 {
2443         ImBuf *out = prepare_effect_imbufs(context, ibuf1, ibuf2, ibuf3);
2444
2445         int render_size = 100 * context->rectx / context->scene->r.xsch;
2446
2447         if (out->rect_float) {
2448                 do_glow_effect_float(
2449                         seq, render_size, facf0, facf1, context->rectx, context->recty,
2450                         ibuf1->rect_float, ibuf2->rect_float, out->rect_float);
2451         }
2452         else {
2453                 do_glow_effect_byte(
2454                         seq, render_size, facf0, facf1, context->rectx, context->recty,
2455                         (unsigned char *) ibuf1->rect, (unsigned char *) ibuf2->rect, (unsigned char *) out->rect);
2456         }
2457
2458         return out;
2459 }
2460
2461 /*********************** Solid color *************************/
2462
2463 static void init_solid_color(Sequence *seq)
2464 {
2465         SolidColorVars *cv;
2466
2467         if (seq->effectdata)
2468                 MEM_freeN(seq->effectdata);
2469
2470         seq->effectdata = MEM_callocN(sizeof(SolidColorVars), "solidcolor");
2471
2472         cv = (SolidColorVars *)seq->effectdata;
2473         cv->col[0] = cv->col[1] = cv->col[2] = 0.5;
2474 }
2475
2476 static int num_inputs_color(void)
2477 {
2478         return 0;
2479 }
2480
2481 static void free_solid_color(Sequence *seq)
2482 {
2483         if (seq->effectdata)
2484                 MEM_freeN(seq->effectdata);
2485
2486         seq->effectdata = NULL;
2487 }
2488
2489 static void copy_solid_color(Sequence *dst, Sequence *src)
2490 {
2491         dst->effectdata = MEM_dupallocN(src->effectdata);
2492 }
2493
2494 static int early_out_color(Sequence *UNUSED(seq), float UNUSED(facf0), float UNUSED(facf1))
2495 {
2496         return EARLY_NO_INPUT;
2497 }
2498
2499 static ImBuf *do_solid_color(
2500         const SeqRenderData *context, Sequence *seq, float UNUSED(cfra), float facf0, float facf1,
2501         ImBuf *ibuf1, ImBuf *ibuf2, ImBuf *ibuf3)
2502 {
2503         ImBuf *out = prepare_effect_imbufs(context, ibuf1, ibuf2, ibuf3);
2504
2505         SolidColorVars *cv = (SolidColorVars *)seq->effectdata;
2506
2507         unsigned char *rect;
2508         float *rect_float;
2509         int x; /*= context->rectx;*/ /*UNUSED*/
2510         int y; /*= context->recty;*/ /*UNUSED*/
2511
2512         if (out->rect) {
2513                 unsigned char col0[3];
2514                 unsigned char col1[3];
2515
2516                 col0[0] = facf0 * cv->col[0] * 255;
2517                 col0[1] = facf0 * cv->col[1] * 255;
2518                 col0[2] = facf0 * cv->col[2] * 255;
2519
2520                 col1[0] = facf1 * cv->col[0] * 255;
2521                 col1[1] = facf1 * cv->col[1] * 255;
2522                 col1[2] = facf1 * cv->col[2] * 255;
2523
2524                 rect = (unsigned char *)out->rect;
2525
2526                 for (y = 0; y < out->y; y++) {
2527                         for (x = 0; x < out->x; x++, rect += 4) {
2528                                 rect[0] = col0[0];
2529                                 rect[1] = col0[1];
2530                                 rect[2] = col0[2];
2531                                 rect[3] = 255;
2532                         }
2533                         y++;
2534                         if (y < out->y) {
2535                                 for (x = 0; x < out->x; x++, rect += 4) {
2536                                         rect[0] = col1[0];
2537                                         rect[1] = col1[1];
2538                                         rect[2] = col1[2];
2539                                         rect[3] = 255;
2540                                 }
2541                         }
2542                 }
2543
2544         }
2545         else if (out->rect_float) {
2546                 float col0[3];
2547                 float col1[3];
2548
2549                 col0[0] = facf0 * cv->col[0];
2550                 col0[1] = facf0 * cv->col[1];
2551                 col0[2] = facf0 * cv->col[2];
2552
2553                 col1[0] = facf1 * cv->col[0];
2554                 col1[1] = facf1 * cv->col[1];
2555                 col1[2] = facf1 * cv->col[2];
2556
2557                 rect_float = out->rect_float;
2558
2559                 for (y = 0; y < out->y; y++) {
2560                         for (x = 0; x < out->x; x++, rect_float += 4) {
2561                                 rect_float[0] = col0[0];
2562                                 rect_float[1] = col0[1];
2563                                 rect_float[2] = col0[2];
2564                                 rect_float[3] = 1.0;
2565                         }
2566                         y++;
2567                         if (y < out->y) {
2568                                 for (x = 0; x < out->x; x++, rect_float += 4) {
2569                                         rect_float[0] = col1[0];
2570                                         rect_float[1] = col1[1];
2571                                         rect_float[2] = col1[2];
2572                                         rect_float[3] = 1.0;
2573                                 }
2574                         }
2575                 }
2576         }
2577         return out;
2578 }
2579
2580 /*********************** Mulitcam *************************/
2581
2582 /* no effect inputs for multicam, we use give_ibuf_seq */
2583 static int num_inputs_multicam(void)
2584 {
2585         return 0;
2586 }
2587
2588 static int early_out_multicam(Sequence *UNUSED(seq), float UNUSED(facf0), float UNUSED(facf1))
2589 {
2590         return EARLY_NO_INPUT;
2591 }
2592
2593 static ImBuf *do_multicam(
2594         const SeqRenderData *context, Sequence *seq, float cfra, float UNUSED(facf0), float UNUSED(facf1),
2595         ImBuf *UNUSED(ibuf1), ImBuf *UNUSED(ibuf2), ImBuf *UNUSED(ibuf3))
2596 {
2597         ImBuf *i;
2598         ImBuf *out;
2599         Editing *ed;
2600         ListBase *seqbasep;
2601
2602         if (seq->multicam_source == 0 || seq->multicam_source >= seq->machine) {
2603                 return NULL;
2604         }
2605
2606         ed = context->scene->ed;
2607         if (!ed) {
2608                 return NULL;
2609         }
2610         seqbasep = BKE_sequence_seqbase(&ed->seqbase, seq);
2611         if (!seqbasep) {
2612                 return NULL;
2613         }
2614
2615         i = BKE_sequencer_give_ibuf_seqbase(context, cfra, seq->multicam_source, seqbasep);
2616         if (!i) {
2617                 return NULL;
2618         }
2619
2620         if (BKE_sequencer_input_have_to_preprocess(context, seq, cfra)) {
2621                 out = IMB_dupImBuf(i);
2622                 IMB_freeImBuf(i);
2623         }
2624         else {
2625                 out = i;
2626         }
2627
2628         return out;
2629 }
2630
2631 /*********************** Adjustment *************************/
2632
2633 /* no effect inputs for adjustment, we use give_ibuf_seq */
2634 static int num_inputs_adjustment(void)
2635 {
2636         return 0;
2637 }
2638
2639 static int early_out_adjustment(Sequence *UNUSED(seq), float UNUSED(facf0), float UNUSED(facf1))
2640 {
2641         return EARLY_NO_INPUT;
2642 }
2643
2644 static ImBuf *do_adjustment_impl(const SeqRenderData *context, Sequence *seq, float cfra)
2645 {
2646         Editing *ed;
2647         ListBase *seqbasep;
2648         ImBuf *i = NULL;
2649
2650         ed = context->scene->ed;
2651
2652         seqbasep = BKE_sequence_seqbase(&ed->seqbase, seq);
2653
2654         if (seq->machine > 1) {
2655                 i = BKE_sequencer_give_ibuf_seqbase(context, cfra, seq->machine - 1, seqbasep);
2656         }
2657
2658         /* found nothing? so let's work the way up the metastrip stack, so
2659          * that it is possible to group a bunch of adjustment strips into
2660          * a metastrip and have that work on everything below the metastrip
2661          */
2662
2663         if (!i) {
2664                 Sequence *meta;
2665
2666                 meta = BKE_sequence_metastrip(&ed->seqbase, NULL, seq);
2667
2668                 if (meta) {
2669                         i = do_adjustment_impl(context, meta, cfra);
2670                 }
2671         }
2672
2673         return i;
2674 }
2675
2676 static ImBuf *do_adjustment(
2677         const SeqRenderData *context, Sequence *seq, float cfra, float UNUSED(facf0), float UNUSED(facf1),
2678         ImBuf *UNUSED(ibuf1), ImBuf *UNUSED(ibuf2), ImBuf *UNUSED(ibuf3))
2679 {
2680         ImBuf *i = NULL;
2681         ImBuf *out;
2682         Editing *ed;
2683
2684         ed = context->scene->ed;
2685
2686         if (!ed) {
2687                 return NULL;
2688         }
2689
2690         i = do_adjustment_impl(context, seq, cfra);
2691
2692         if (BKE_sequencer_input_have_to_preprocess(context, seq, cfra)) {
2693                 out = IMB_dupImBuf(i);
2694                 if (out) {
2695                         IMB_metadata_copy(out, i);
2696                 }
2697                 IMB_freeImBuf(i);
2698         }
2699         else {
2700                 out = i;
2701         }
2702
2703         return out;
2704 }
2705
2706 /*********************** Speed *************************/
2707
2708 static void init_speed_effect(Sequence *seq)
2709 {
2710         SpeedControlVars *v;
2711
2712         if (seq->effectdata)
2713                 MEM_freeN(seq->effectdata);
2714
2715         seq->effectdata = MEM_callocN(sizeof(SpeedControlVars), "speedcontrolvars");
2716
2717         v = (SpeedControlVars *)seq->effectdata;
2718         v->globalSpeed = 1.0;
2719         v->frameMap = NULL;
2720         v->flags |= SEQ_SPEED_INTEGRATE; /* should be default behavior */
2721         v->length = 0;
2722 }
2723
2724 static void load_speed_effect(Sequence *seq)
2725 {
2726         SpeedControlVars *v = (SpeedControlVars *)seq->effectdata;
2727
2728         v->frameMap = NULL;
2729         v->length = 0;
2730 }
2731
2732 static int num_inputs_speed(void)
2733 {
2734         return 1;
2735 }
2736
2737 static void free_speed_effect(Sequence *seq)
2738 {
2739         SpeedControlVars *v = (SpeedControlVars *)seq->effectdata;
2740         if (v->frameMap)
2741                 MEM_freeN(v->frameMap);
2742         if (seq->effectdata)
2743                 MEM_freeN(seq->effectdata);
2744         seq->effectdata = NULL;
2745 }
2746
2747 static void copy_speed_effect(Sequence *dst, Sequence *src)
2748 {
2749         SpeedControlVars *v;
2750         dst->effectdata = MEM_dupallocN(src->effectdata);
2751         v = (SpeedControlVars *)dst->effectdata;
2752         v->frameMap = NULL;
2753         v->length = 0;
2754 }
2755
2756 static int early_out_speed(Sequence *UNUSED(seq), float UNUSED(facf0), float UNUSED(facf1))
2757 {
2758         return EARLY_USE_INPUT_1;
2759 }
2760
2761 static void store_icu_yrange_speed(Sequence *seq, short UNUSED(adrcode), float *ymin, float *ymax)
2762 {
2763         SpeedControlVars *v = (SpeedControlVars *)seq->effectdata;
2764
2765         /* if not already done, load / initialize data */
2766         BKE_sequence_get_effect(seq);
2767
2768         if ((v->flags & SEQ_SPEED_INTEGRATE) != 0) {
2769                 *ymin = -100.0;
2770                 *ymax = 100.0;
2771         }
2772         else {
2773                 if (v->flags & SEQ_SPEED_COMPRESS_IPO_Y) {
2774                         *ymin = 0.0;
2775                         *ymax = 1.0;
2776                 }
2777                 else {
2778                         *ymin = 0.0;
2779                         *ymax = seq->len;
2780                 }
2781         }
2782 }
2783
2784 void BKE_sequence_effect_speed_rebuild_map(Scene *scene, Sequence *seq, bool force)
2785 {
2786         int cfra;
2787         float fallback_fac = 1.0f;
2788         SpeedControlVars *v = (SpeedControlVars *) seq->effectdata;
2789         FCurve *fcu = NULL;
2790         int flags = v->flags;
2791
2792         /* if not already done, load / initialize data */
2793         BKE_sequence_get_effect(seq);
2794
2795         if ((force == false) &&
2796             (seq->len == v->length) &&
2797             (v->frameMap != NULL))
2798         {
2799                 return;
2800         }
2801         if ((seq->seq1 == NULL) || (seq->len < 1)) {
2802                 /* make coverity happy and check for (CID 598) input strip ... */
2803                 return;
2804         }
2805
2806         /* XXX - new in 2.5x. should we use the animation system this way?
2807          * The fcurve is needed because many frames need evaluating at once - campbell */
2808         fcu = id_data_find_fcurve(&scene->id, seq, &RNA_Sequence, "speed_factor", 0, NULL);
2809
2810
2811         if (!v->frameMap || v->length != seq->len) {
2812                 if (v->frameMap) MEM_freeN(v->frameMap);
2813
2814                 v->length = seq->len;
2815
2816                 v->frameMap = MEM_callocN(sizeof(float) * v->length, "speedcontrol frameMap");
2817         }
2818
2819         fallback_fac = 1.0;
2820
2821         if (seq->flag & SEQ_USE_EFFECT_DEFAULT_FADE) {
2822                 if ((seq->seq1->enddisp != seq->seq1->start) &&
2823                     (seq->seq1->len != 0))
2824                 {
2825                         fallback_fac = (float) seq->seq1->len / (float) (seq->seq1->enddisp - seq->seq1->start);
2826                         flags = SEQ_SPEED_INTEGRATE;
2827                         fcu = NULL;
2828                 }
2829         }
2830         else {
2831                 /* if there is no fcurve, use value as simple multiplier */
2832                 if (!fcu) {
2833                         fallback_fac = seq->speed_fader; /* same as speed_factor in rna*/
2834                 }
2835         }
2836
2837         if (flags & SEQ_SPEED_INTEGRATE) {
2838                 float cursor = 0;
2839                 float facf;
2840
2841                 v->frameMap[0] = 0;
2842                 v->lastValidFrame = 0;
2843
2844                 for (cfra = 1; cfra < v->length; cfra++) {
2845                         if (fcu) {
2846                                 facf = evaluate_fcurve(fcu, seq->startdisp + cfra);
2847                         }
2848                         else {
2849                                 facf = fallback_fac;
2850                         }
2851                         facf *= v->globalSpeed;
2852
2853                         cursor += facf;
2854
2855                         if (cursor >= seq->seq1->len) {
2856                                 v->frameMap[cfra] = seq->seq1->len - 1;
2857                         }
2858                         else {
2859                                 v->frameMap[cfra] = cursor;
2860                                 v->lastValidFrame = cfra;
2861                         }
2862                 }
2863         }
2864         else {
2865                 float facf;
2866
2867                 v->lastValidFrame = 0;
2868                 for (cfra = 0; cfra < v->length; cfra++) {
2869
2870                         if (fcu) {
2871                                 facf = evaluate_fcurve(fcu, seq->startdisp + cfra);
2872                         }
2873                         else {
2874                                 facf = fallback_fac;
2875                         }
2876
2877                         if (flags & SEQ_SPEED_COMPRESS_IPO_Y) {
2878                                 facf *= seq->seq1->len;
2879                         }
2880                         facf *= v->globalSpeed;
2881
2882                         if (facf >= seq->seq1->len) {
2883                                 facf = seq->seq1->len - 1;
2884                         }
2885                         else {
2886                                 v->lastValidFrame = cfra;
2887                         }
2888                         v->frameMap[cfra] = facf;
2889                 }
2890         }
2891 }
2892
2893 static ImBuf *do_speed_effect(
2894         const SeqRenderData *context, Sequence *UNUSED(seq), float UNUSED(cfra),
2895         float facf0, float facf1, ImBuf *ibuf1, ImBuf *ibuf2, ImBuf *ibuf3)
2896 {
2897         ImBuf *out = prepare_effect_imbufs(context, ibuf1, ibuf2, ibuf3);
2898
2899         if (out->rect_float) {
2900                 do_cross_effect_float(
2901                         facf0, facf1, context->rectx, context->recty,
2902                         ibuf1->rect_float, ibuf2->rect_float, out->rect_float);
2903         }
2904         else {
2905                 do_cross_effect_byte(
2906                         facf0, facf1, context->rectx, context->recty,
2907                         (unsigned char *) ibuf1->rect, (unsigned char *) ibuf2->rect, (unsigned char *) out->rect);
2908         }
2909         return out;
2910 }
2911
2912 /*********************** overdrop *************************/
2913
2914 static void do_overdrop_effect(
2915         const SeqRenderData *context, Sequence *UNUSED(seq), float UNUSED(cfra), float facf0, float facf1,
2916         ImBuf *ibuf1, ImBuf *ibuf2, ImBuf *UNUSED(ibuf3), int start_line, int total_lines, ImBuf *out)
2917 {
2918         int x = context->rectx;
2919         int y = total_lines;
2920
2921         if (out->rect_float) {
2922                 float *rect1 = NULL, *rect2 = NULL, *rect_out = NULL;
2923
2924                 slice_get_float_buffers(context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
2925
2926                 do_drop_effect_float(facf0, facf1, x, y, rect1, rect2, rect_out);
2927                 do_alphaover_effect_float(facf0, facf1, x, y, rect1, rect2, rect_out);
2928         }
2929         else {
2930                 unsigned char *rect1 = NULL, *rect2 = NULL, *rect_out = NULL;
2931
2932                 slice_get_byte_buffers(context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
2933
2934                 do_drop_effect_byte(facf0, facf1, x, y, rect1, rect2, rect_out);
2935                 do_alphaover_effect_byte(facf0, facf1, x, y, rect1, rect2, rect_out);
2936         }
2937 }
2938
2939 /*********************** Gaussian Blur *************************/
2940
2941 /* NOTE: This gaussian blur implementation accumulates values in the square
2942  * kernel rather that doing X direction and then Y direction because of the
2943  * lack of using multiple-staged filters.
2944  *
2945  * Once we can we'll implement a way to apply filter as multiple stages we
2946  * can optimize hell of a lot in here.
2947  */
2948
2949 static void init_gaussian_blur_effect(Sequence *seq)
2950 {
2951         if (seq->effectdata)
2952                 MEM_freeN(seq->effectdata);
2953
2954         seq->effectdata = MEM_callocN(sizeof(WipeVars), "wipevars");
2955 }
2956
2957 static int num_inputs_gaussian_blur(void)
2958 {
2959         return 1;
2960 }
2961
2962 static void free_gaussian_blur_effect(Sequence *seq)
2963 {
2964         if (seq->effectdata)
2965                 MEM_freeN(seq->effectdata);
2966
2967         seq->effectdata = NULL;
2968 }
2969
2970 static void copy_gaussian_blur_effect(Sequence *dst, Sequence *src)
2971 {
2972         dst->effectdata = MEM_dupallocN(src->effectdata);
2973 }
2974
2975 static int early_out_gaussian_blur(Sequence *seq, float UNUSED(facf0), float UNUSED(facf1))
2976 {
2977         GaussianBlurVars *data = seq->effectdata;
2978         if (data->size_x == 0.0f && data->size_y == 0) {
2979                 return EARLY_USE_INPUT_1;
2980         }
2981         return EARLY_DO_EFFECT;
2982 }
2983
2984 /* TODO(sergey): De-duplicate with compositor. */
2985 static float *make_gaussian_blur_kernel(float rad, int size)
2986 {
2987         float *gausstab, sum, val;
2988         float fac;
2989         int i, n;
2990
2991         n = 2 * size + 1;
2992
2993         gausstab = (float *)MEM_mallocN(sizeof(float) * n, __func__);
2994
2995         sum = 0.0f;
2996         fac = (rad > 0.0f ? 1.0f / rad : 0.0f);
2997         for (i = -size; i <= size; i++) {
2998                 val = RE_filter_value(R_FILTER_GAUSS, (float)i * fac);
2999                 sum += val;
3000                 gausstab[i + size] = val;
3001         }
3002
3003         sum = 1.0f / sum;
3004         for (i = 0; i < n; i++)
3005                 gausstab[i] *= sum;
3006
3007         return gausstab;
3008 }
3009
3010 static void do_gaussian_blur_effect_byte_x(
3011         Sequence *seq,
3012         int start_line,
3013         int x, int y,
3014         int frame_width,
3015         int UNUSED(frame_height),
3016         unsigned char *rect,
3017         unsigned char *out)
3018 {
3019 #define INDEX(_x, _y) (((_y) * (x) + (_x)) * 4)
3020         GaussianBlurVars *data = seq->effectdata;
3021         const int size_x = (int) (data->size_x + 0.5f);
3022         int i, j;
3023
3024         /* Make gaussian weight table. */
3025         float *gausstab_x;
3026         gausstab_x = make_gaussian_blur_kernel(data->size_x, size_x);
3027
3028         for (i = 0; i < y; ++i) {
3029                 for (j = 0; j < x; ++j) {
3030                         int out_index = INDEX(j, i);
3031                         float accum[4] = {0.0f, 0.0f, 0.0f, 0.0f};
3032                         float accum_weight = 0.0f;
3033
3034                         for (int current_x = j - size_x;
3035                              current_x <= j + size_x;
3036                              ++current_x)
3037                         {
3038                                 if (current_x < 0 || current_x >= frame_width) {
3039                                         /* Out of bounds. */
3040                                         continue;
3041                                 }
3042                                 int index = INDEX(current_x, i + start_line);
3043                                 float weight = gausstab_x[current_x - j + size_x];
3044                                 accum[0] += rect[index] * weight;
3045                                 accum[1] += rect[index + 1] * weight;
3046                                 accum[2] += rect[index + 2] * weight;
3047                                 accum[3] += rect[index + 3] * weight;
3048                                 accum_weight += weight;
3049                         }
3050
3051                         float inv_accum_weight = 1.0f / accum_weight;
3052                         out[out_index + 0] = accum[0] * inv_accum_weight;
3053                         out[out_index + 1] = accum[1] * inv_accum_weight;
3054                         out[out_index + 2] = accum[2] * inv_accum_weight;
3055                         out[out_index + 3] = accum[3] * inv_accum_weight;
3056                 }
3057         }
3058
3059         MEM_freeN(gausstab_x);
3060 #undef INDEX
3061 }
3062
3063 static void do_gaussian_blur_effect_byte_y(
3064         Sequence *seq,
3065         int start_line,
3066         int x, int y,
3067         int UNUSED(frame_width),
3068         int frame_height,
3069         unsigned char *rect,
3070         unsigned char *out)
3071 {
3072 #define INDEX(_x, _y) (((_y) * (x) + (_x)) * 4)
3073         GaussianBlurVars *data = seq->effectdata;
3074         const int size_y = (int) (data->size_y + 0.5f);
3075         int i, j;
3076
3077         /* Make gaussian weight table. */
3078         float *gausstab_y;
3079         gausstab_y = make_gaussian_blur_kernel(data->size_y, size_y);
3080
3081         for (i = 0; i < y; ++i) {
3082                 for (j = 0; j < x; ++j) {
3083                         int out_index = INDEX(j, i);
3084                         float accum[4] = {0.0f, 0.0f, 0.0f, 0.0f};
3085                         float accum_weight = 0.0f;
3086                         for (int current_y = i - size_y;
3087                              current_y <= i + size_y;
3088                              ++current_y)
3089                         {
3090                                 if (current_y < -start_line ||
3091                                     current_y + start_line >= frame_height)
3092                                 {
3093                                         /* Out of bounds. */
3094                                         continue;
3095                                 }
3096                                 int index = INDEX(j, current_y + start_line);
3097                                 float weight = gausstab_y[current_y - i + size_y];
3098                                 accum[0] += rect[index] * weight;
3099                                 accum[1] += rect[index + 1] * weight;
3100                                 accum[2] += rect[index + 2] * weight;
3101                                 accum[3] += rect[index + 3] * weight;
3102                                 accum_weight += weight;
3103                         }
3104                         float inv_accum_weight = 1.0f / accum_weight;
3105                         out[out_index + 0] = accum[0] * inv_accum_weight;
3106                         out[out_index + 1] = accum[1] * inv_accum_weight;
3107                         out[out_index + 2] = accum[2] * inv_accum_weight;
3108                         out[out_index + 3] = accum[3] * inv_accum_weight;
3109                 }
3110         }
3111
3112         MEM_freeN(gausstab_y);
3113 #undef INDEX
3114 }
3115
3116 static void do_gaussian_blur_effect_float_x(
3117         Sequence *seq,
3118         int start_line,
3119         int x, int y,
3120         int frame_width,
3121         int UNUSED(frame_height),
3122         float *rect,
3123         float *out)
3124 {
3125 #define INDEX(_x, _y) (((_y) * (x) + (_x)) * 4)
3126         GaussianBlurVars *data = seq->effectdata;
3127         const int size_x = (int) (data->size_x + 0.5f);
3128         int i, j;