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