2
* $Id: seqeffects.c,v 1.6 2006/06/27 10:28:00 ton Exp $
4
* ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
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
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.
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.
23
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
24
* All rights reserved.
26
* Contributor(s): Peter Schlaile <peter [at] schlaile [dot] de> 2005/2006
28
* ***** END GPL/BL DUAL LICENSE BLOCK *****
35
#include "MEM_guardedalloc.h"
36
#include "PIL_dynlib.h"
37
#include "BKE_plugin_types.h"
39
#include "IMB_imbuf_types.h"
40
#include "IMB_imbuf.h"
42
#include "DNA_sequence_types.h"
43
#include "BSE_seqeffects.h"
45
#include "BLI_blenlib.h"
46
#include "BLI_arithb.h"
48
#include "DNA_sequence_types.h"
50
#include "BKE_utildefines.h"
51
#include "BKE_global.h"
53
#include "BKE_texture.h"
54
#include "BIF_toolbox.h"
55
#include "BIF_interface.h"
57
#include "BSE_sequence.h"
59
#include "RE_pipeline.h" // talks to entire render API
72
/* **********************************************************************
74
********************************************************************** */
76
static void open_plugin_seq(PluginSeq *pis, const char *seqname)
79
void* (*alloc_private)();
82
/* to be sure: (is tested for) */
88
pis->instance_private_data = 0;
90
/* clear the error list */
91
PIL_dynlib_get_error_as_string(NULL);
93
/* if(pis->handle) PIL_dynlib_close(pis->handle); */
96
/* open the needed object */
97
pis->handle= PIL_dynlib_open(pis->name);
98
if(test_dlerr(pis->name, pis->name)) return;
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;
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");;
112
info_func= (int (*)(PluginInfo *))PIL_dynlib_find_symbol(pis->handle, "plugin_getinfo");
114
if(info_func == NULL) error("No info func");
118
pis->pname= info->name;
119
pis->vars= info->nvars;
120
pis->cfra= info->cfra;
122
pis->varstr= info->varstr;
124
pis->doit= (void(*)(void))info->seq_doit;
130
cp= PIL_dynlib_find_symbol(pis->handle, "seqname");
131
if(cp) strncpy(cp, seqname, 21);
133
printf ("Plugin returned unrecognized version number\n");
137
alloc_private = (void* (*)())PIL_dynlib_find_symbol(
138
pis->handle, "plugin_seq_alloc_private_data");
140
pis->instance_private_data = alloc_private();
143
pis->current_private_data = (void**)
144
PIL_dynlib_find_symbol(
145
pis->handle, "plugin_private_data");
149
static PluginSeq *add_plugin_seq(const char *str, const char *seqname)
155
pis= MEM_callocN(sizeof(PluginSeq), "PluginSeq");
157
strncpy(pis->name, str, FILE_MAXDIR+FILE_MAXFILE);
158
open_plugin_seq(pis, seqname);
161
if(pis->handle==0) error("no plugin: %s", str);
162
else error("in plugin: %s", str);
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;
179
static void free_plugin_seq(PluginSeq *pis)
183
/* no PIL_dynlib_close: same plugin can be opened multiple times with 1 handle */
185
if (pis->instance_private_data) {
186
void (*free_private)(void *);
188
free_private = (void (*)(void *))PIL_dynlib_find_symbol(
189
pis->handle, "plugin_seq_free_private_data");
191
free_private(pis->instance_private_data);
198
static void init_plugin(Sequence * seq, const char * fname)
200
seq->plugin= (PluginSeq *)add_plugin_seq(fname, seq->name+2);
203
static void load_plugin(Sequence * seq)
206
open_plugin_seq(seq->plugin, seq->name+2);
210
static void copy_plugin(Sequence * dst, Sequence * src)
213
dst->plugin= MEM_dupallocN(src->plugin);
214
open_plugin_seq(dst->plugin, dst->name+2);
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)
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 */
229
if(seq->plugin && seq->plugin->doit) {
230
if(seq->plugin->cfra)
231
*(seq->plugin->cfra)= frame_to_float(cfra);
233
cp = PIL_dynlib_find_symbol(
234
seq->plugin->handle, "seqname");
236
if(cp) strncpy(cp, seq->name+2, 22);
238
if (seq->plugin->current_private_data) {
239
*seq->plugin->current_private_data
240
= seq->plugin->instance_private_data;
243
float_rendering = (out->rect_float != NULL);
245
if (seq->plugin->version<=3 && float_rendering) {
249
ibuf1 = IMB_dupImBuf(ibuf1);
250
IMB_rect_from_float(ibuf1);
251
imb_freerectfloatImBuf(ibuf1);
252
ibuf1->flags &= ~IB_rectfloat;
255
ibuf2 = IMB_dupImBuf(ibuf2);
256
IMB_rect_from_float(ibuf2);
257
imb_freerectfloatImBuf(ibuf2);
258
ibuf2->flags &= ~IB_rectfloat;
261
ibuf3 = IMB_dupImBuf(ibuf3);
262
IMB_rect_from_float(ibuf3);
263
imb_freerectfloatImBuf(ibuf3);
264
ibuf3->flags &= ~IB_rectfloat;
266
if (!out->rect) imb_addrectImBuf(out);
267
imb_freerectfloatImBuf(out);
268
out->flags &= ~IB_rectfloat;
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);
277
((SeqDoit)seq->plugin->doit)(
278
seq->plugin->data, facf0, facf1, x, y,
279
ibuf1, ibuf2, out, ibuf3);
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);
287
IMB_convert_rgba_to_abgr(out);
289
if (seq->plugin->version<=3 && float_rendering) {
290
IMB_float_from_rect(out);
294
if (ibuf1) IMB_freeImBuf(ibuf1);
295
if (ibuf2) IMB_freeImBuf(ibuf2);
296
if (ibuf3) IMB_freeImBuf(ibuf3);
301
static int do_plugin_early_out(struct Sequence *seq,
302
float facf0, float facf1)
307
static void free_plugin(struct Sequence * seq)
309
free_plugin_seq(seq->plugin);
313
/* **********************************************************************
315
********************************************************************** */
317
static void init_alpha_over_or_under(Sequence * seq)
319
Sequence * seq1 = seq->seq1;
320
Sequence * seq2 = seq->seq2;
326
static void do_alphaover_effect_byte(float facf0, float facf1, int x, int y,
327
char * rect1, char *rect2, char *out)
329
int fac2, mfac, fac, fac4;
331
char *rt1, *rt2, *rt;
338
fac2= (int)(256.0*facf0);
339
fac4= (int)(256.0*facf1);
346
/* rt = rt1 over rt2 (alpha from rt1) */
349
mfac= 256 - ( (fac2*rt1[3])>>8 );
351
if(fac==0) *( (unsigned int *)rt) = *( (unsigned int *)rt2);
352
else if(mfac==0) *( (unsigned int *)rt) = *( (unsigned int *)rt1);
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;
363
rt1+= 4; rt2+= 4; rt+= 4;
373
mfac= 256 - ( (fac4*rt1[3])>>8 );
375
if(fac==0) *( (unsigned int *)rt) = *( (unsigned int *)rt2);
376
else if(mfac==0) *( (unsigned int *)rt) = *( (unsigned int *)rt1);
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;
387
rt1+= 4; rt2+= 4; rt+= 4;
392
static void do_alphaover_effect_float(float facf0, float facf1, int x, int y,
393
float * rect1, float *rect2, float *out)
395
float fac2, mfac, fac, fac4;
397
float *rt1, *rt2, *rt;
412
/* rt = rt1 over rt2 (alpha from rt1) */
415
mfac= 1.0 - (fac2*rt1[3]) ;
418
memcpy(rt, rt2, 4 * sizeof(float));
419
} else if(mfac <=0) {
420
memcpy(rt, rt1, 4 * sizeof(float));
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];
427
rt1+= 4; rt2+= 4; rt+= 4;
437
mfac= 1.0 - (fac4*rt1[3]);
440
memcpy(rt, rt2, 4 * sizeof(float));
441
} else if(mfac <= 0.0) {
442
memcpy(rt, rt1, 4 * sizeof(float));
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];
449
rt1+= 4; rt2+= 4; rt+= 4;
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)
459
if (out->rect_float) {
460
do_alphaover_effect_float(
462
ibuf1->rect_float, ibuf2->rect_float,
465
do_alphaover_effect_byte(
467
(char*) ibuf1->rect, (char*) ibuf2->rect,
473
/* **********************************************************************
475
********************************************************************** */
477
void do_alphaunder_effect_byte(
478
float facf0, float facf1, int x, int y, char *rect1,
479
char *rect2, char *out)
481
int fac2, mfac, fac, fac4;
483
char *rt1, *rt2, *rt;
490
fac2= (int)(256.0*facf0);
491
fac4= (int)(256.0*facf1);
498
/* rt = rt1 under rt2 (alpha from rt2) */
500
/* this complex optimalisation is because the
501
* 'skybuf' can be crossed in
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);
507
fac= (fac2*(256-mfac))>>8;
509
if(fac==0) *( (unsigned int *)rt) = *( (unsigned int *)rt2);
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;
517
rt1+= 4; rt2+= 4; rt+= 4;
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);
530
fac= (fac4*(256-mfac))>>8;
532
if(fac==0) *( (unsigned int *)rt) = *( (unsigned int *)rt2);
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;
540
rt1+= 4; rt2+= 4; rt+= 4;
546
static void do_alphaunder_effect_float(float facf0, float facf1, int x, int y,
547
float *rect1, float *rect2,
550
float fac2, mfac, fac, fac4;
552
float *rt1, *rt2, *rt;
567
/* rt = rt1 under rt2 (alpha from rt2) */
569
/* this complex optimalisation is because the
570
* 'skybuf' can be crossed in
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));
578
fac = fac2 * (1.0 - mfac);
581
memcpy(rt, rt2, 4 * sizeof(float));
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];
589
rt1+= 4; rt2+= 4; rt+= 4;
598
if(rt2[3]<=0 && fac4 >= 1.0) {
599
memcpy(rt, rt1, 4 * sizeof(float));
601
} else if(rt2[3]>=1.0) {
602
memcpy(rt, rt2, 4 * sizeof(float));
605
fac= fac4*(1.0-mfac);
608
memcpy(rt, rt2, 4 * sizeof(float));
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];
616
rt1+= 4; rt2+= 4; rt+= 4;
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)
626
if (out->rect_float) {
627
do_alphaunder_effect_float(
629
ibuf1->rect_float, ibuf2->rect_float,
632
do_alphaunder_effect_byte(
634
(char*) ibuf1->rect, (char*) ibuf2->rect,
640
/* **********************************************************************
642
********************************************************************** */
644
void do_cross_effect_byte(float facf0, float facf1, int x, int y,
645
char *rect1, char *rect2,
648
int fac1, fac2, fac3, fac4;
650
char *rt1, *rt2, *rt;
657
fac2= (int)(256.0*facf0);
659
fac4= (int)(256.0*facf1);
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;
672
rt1+= 4; rt2+= 4; rt+= 4;
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;
686
rt1+= 4; rt2+= 4; rt+= 4;
692
void do_cross_effect_float(float facf0, float facf1, int x, int y,
693
float *rect1, float *rect2, float *out)
695
float fac1, fac2, fac3, fac4;
697
float *rt1, *rt2, *rt;
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];
719
rt1+= 4; rt2+= 4; rt+= 4;
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];
733
rt1+= 4; rt2+= 4; rt+= 4;
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)
744
if (out->rect_float) {
745
do_cross_effect_float(
747
ibuf1->rect_float, ibuf2->rect_float,
750
do_cross_effect_byte(
752
(char*) ibuf1->rect, (char*) ibuf2->rect,
758
/* **********************************************************************
760
********************************************************************** */
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;
767
#define RE_GAMMA_TABLE_SIZE 400
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;
779
static void makeGammaTables(float gamma)
781
/* we need two tables: one forward, one backward */
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;
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],
794
inv_gamma_range_table[i] = pow(colour_domain_table[i],
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;
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]) ;
815
} /* end of void makeGammaTables(float gamma) */
818
static float gammaCorrect(float c)
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]);
834
} /* end of float gammaCorrect(float col) */
836
/* ------------------------------------------------------------------------- */
838
static float invGammaCorrect(float col)
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]);
851
} /* end of float invGammaCorrect(float col) */
854
static void gamtabs(float gamma)
856
float val, igamma= 1.0f/gamma;
859
gamtab= MEM_mallocN(65536*sizeof(short), "initGaus2");
860
igamtab1= MEM_mallocN(256*sizeof(short), "initGaus2");
862
/* gamtab: in short, out short */
863
for(a=0; a<65536; a++) {
867
if(gamma==2.0) val= sqrt(val);
868
else if(gamma!=1.0) val= pow(val, igamma);
870
gamtab[a]= (65535.99*val);
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;
878
igamtab1[a-1]= (65535.0*pow(val, gamma)) -1 ;
884
static void alloc_or_ref_gammatabs()
886
if (gamma_tabs_refcount == 0) {
888
makeGammaTables(2.0f);
890
gamma_tabs_refcount++;
893
static void init_gammacross(Sequence * seq)
895
alloc_or_ref_gammatabs();
898
static void load_gammacross(Sequence * seq)
900
alloc_or_ref_gammatabs();
903
static void free_gammacross(Sequence * seq)
905
if (--gamma_tabs_refcount == 0) {
911
if (gamma_tabs_refcount < 0) {
912
fprintf(stderr, "seqeffects: free_gammacross double free!\n");
916
static void do_gammacross_effect_byte(float facf0, float facf1,
924
char *rt1, *rt2, *rt;
931
fac2= (int)(256.0*facf0);
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];
948
rt1+= 4; rt2+= 4; rt+= 4;
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];
966
rt1+= 4; rt2+= 4; rt+= 4;
972
static void do_gammacross_effect_float(float facf0, float facf1,
974
float *rect1, float *rect2,
977
float fac1, fac2, col;
979
float *rt1, *rt2, *rt;
995
fac1 * invGammaCorrect(*rt1)
996
+ fac2 * invGammaCorrect(*rt2));
1007
fac1*invGammaCorrect(*rt1)
1008
+ fac2*invGammaCorrect(*rt2));
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)
1020
if (out->rect_float) {
1021
do_gammacross_effect_float(
1023
ibuf1->rect_float, ibuf2->rect_float,
1026
do_gammacross_effect_byte(
1028
(char*) ibuf1->rect, (char*) ibuf2->rect,
1034
/* **********************************************************************
1036
********************************************************************** */
1038
static void do_add_effect_byte(float facf0, float facf1, int x, int y,
1039
unsigned char *rect1, unsigned char *rect2,
1042
int col, xo, fac1, fac3;
1043
char *rt1, *rt2, *rt;
1050
fac1= (int)(256.0*facf0);
1051
fac3= (int)(256.0*facf1);
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;
1067
rt1+= 4; rt2+= 4; rt+= 4;
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;
1085
rt1+= 4; rt2+= 4; rt+= 4;
1090
static void do_add_effect_float(float facf0, float facf1, int x, int y,
1091
float *rect1, float *rect2,
1096
float *rt1, *rt2, *rt;
1110
*rt = *rt1 + fac1 * (*rt2);
1120
*rt = *rt1 + fac3 * (*rt2);
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)
1132
if (out->rect_float) {
1133
do_add_effect_float(
1135
ibuf1->rect_float, ibuf2->rect_float,
1140
(char*) ibuf1->rect, (char*) ibuf2->rect,
1146
/* **********************************************************************
1148
********************************************************************** */
1150
static void do_sub_effect_byte(float facf0, float facf1,
1152
char *rect1, char *rect2, char *out)
1154
int col, xo, fac1, fac3;
1155
char *rt1, *rt2, *rt;
1162
fac1= (int)(256.0*facf0);
1163
fac3= (int)(256.0*facf1);
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;
1179
rt1+= 4; rt2+= 4; rt+= 4;
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;
1197
rt1+= 4; rt2+= 4; rt+= 4;
1202
static void do_sub_effect_float(float facf0, float facf1, int x, int y,
1203
float *rect1, float *rect2,
1208
float *rt1, *rt2, *rt;
1222
*rt = *rt1 - fac1 * (*rt2);
1232
*rt = *rt1 - fac3 * (*rt2);
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)
1244
if (out->rect_float) {
1245
do_sub_effect_float(
1247
ibuf1->rect_float, ibuf2->rect_float,
1252
(char*) ibuf1->rect, (char*) ibuf2->rect,
1257
/* **********************************************************************
1259
********************************************************************** */
1261
/* Must be > 0 or add precopy, etc to the function */
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)
1269
int height, width, temp, fac, fac1, fac2;
1270
char *rt1, *rt2, *out;
1276
fac1= (int)(70.0*facf0);
1277
fac2= (int)(70.0*facf1);
1279
rt2= (char*) (rect2i + YOFF*width);
1280
rt1= (char*) rect1i;
1282
for (y=0; y<height-YOFF; y++) {
1283
if(field) fac= fac1;
1287
memcpy(out, rt1, sizeof(int)*XOFF);
1291
for (x=XOFF; x<width; x++) {
1292
temp= ((fac*rt2[3])>>8);
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++;
1302
memcpy(out, rt1, sizeof(int)*YOFF*width);
1305
static void do_drop_effect_float(float facf0, float facf1, int x, int y,
1306
float *rect2i, float *rect1i,
1310
float temp, fac, fac1, fac2;
1311
float *rt1, *rt2, *out;
1320
rt2= (rect2i + YOFF*width);
1323
for (y=0; y<height-YOFF; y++) {
1324
if(field) fac= fac1;
1328
memcpy(out, rt1, 4 * sizeof(float)*XOFF);
1332
for (x=XOFF; x<width; x++) {
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++;
1343
memcpy(out, rt1, 4 * sizeof(float)*YOFF*width);
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,
1353
if (out->rect_float) {
1354
do_drop_effect_float(
1356
ibuf1->rect_float, ibuf2->rect_float,
1359
do_drop_effect_byte(
1361
(char*) ibuf1->rect, (char*) ibuf2->rect,
1366
/* **********************************************************************
1368
********************************************************************** */
1370
static void do_mul_effect_byte(float facf0, float facf1, int x, int y,
1371
unsigned char *rect1, unsigned char *rect2,
1375
char *rt1, *rt2, *rt;
1382
fac1= (int)(256.0*facf0);
1383
fac3= (int)(256.0*facf1);
1386
* fac*(a*b) + (1-fac)*a => fac*a*(b-1)+a
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);
1399
rt1+= 4; rt2+= 4; rt+= 4;
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);
1413
rt1+= 4; rt2+= 4; rt+= 4;
1418
static void do_mul_effect_float(float facf0, float facf1, int x, int y,
1419
float *rect1, float *rect2,
1424
float *rt1, *rt2, *rt;
1435
* fac*(a*b) + (1-fac)*a => fac*a*(b-1)+a
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);
1448
rt1+= 4; rt2+= 4; rt+= 4;
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);
1462
rt1+= 4; rt2+= 4; rt+= 4;
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)
1472
if (out->rect_float) {
1473
do_mul_effect_float(
1475
ibuf1->rect_float, ibuf2->rect_float,
1480
(char*) ibuf1->rect, (char*) ibuf2->rect,
1485
/* **********************************************************************
1487
********************************************************************** */
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){
1492
float t1,t2,alpha,percwidth;
1496
percwidth = width * perc;
1498
percwidth = width * (1 - perc);
1503
t1 = dist / width; //percentange of width that is
1504
t2 = 1 / width; //amount of alpha per % point
1507
alpha = (t1*t2*100) + (1-perc); // add point's alpha contrib to current position in wipe
1509
alpha = (1-perc) - (t1*t2*100);
1516
static float check_zone(int x, int y, int xo, int yo,
1517
Sequence *seq, float facf0)
1519
float posx, posy,hyp,hyp2,angle,hwidth,b1,b2,b3,pointdist;
1521
float hyp3,hyp4,b4,b5
1523
float temp1,temp2,temp3,temp4; //some placeholder variables
1526
float widthf,output=0;
1527
WipeVars *wipe = (WipeVars *)seq->effectdata;
1530
angle = wipe->angle;
1535
angle = pow(fabs(angle)/45,log(xo)/log(2));
1542
posx = xo - facf0 * xo;
1543
posy = yo - facf0 * yo;
1545
switch (wipe->wipetype) {
1546
case DO_SINGLE_WIPE:
1547
width = (int)(wipe->edgeWidth*((xo+yo)/2.0));
1548
hwidth = (float)width/2.0;
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);
1561
output = in_band(width,hyp,facf0,1,1);
1563
output = in_band(width,hyp,facf0,0,1);
1567
output = in_band(width,hyp,facf0,0,1);
1569
output = in_band(width,hyp,facf0,1,1);
1574
case DO_DOUBLE_WIPE:
1575
if(!wipe->forward)facf0 = 1-facf0; // Go the other direction
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;
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);
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);
1591
if(b2 < b1 && b2 < b3 ){
1592
if(hwidth < pointdist)
1593
output = in_band(hwidth,hyp,facf0,0,1);
1595
else if(b2 > b1 && b2 > b3 ){
1596
if(hwidth < pointdist)
1597
output = in_band(hwidth,hyp2,facf0,0,1);
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);
1605
output = in_band(hwidth,hyp2,facf0,1,1) * in_band(hwidth,hyp,facf0,1,1);
1607
if(!wipe->forward)output = 1-output;
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
1617
widthf = wipe->edgeWidth*2*3.14159;
1618
temp1 = 2 * 3.14159 * facf0;
1621
temp1 = 2*3.14159-temp1;
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)
1632
else if(x >= 0 && y <= 0)
1633
temp2 = 2*3.14159 - temp2;
1636
temp3 = temp1-(widthf/2)*facf0;
1637
temp4 = temp1+(widthf/2)*(1-facf0);
1640
temp3 = temp1-(widthf/2)*(1-facf0);
1641
temp4 = temp1+(widthf/2)*facf0;
1643
if (temp3 < 0) temp3 = 0;
1644
if (temp4 > 2*3.14159) temp4 = 2*3.14159;
1649
else if (temp2 > temp4)
1652
output = (temp2-temp3)/(temp4-temp3);
1653
if(x == 0 && y == 0){
1656
if(output != output)
1659
output = 1 - output;
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;
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;
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);
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);
1681
if(b2 < b1 && b2 < b3 ){
1682
if(hwidth < pointdist)
1683
output = in_band(hwidth,hyp,facf0,0,1);
1685
else if(b2 > b1 && b2 > b3 ){
1686
if(hwidth < pointdist)
1687
output = in_band(hwidth,hyp2,facf0,0,1);
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);
1695
output = in_band(hwidth,hyp2,facf0,1,1) * in_band(hwidth,hyp,facf0,1,1);
1697
if(invert)facf0 = 1-facf0;
1699
b1 = posy/2 - (-angle)*posx/2;
1700
b3 = (yo-posy/2) - (-angle)*(xo-posx/2);
1701
b2 = y - (-angle)*x;
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);
1706
if(b2 < b1 && b2 < b3 ){
1707
if(hwidth < pointdist)
1708
output *= in_band(hwidth,hyp,facf0,0,1);
1710
else if(b2 > b1 && b2 > b3 ){
1711
if(hwidth < pointdist)
1712
output *= in_band(hwidth,hyp2,facf0,0,1);
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);
1720
output *= in_band(hwidth,hyp2,facf0,1,1) * in_band(hwidth,hyp,facf0,1,1);
1725
if(xo > yo) yo = xo;
1731
width = (int)(wipe->edgeWidth*((xo+yo)/2.0));
1732
hwidth = (float)width/2.0;
1734
temp1 = (halfx-(halfx)*facf0);
1735
pointdist = sqrt(temp1*temp1 + temp1*temp1);
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);
1741
output = in_band(hwidth,fabs(temp2-pointdist),facf0,1,1);
1748
if (output < 0) output = 0;
1749
else if(output > 1) output = 1;
1753
static void init_wipe_effect(Sequence *seq)
1755
if(seq->effectdata)MEM_freeN(seq->effectdata);
1756
seq->effectdata = MEM_callocN(sizeof(struct WipeVars), "wipevars");
1759
static void free_wipe_effect(Sequence *seq)
1761
if(seq->effectdata)MEM_freeN(seq->effectdata);
1762
seq->effectdata = 0;
1765
static void copy_wipe_effect(Sequence *dst, Sequence *src)
1767
dst->effectdata = MEM_dupallocN(src->effectdata);
1770
static void do_wipe_effect_byte(Sequence *seq, float facf0, float facf1,
1772
unsigned char *rect1,
1773
unsigned char *rect2, unsigned char *out)
1776
char *rt1, *rt2, *rt;
1777
rt1 = (char *)rect1;
1778
rt2 = (char *)rect2;
1785
float check = check_zone(x,y,xo,yo,seq,facf0);
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));
1823
static void do_wipe_effect_float(Sequence *seq, float facf0, float facf1,
1826
float *rect2, float *out)
1829
float *rt1, *rt2, *rt;
1838
float check = check_zone(x,y,xo,yo,seq,facf0);
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);
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)
1881
if (out->rect_float) {
1882
do_wipe_effect_float(seq,
1884
ibuf1->rect_float, ibuf2->rect_float,
1887
do_wipe_effect_byte(seq,
1889
(char*) ibuf1->rect, (char*) ibuf2->rect,
1894
/* **********************************************************************
1896
********************************************************************** */
1898
static void RVBlurBitmap2_byte ( unsigned char* map, int width,int height,
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 */
1906
/* Watch out though, it tends to misbehaven with large blur values on */
1907
/* a small bitmap. Avoid avoid avoid. */
1908
/*=============================== */
1910
unsigned char* temp=NULL,*swap;
1913
int index, ix, halfWidth;
1914
float fval, k, curColor[3], curColor2[3], weight=0;
1916
/* If we're not really blurring, bail out */
1920
/* Allocate memory for the tempmap and the blur filter matrix */
1921
temp= MEM_mallocN( (width*height*4), "blurbitmaptemp");
1925
/* Allocate memory for the filter elements */
1926
halfWidth = ((quality+1)*blur);
1927
filter = (float *)MEM_mallocN(sizeof(float)*halfWidth*2, "blurbitmapfilter");
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) */
1939
k = -1.0/(2.0*3.14159*blur*blur);
1941
for (ix = 0;ix< halfWidth;ix++){
1942
weight = (float)exp(k*(ix*ix));
1943
filter[halfWidth - ix] = weight;
1944
filter[halfWidth + ix] = weight;
1948
/* Normalize the array */
1950
for (ix = 0;ix< halfWidth*2;ix++)
1953
for (ix = 0;ix< halfWidth*2;ix++)
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;
1962
curColor[0]=curColor[1]=curColor[2]=0;
1963
curColor2[0]=curColor2[1]=curColor2[2]=0;
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];
1971
curColor2[0]+=map[(width-1-i+y*width)*4+GlowR] *
1973
curColor2[1]+=map[(width-1-i+y*width)*4+GlowG] *
1975
curColor2[2]+=map[(width-1-i+y*width)*4+GlowB] *
1980
temp[index+GlowR]=curColor[0];
1981
temp[index+GlowG]=curColor[1];
1982
temp[index+GlowB]=curColor[2];
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];
1989
/* Do the main body */
1990
for (x=halfWidth;x<width-halfWidth;x++){
1991
index=(x+y*width)*4;
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];
2000
temp[index+GlowR]=curColor[0];
2001
temp[index+GlowG]=curColor[1];
2002
temp[index+GlowB]=curColor[2];
2007
swap=temp;temp=map;map=swap;
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;
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)){
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];
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];
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];
2042
/* Do the main body */
2043
for (y=halfWidth;y<height-halfWidth;y++){
2044
index=(x+y*width)*4;
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];
2053
temp[index+GlowR]=curColor[0];
2054
temp[index+GlowG]=curColor[1];
2055
temp[index+GlowB]=curColor[2];
2061
swap=temp;temp=map;map=swap;
2068
static void RVBlurBitmap2_float ( float* map, int width,int height,
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 */
2076
/* Watch out though, it tends to misbehaven with large blur values on */
2077
/* a small bitmap. Avoid avoid avoid. */
2078
/*=============================== */
2080
float* temp=NULL,*swap;
2083
int index, ix, halfWidth;
2084
float fval, k, curColor[3], curColor2[3], weight=0;
2086
/* If we're not really blurring, bail out */
2090
/* Allocate memory for the tempmap and the blur filter matrix */
2091
temp= MEM_mallocN( (width*height*4*sizeof(float)), "blurbitmaptemp");
2095
/* Allocate memory for the filter elements */
2096
halfWidth = ((quality+1)*blur);
2097
filter = (float *)MEM_mallocN(sizeof(float)*halfWidth*2, "blurbitmapfilter");
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) */
2109
k = -1.0/(2.0*3.14159*blur*blur);
2111
for (ix = 0;ix< halfWidth;ix++){
2112
weight = (float)exp(k*(ix*ix));
2113
filter[halfWidth - ix] = weight;
2114
filter[halfWidth + ix] = weight;
2118
/* Normalize the array */
2120
for (ix = 0;ix< halfWidth*2;ix++)
2123
for (ix = 0;ix< halfWidth*2;ix++)
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;
2132
curColor[0]=curColor[1]=curColor[2]=0.0f;
2133
curColor2[0]=curColor2[1]=curColor2[2]=0.0f;
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];
2141
curColor2[0]+=map[(width-1-i+y*width)*4+GlowR] *
2143
curColor2[1]+=map[(width-1-i+y*width)*4+GlowG] *
2145
curColor2[2]+=map[(width-1-i+y*width)*4+GlowB] *
2150
temp[index+GlowR]=curColor[0];
2151
temp[index+GlowG]=curColor[1];
2152
temp[index+GlowB]=curColor[2];
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];
2159
/* Do the main body */
2160
for (x=halfWidth;x<width-halfWidth;x++){
2161
index=(x+y*width)*4;
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];
2170
temp[index+GlowR]=curColor[0];
2171
temp[index+GlowG]=curColor[1];
2172
temp[index+GlowB]=curColor[2];
2177
swap=temp;temp=map;map=swap;
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;
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)){
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];
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];
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];
2212
/* Do the main body */
2213
for (y=halfWidth;y<height-halfWidth;y++){
2214
index=(x+y*width)*4;
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];
2223
temp[index+GlowR]=curColor[0];
2224
temp[index+GlowG]=curColor[1];
2225
temp[index+GlowB]=curColor[2];
2231
swap=temp;temp=map;map=swap;
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)
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]);
2258
static void RVAddBitmaps_float (float* a, float* b, float* c,
2259
int width, int height)
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]);
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)
2284
for(y=0;y< height;y++) {
2285
for (x=0;x< width;x++) {
2286
index= (x+y*width)*4;
2288
/* Isolate the intensity */
2289
intensity=(in[index+GlowR]+in[index+GlowG]+in[index+GlowB]-threshold);
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);
2306
static void RVIsolateHighlights_float (float* in, float* out,
2307
int width, int height, float threshold,
2308
float boost, float clamp)
2314
for(y=0;y< height;y++) {
2315
for (x=0;x< width;x++) {
2316
index= (x+y*width)*4;
2318
/* Isolate the intensity */
2319
intensity=(in[index+GlowR]+in[index+GlowG]+in[index+GlowB]-threshold);
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));
2336
static void init_glow_effect(Sequence *seq)
2340
if(seq->effectdata)MEM_freeN(seq->effectdata);
2341
seq->effectdata = MEM_callocN(sizeof(struct GlowVars), "glowvars");
2343
glow = (GlowVars *)seq->effectdata;
2352
static void free_glow_effect(Sequence *seq)
2354
if(seq->effectdata)MEM_freeN(seq->effectdata);
2355
seq->effectdata = 0;
2358
static void copy_glow_effect(Sequence *dst, Sequence *src)
2360
dst->effectdata = MEM_dupallocN(src->effectdata);
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)
2368
unsigned char *outbuf=(unsigned char *)out;
2369
unsigned char *inbuf=(unsigned char *)rect1;
2370
GlowVars *glow = (GlowVars *)seq->effectdata;
2372
RVIsolateHighlights_byte(inbuf, outbuf , x, y, glow->fMini*765, glow->fBoost, glow->fClamp);
2373
RVBlurBitmap2_byte (outbuf, x, y, glow->dDist,glow->dQuality);
2375
RVAddBitmaps_byte (inbuf , outbuf, outbuf, x, y);
2378
static void do_glow_effect_float(Sequence *seq, float facf0, float facf1,
2380
float *rect1, float *rect2, float *out)
2382
float *outbuf = out;
2383
float *inbuf = rect1;
2384
GlowVars *glow = (GlowVars *)seq->effectdata;
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);
2389
RVAddBitmaps_float (inbuf , outbuf, outbuf, x, y);
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)
2397
if (out->rect_float) {
2398
do_glow_effect_float(seq,
2400
ibuf1->rect_float, ibuf2->rect_float,
2403
do_glow_effect_byte(seq,
2405
(char*) ibuf1->rect, (char*) ibuf2->rect,
2411
/* **********************************************************************
2412
sequence effect factory
2413
********************************************************************** */
2416
static void init_noop(struct Sequence *seq)
2421
static void load_noop(struct Sequence *seq)
2426
static void init_plugin_noop(struct Sequence *seq, const char * fname)
2431
static void free_noop(struct Sequence *seq)
2436
static int early_out_noop(struct Sequence *seq,
2437
float facf0, float facf1)
2442
static int early_out_fade(struct Sequence *seq,
2443
float facf0, float facf1)
2445
if (facf0 == 0.0 && facf1 == 0.0) {
2447
} else if (facf0 == 1.0 && facf1 == 1.0) {
2453
static int early_out_mul_input2(struct Sequence *seq,
2454
float facf0, float facf1)
2456
if (facf0 == 0.0 && facf1 == 0.0) {
2462
static void get_default_fac_noop(struct Sequence *seq, int cfra,
2463
float * facf0, float * facf1)
2465
*facf0 = *facf1 = 1.0;
2468
static void get_default_fac_fade(struct Sequence *seq, int cfra,
2469
float * facf0, float * facf1)
2471
*facf0 = (float)(cfra - seq->startdisp);
2472
*facf1 = (float)(*facf0 + 0.5);
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,
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);
2490
struct SeqEffectHandle get_sequence_effect(Sequence * seq)
2492
struct SeqEffectHandle rval;
2493
int sequence_type = seq->type;
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;
2504
switch (sequence_type) {
2506
rval.execute = do_cross_effect;
2507
rval.early_out = early_out_fade;
2508
rval.get_default_fac = get_default_fac_fade;
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;
2519
rval.execute = do_add_effect;
2520
rval.early_out = early_out_mul_input2;
2523
rval.execute = do_sub_effect;
2524
rval.early_out = early_out_mul_input2;
2527
rval.execute = do_mul_effect;
2528
rval.early_out = early_out_mul_input2;
2531
rval.init = init_alpha_over_or_under;
2532
rval.execute = do_alphaover_effect;
2535
rval.execute = do_overdrop_effect;
2537
case SEQ_ALPHAUNDER:
2538
rval.init = init_alpha_over_or_under;
2539
rval.execute = do_alphaunder_effect;
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;
2550
rval.init = init_glow_effect;
2551
rval.free = free_glow_effect;
2552
rval.copy = copy_glow_effect;
2553
rval.execute = do_glow_effect;
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;
2566
if (seq->flag & SEQ_EFFECT_NOT_LOADED) {
2568
seq->flag &= ~SEQ_EFFECT_NOT_LOADED;