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