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