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