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