~ubuntu-branches/ubuntu/gutsy/blender/gutsy-security

« back to all changes in this revision

Viewing changes to source/blender/src/seqeffects.c

  • Committer: Bazaar Package Importer
  • Author(s): Lukas Fittl
  • Date: 2006-09-20 01:57:27 UTC
  • mfrom: (1.2.4 upstream)
  • Revision ID: james.westby@ubuntu.com-20060920015727-gmoqlxwstx9wwqs3
Tags: 2.42a-1ubuntu1
* Merge from Debian unstable (Closes: Malone #55903). Remaining changes:
  - debian/genpot: Add python scripts from Lee June <blender@eyou.com> to
    generate a reasonable PO template from the sources. Since gettext is used
    in a highly nonstandard way, xgettext does not work for this job.
  - debian/rules: Call the scripts, generate po/blender.pot, and clean it up
    in the clean target.
  - Add a proper header to the generated PO template.
* debian/control: Build depend on libavformat-dev >= 3:0.cvs20060823-3.1,
  otherwise this package will FTBFS

Show diffs side-by-side

added added

removed removed

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