diff options
author | Peter Schlaile <peter@schlaile.de> | 2006-03-07 23:01:12 +0300 |
---|---|---|
committer | Peter Schlaile <peter@schlaile.de> | 2006-03-07 23:01:12 +0300 |
commit | 327d413eb3c0c4cf07b71903eaa27e784be172c3 (patch) | |
tree | 9563098700eaa9f038dd476541ba71adf9d50e16 /source/blender/src/sequence.c | |
parent | 9ce587e2117dcb2340d75c4bfa2b6e3c1135254c (diff) |
this patch features several cleanups and bugfixes for the sequencer:
- blur works again (this was a serious bug in gamwarp...)
- seperates all sequence effects into a seperate file with a clean interface
- thereby fixing some obscure segfaults
- seperates the scope views into a seperate file
- adds float support to all effects and scope views
- removes a bad level call to open_plugin_seq
- FFMPEG seeking improved a lot.
- FFMPEG compiles with debian sarge version cleanly
- Makes hdaudio seek and resample code really work
Diffstat (limited to 'source/blender/src/sequence.c')
-rw-r--r-- | source/blender/src/sequence.c | 1723 |
1 files changed, 139 insertions, 1584 deletions
diff --git a/source/blender/src/sequence.c b/source/blender/src/sequence.c index 3fbe9735626..71c258bf3f6 100644 --- a/source/blender/src/sequence.c +++ b/source/blender/src/sequence.c @@ -23,7 +23,7 @@ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. * All rights reserved. * - * Contributor(s): Peter Schlaile <peter@schlaile.de> 2005/2006 + * Contributor(s): Peter Schlaile <peter [at] schlaile [dot] de> 2005/2006 * * ***** END GPL/BL DUAL LICENSE BLOCK ***** */ @@ -33,7 +33,6 @@ #include <stdlib.h> #include "MEM_guardedalloc.h" -#include "PIL_dynlib.h" #include "BLI_blenlib.h" #include "BLI_arithb.h" @@ -47,7 +46,6 @@ #include "DNA_view3d_types.h" #include "BKE_utildefines.h" -#include "BKE_plugin_types.h" #include "BKE_global.h" #include "BKE_texture.h" #include "BKE_image.h" @@ -64,138 +62,14 @@ #include "BIF_editsound.h" #include "BSE_sequence.h" +#include "BSE_seqeffects.h" #include "RE_pipeline.h" // talks to entire render API #include "blendef.h" -static void do_build_seq_depend(Sequence * seq, int cfra); - int seqrectx, seqrecty; -/* support for plugin sequences: */ - -void open_plugin_seq(PluginSeq *pis, char *seqname) -{ - int (*version)(); - void* (*alloc_private)(); - char *cp; - - /* to be sure: (is tested for) */ - pis->doit= 0; - pis->pname= 0; - pis->varstr= 0; - pis->cfra= 0; - pis->version= 0; - pis->instance_private_data = 0; - - /* clear the error list */ - PIL_dynlib_get_error_as_string(NULL); - - /* if(pis->handle) PIL_dynlib_close(pis->handle); */ - /* pis->handle= 0; */ - - /* open the needed object */ - pis->handle= PIL_dynlib_open(pis->name); - if(test_dlerr(pis->name, pis->name)) return; - - if (pis->handle != 0) { - /* find the address of the version function */ - version= (int (*)())PIL_dynlib_find_symbol(pis->handle, "plugin_seq_getversion"); - if (test_dlerr(pis->name, "plugin_seq_getversion")) return; - - if (version != 0) { - pis->version= version(); - if (pis->version==2 || pis->version==3) { - int (*info_func)(PluginInfo *); - PluginInfo *info= (PluginInfo*) MEM_mallocN(sizeof(PluginInfo), "plugin_info");; - - info_func= (int (*)(PluginInfo *))PIL_dynlib_find_symbol(pis->handle, "plugin_getinfo"); - - if(info_func == NULL) error("No info func"); - else { - info_func(info); - - pis->pname= info->name; - pis->vars= info->nvars; - pis->cfra= info->cfra; - - pis->varstr= info->varstr; - - pis->doit= (void(*)(void))info->seq_doit; - if (info->init) - info->init(); - } - MEM_freeN(info); - - cp= PIL_dynlib_find_symbol(pis->handle, "seqname"); - if(cp) strncpy(cp, seqname, 21); - } else { - printf ("Plugin returned unrecognized version number\n"); - return; - } - } - alloc_private = (void* (*)())PIL_dynlib_find_symbol( - pis->handle, "plugin_seq_alloc_private_data"); - if (alloc_private) { - pis->instance_private_data = alloc_private(); - } - - pis->current_private_data = (void**) - PIL_dynlib_find_symbol( - pis->handle, "plugin_private_data"); - } -} - -PluginSeq *add_plugin_seq(char *str, char *seqname) -{ - PluginSeq *pis; - VarStruct *varstr; - int a; - - pis= MEM_callocN(sizeof(PluginSeq), "PluginSeq"); - - strncpy(pis->name, str, FILE_MAXDIR+FILE_MAXFILE); - open_plugin_seq(pis, seqname); - - if(pis->doit==0) { - if(pis->handle==0) error("no plugin: %s", str); - else error("in plugin: %s", str); - MEM_freeN(pis); - return 0; - } - - /* default values */ - varstr= pis->varstr; - for(a=0; a<pis->vars; a++, varstr++) { - if( (varstr->type & FLO)==FLO) - pis->data[a]= varstr->def; - else if( (varstr->type & INT)==INT) - *((int *)(pis->data+a))= (int) varstr->def; - } - - return pis; -} - -void free_plugin_seq(PluginSeq *pis) -{ - if(pis==0) return; - - /* no PIL_dynlib_close: same plugin can be opened multiple times with 1 handle */ - - if (pis->instance_private_data) { - void (*free_private)(void *); - - free_private = (void (*)(void *))PIL_dynlib_find_symbol( - pis->handle, "plugin_seq_free_private_data"); - if (free_private) { - free_private(pis->instance_private_data); - } - } - - MEM_freeN(pis); -} - /* ***************** END PLUGIN ************************ */ void free_stripdata(int len, StripElem *se) @@ -247,12 +121,15 @@ void free_sequence(Sequence *seq) extern Sequence *last_seq; if(seq->strip) free_strip(seq->strip); - if(seq->effectdata) MEM_freeN(seq->effectdata); if(seq->anim) IMB_free_anim(seq->anim); if(seq->hdaudio) sound_close_hdaudio(seq->hdaudio); - free_plugin_seq(seq->plugin); + if (seq->type & SEQ_EFFECT) { + struct SeqEffectHandle sh = get_sequence_effect(seq); + + sh.free(seq); + } if(seq==last_seq) last_seq= 0; @@ -467,1158 +344,65 @@ void clear_scene_in_allseqs(Scene *sce) /* ***************** DO THE SEQUENCE ***************** */ -void do_alphaover_effect(float facf0, float facf1, int x, int y, unsigned int *rect1, unsigned int *rect2, unsigned int *out) -{ - int fac2, mfac, fac, fac4; - int xo, tempc; - char *rt1, *rt2, *rt; - - xo= x; - rt1= (char *)rect1; - rt2= (char *)rect2; - rt= (char *)out; - - fac2= (int)(256.0*facf0); - fac4= (int)(256.0*facf1); - - while(y--) { - - x= xo; - while(x--) { - - /* rt = rt1 over rt2 (alpha from rt1) */ - - fac= fac2; - mfac= 256 - ( (fac2*rt1[3])>>8 ); - - if(fac==0) *( (unsigned int *)rt) = *( (unsigned int *)rt2); - else if(mfac==0) *( (unsigned int *)rt) = *( (unsigned int *)rt1); - else { - tempc= ( fac*rt1[0] + mfac*rt2[0])>>8; - if(tempc>255) rt[0]= 255; else rt[0]= tempc; - tempc= ( fac*rt1[1] + mfac*rt2[1])>>8; - if(tempc>255) rt[1]= 255; else rt[1]= tempc; - tempc= ( fac*rt1[2] + mfac*rt2[2])>>8; - if(tempc>255) rt[2]= 255; else rt[2]= tempc; - tempc= ( fac*rt1[3] + mfac*rt2[3])>>8; - if(tempc>255) rt[3]= 255; else rt[3]= tempc; - } - rt1+= 4; rt2+= 4; rt+= 4; - } - - if(y==0) break; - y--; - - x= xo; - while(x--) { - - fac= fac4; - mfac= 256 - ( (fac4*rt1[3])>>8 ); - - if(fac==0) *( (unsigned int *)rt) = *( (unsigned int *)rt2); - else if(mfac==0) *( (unsigned int *)rt) = *( (unsigned int *)rt1); - else { - tempc= ( fac*rt1[0] + mfac*rt2[0])>>8; - if(tempc>255) rt[0]= 255; else rt[0]= tempc; - tempc= ( fac*rt1[1] + mfac*rt2[1])>>8; - if(tempc>255) rt[1]= 255; else rt[1]= tempc; - tempc= ( fac*rt1[2] + mfac*rt2[2])>>8; - if(tempc>255) rt[2]= 255; else rt[2]= tempc; - tempc= ( fac*rt1[3] + mfac*rt2[3])>>8; - if(tempc>255) rt[3]= 255; else rt[3]= tempc; - } - rt1+= 4; rt2+= 4; rt+= 4; - } - } -} - -void do_alphaunder_effect(float facf0, float facf1, int x, int y, unsigned int *rect1, unsigned int *rect2, unsigned int *out) -{ - int fac2, mfac, fac, fac4; - int xo; - char *rt1, *rt2, *rt; - - xo= x; - rt1= (char *)rect1; - rt2= (char *)rect2; - rt= (char *)out; - - fac2= (int)(256.0*facf0); - fac4= (int)(256.0*facf1); - - while(y--) { - - x= xo; - while(x--) { - - /* rt = rt1 under rt2 (alpha from rt2) */ - - /* this complex optimalisation is because the - * 'skybuf' can be crossed in - */ - if(rt2[3]==0 && fac2==256) *( (unsigned int *)rt) = *( (unsigned int *)rt1); - else if(rt2[3]==255) *( (unsigned int *)rt) = *( (unsigned int *)rt2); - else { - mfac= rt2[3]; - fac= (fac2*(256-mfac))>>8; - - if(fac==0) *( (unsigned int *)rt) = *( (unsigned int *)rt2); - else { - rt[0]= ( fac*rt1[0] + mfac*rt2[0])>>8; - rt[1]= ( fac*rt1[1] + mfac*rt2[1])>>8; - rt[2]= ( fac*rt1[2] + mfac*rt2[2])>>8; - rt[3]= ( fac*rt1[3] + mfac*rt2[3])>>8; - } - } - rt1+= 4; rt2+= 4; rt+= 4; - } - - if(y==0) break; - y--; - - x= xo; - while(x--) { - - if(rt2[3]==0 && fac4==256) *( (unsigned int *)rt) = *( (unsigned int *)rt1); - else if(rt2[3]==255) *( (unsigned int *)rt) = *( (unsigned int *)rt2); - else { - mfac= rt2[3]; - fac= (fac4*(256-mfac))>>8; - - if(fac==0) *( (unsigned int *)rt) = *( (unsigned int *)rt2); - else { - rt[0]= ( fac*rt1[0] + mfac*rt2[0])>>8; - rt[1]= ( fac*rt1[1] + mfac*rt2[1])>>8; - rt[2]= ( fac*rt1[2] + mfac*rt2[2])>>8; - rt[3]= ( fac*rt1[3] + mfac*rt2[3])>>8; - } - } - rt1+= 4; rt2+= 4; rt+= 4; - } - } -} - - -void do_cross_effect(float facf0, float facf1, int x, int y, unsigned int *rect1, unsigned int *rect2, unsigned int *out) -{ - int fac1, fac2, fac3, fac4; - int xo; - char *rt1, *rt2, *rt; - - xo= x; - rt1= (char *)rect1; - rt2= (char *)rect2; - rt= (char *)out; - - fac2= (int)(256.0*facf0); - fac1= 256-fac2; - fac4= (int)(256.0*facf1); - fac3= 256-fac4; - - while(y--) { - - x= xo; - while(x--) { - - rt[0]= (fac1*rt1[0] + fac2*rt2[0])>>8; - rt[1]= (fac1*rt1[1] + fac2*rt2[1])>>8; - rt[2]= (fac1*rt1[2] + fac2*rt2[2])>>8; - rt[3]= (fac1*rt1[3] + fac2*rt2[3])>>8; - - rt1+= 4; rt2+= 4; rt+= 4; - } - - if(y==0) break; - y--; - - x= xo; - while(x--) { - - rt[0]= (fac3*rt1[0] + fac4*rt2[0])>>8; - rt[1]= (fac3*rt1[1] + fac4*rt2[1])>>8; - rt[2]= (fac3*rt1[2] + fac4*rt2[2])>>8; - rt[3]= (fac3*rt1[3] + fac4*rt2[3])>>8; - - rt1+= 4; rt2+= 4; rt+= 4; - } - - } -} - -/* copied code from initrender.c */ -static unsigned short *gamtab, *igamtab1; - -static void gamtabs(float gamma) -{ - float val, igamma= 1.0f/gamma; - int a; - - gamtab= MEM_mallocN(65536*sizeof(short), "initGaus2"); - igamtab1= MEM_mallocN(256*sizeof(short), "initGaus2"); - - /* gamtab: in short, out short */ - for(a=0; a<65536; a++) { - val= a; - val/= 65535.0; - - if(gamma==2.0) val= sqrt(val); - else if(gamma!=1.0) val= pow(val, igamma); - - gamtab[a]= (65535.99*val); - } - /* inverse gamtab1 : in byte, out short */ - for(a=1; a<=256; a++) { - if(gamma==2.0) igamtab1[a-1]= a*a-1; - else if(gamma==1.0) igamtab1[a-1]= 256*a-1; - else { - val= a/256.0; - igamtab1[a-1]= (65535.0*pow(val, gamma)) -1 ; - } - } - -} - -void do_gammacross_effect(float facf0, float facf1, int x, int y, unsigned int *rect1, unsigned int *rect2, unsigned int *out) -{ - int fac1, fac2, col; - int xo; - char *rt1, *rt2, *rt; - - gamtabs(2.0f); - - xo= x; - rt1= (char *)rect1; - rt2= (char *)rect2; - rt= (char *)out; - - fac2= (int)(256.0*facf0); - fac1= 256-fac2; - - while(y--) { - - x= xo; - while(x--) { - - col= (fac1*igamtab1[rt1[0]] + fac2*igamtab1[rt2[0]])>>8; - if(col>65535) rt[0]= 255; else rt[0]= ( (char *)(gamtab+col))[MOST_SIG_BYTE]; - col=(fac1*igamtab1[rt1[1]] + fac2*igamtab1[rt2[1]])>>8; - if(col>65535) rt[1]= 255; else rt[1]= ( (char *)(gamtab+col))[MOST_SIG_BYTE]; - col= (fac1*igamtab1[rt1[2]] + fac2*igamtab1[rt2[2]])>>8; - if(col>65535) rt[2]= 255; else rt[2]= ( (char *)(gamtab+col))[MOST_SIG_BYTE]; - col= (fac1*igamtab1[rt1[3]] + fac2*igamtab1[rt2[3]])>>8; - if(col>65535) rt[3]= 255; else rt[3]= ( (char *)(gamtab+col))[MOST_SIG_BYTE]; - - rt1+= 4; rt2+= 4; rt+= 4; - } - - if(y==0) break; - y--; - - x= xo; - while(x--) { - - col= (fac1*igamtab1[rt1[0]] + fac2*igamtab1[rt2[0]])>>8; - if(col>65535) rt[0]= 255; else rt[0]= ( (char *)(gamtab+col))[MOST_SIG_BYTE]; - col= (fac1*igamtab1[rt1[1]] + fac2*igamtab1[rt2[1]])>>8; - if(col>65535) rt[1]= 255; else rt[1]= ( (char *)(gamtab+col))[MOST_SIG_BYTE]; - col= (fac1*igamtab1[rt1[2]] + fac2*igamtab1[rt2[2]])>>8; - if(col>65535) rt[2]= 255; else rt[2]= ( (char *)(gamtab+col))[MOST_SIG_BYTE]; - col= (fac1*igamtab1[rt1[3]] + fac2*igamtab1[rt2[3]])>>8; - if(col>65535) rt[3]= 255; else rt[3]= ( (char *)(gamtab+col))[MOST_SIG_BYTE]; - - rt1+= 4; rt2+= 4; rt+= 4; - } - } - - MEM_freeN(gamtab); - MEM_freeN(igamtab1); -} - -void do_add_effect(float facf0, float facf1, int x, int y, unsigned int *rect1, unsigned int *rect2, unsigned int *out) -{ - int col, xo, fac1, fac3; - char *rt1, *rt2, *rt; - - xo= x; - rt1= (char *)rect1; - rt2= (char *)rect2; - rt= (char *)out; - - fac1= (int)(256.0*facf0); - fac3= (int)(256.0*facf1); - - while(y--) { - - x= xo; - while(x--) { - - col= rt1[0]+ ((fac1*rt2[0])>>8); - if(col>255) rt[0]= 255; else rt[0]= col; - col= rt1[1]+ ((fac1*rt2[1])>>8); - if(col>255) rt[1]= 255; else rt[1]= col; - col= rt1[2]+ ((fac1*rt2[2])>>8); - if(col>255) rt[2]= 255; else rt[2]= col; - col= rt1[3]+ ((fac1*rt2[3])>>8); - if(col>255) rt[3]= 255; else rt[3]= col; - - rt1+= 4; rt2+= 4; rt+= 4; - } - - if(y==0) break; - y--; - - x= xo; - while(x--) { - - col= rt1[0]+ ((fac3*rt2[0])>>8); - if(col>255) rt[0]= 255; else rt[0]= col; - col= rt1[1]+ ((fac3*rt2[1])>>8); - if(col>255) rt[1]= 255; else rt[1]= col; - col= rt1[2]+ ((fac3*rt2[2])>>8); - if(col>255) rt[2]= 255; else rt[2]= col; - col= rt1[3]+ ((fac3*rt2[3])>>8); - if(col>255) rt[3]= 255; else rt[3]= col; - - rt1+= 4; rt2+= 4; rt+= 4; - } - } -} - -void do_sub_effect(float facf0, float facf1, int x, int y, unsigned int *rect1, unsigned int *rect2, unsigned int *out) -{ - int col, xo, fac1, fac3; - char *rt1, *rt2, *rt; - - xo= x; - rt1= (char *)rect1; - rt2= (char *)rect2; - rt= (char *)out; - - fac1= (int)(256.0*facf0); - fac3= (int)(256.0*facf1); - - while(y--) { - - x= xo; - while(x--) { - - col= rt1[0]- ((fac1*rt2[0])>>8); - if(col<0) rt[0]= 0; else rt[0]= col; - col= rt1[1]- ((fac1*rt2[1])>>8); - if(col<0) rt[1]= 0; else rt[1]= col; - col= rt1[2]- ((fac1*rt2[2])>>8); - if(col<0) rt[2]= 0; else rt[2]= col; - col= rt1[3]- ((fac1*rt2[3])>>8); - if(col<0) rt[3]= 0; else rt[3]= col; - - rt1+= 4; rt2+= 4; rt+= 4; - } - - if(y==0) break; - y--; - - x= xo; - while(x--) { - - col= rt1[0]- ((fac3*rt2[0])>>8); - if(col<0) rt[0]= 0; else rt[0]= col; - col= rt1[1]- ((fac3*rt2[1])>>8); - if(col<0) rt[1]= 0; else rt[1]= col; - col= rt1[2]- ((fac3*rt2[2])>>8); - if(col<0) rt[2]= 0; else rt[2]= col; - col= rt1[3]- ((fac3*rt2[3])>>8); - if(col<0) rt[3]= 0; else rt[3]= col; - - rt1+= 4; rt2+= 4; rt+= 4; - } - } -} - -/* Must be > 0 or add precopy, etc to the function */ -#define XOFF 8 -#define YOFF 8 - -void do_drop_effect(float facf0, float facf1, int x, int y, unsigned int *rect2i, unsigned int *rect1i, unsigned int *outi) -{ - int height, width, temp, fac, fac1, fac2; - char *rt1, *rt2, *out; - int field= 1; - - width= x; - height= y; - - fac1= (int)(70.0*facf0); - fac2= (int)(70.0*facf1); - - rt2= (char*) (rect2i + YOFF*width); - rt1= (char*) rect1i; - out= (char*) outi; - for (y=0; y<height-YOFF; y++) { - if(field) fac= fac1; - else fac= fac2; - field= !field; - - memcpy(out, rt1, sizeof(int)*XOFF); - rt1+= XOFF*4; - out+= XOFF*4; - - for (x=XOFF; x<width; x++) { - temp= ((fac*rt2[3])>>8); - - *(out++)= MAX2(0, *rt1 - temp); rt1++; - *(out++)= MAX2(0, *rt1 - temp); rt1++; - *(out++)= MAX2(0, *rt1 - temp); rt1++; - *(out++)= MAX2(0, *rt1 - temp); rt1++; - rt2+=4; - } - rt2+=XOFF*4; - } - memcpy(out, rt1, sizeof(int)*YOFF*width); -} - - /* WATCH: rect2 and rect1 reversed */ -void do_drop_effect2(float facf0, float facf1, int x, int y, unsigned int *rect2, unsigned int *rect1, unsigned int *out) -{ - int col, xo, yo, temp, fac1, fac3; - int xofs= -8, yofs= 8; - char *rt1, *rt2, *rt; - - xo= x; - yo= y; - - rt2= (char *)(rect2 + yofs*x + xofs); - - rt1= (char *)rect1; - rt= (char *)out; - - fac1= (int)(70.0*facf0); - fac3= (int)(70.0*facf1); - - while(y-- > 0) { - - temp= y-yofs; - if(temp > 0 && temp < yo) { - - x= xo; - while(x--) { - - temp= x+xofs; - if(temp > 0 && temp < xo) { - - temp= ((fac1*rt2[3])>>8); - - col= rt1[0]- temp; - if(col<0) rt[0]= 0; else rt[0]= col; - col= rt1[1]- temp; - if(col<0) rt[1]= 0; else rt[1]= col; - col= rt1[2]- temp; - if(col<0) rt[2]= 0; else rt[2]= col; - col= rt1[3]- temp; - if(col<0) rt[3]= 0; else rt[3]= col; - } - else *( (unsigned int *)rt) = *( (unsigned int *)rt1); - - rt1+= 4; rt2+= 4; rt+= 4; - } - } - else { - x= xo; - while(x--) { - *( (unsigned int *)rt) = *( (unsigned int *)rt1); - rt1+= 4; rt2+= 4; rt+= 4; - } - } - - if(y==0) break; - y--; - - temp= y-yofs; - if(temp > 0 && temp < yo) { - - x= xo; - while(x--) { - - temp= x+xofs; - if(temp > 0 && temp < xo) { - - temp= ((fac3*rt2[3])>>8); - - col= rt1[0]- temp; - if(col<0) rt[0]= 0; else rt[0]= col; - col= rt1[1]- temp; - if(col<0) rt[1]= 0; else rt[1]= col; - col= rt1[2]- temp; - if(col<0) rt[2]= 0; else rt[2]= col; - col= rt1[3]- temp; - if(col<0) rt[3]= 0; else rt[3]= col; - } - else *( (unsigned int *)rt) = *( (unsigned int *)rt1); - - rt1+= 4; rt2+= 4; rt+= 4; - } - } - else { - x= xo; - while(x--) { - *( (unsigned int *)rt) = *( (unsigned int *)rt1); - rt1+= 4; rt2+= 4; rt+= 4; - } - } - } -} - - -void do_mul_effect(float facf0, float facf1, int x, int y, unsigned int *rect1, unsigned int *rect2, unsigned int *out) -{ - int xo, fac1, fac3; - char *rt1, *rt2, *rt; - - xo= x; - rt1= (char *)rect1; - rt2= (char *)rect2; - rt= (char *)out; - - fac1= (int)(256.0*facf0); - fac3= (int)(256.0*facf1); - - /* formula: - * fac*(a*b) + (1-fac)*a => fac*a*(b-1)+a - */ - - while(y--) { - - x= xo; - while(x--) { - - rt[0]= rt1[0] + ((fac1*rt1[0]*(rt2[0]-256))>>16); - rt[1]= rt1[1] + ((fac1*rt1[1]*(rt2[1]-256))>>16); - rt[2]= rt1[2] + ((fac1*rt1[2]*(rt2[2]-256))>>16); - rt[3]= rt1[3] + ((fac1*rt1[3]*(rt2[3]-256))>>16); - - rt1+= 4; rt2+= 4; rt+= 4; - } - - if(y==0) break; - y--; - - x= xo; - while(x--) { - - rt[0]= rt1[0] + ((fac3*rt1[0]*(rt2[0]-256))>>16); - rt[1]= rt1[1] + ((fac3*rt1[1]*(rt2[1]-256))>>16); - rt[2]= rt1[2] + ((fac3*rt1[2]*(rt2[2]-256))>>16); - rt[3]= rt1[3] + ((fac3*rt1[3]*(rt2[3]-256))>>16); - - rt1+= 4; rt2+= 4; rt+= 4; - } - } -} - -// This function calculates the blur band for the wipe effects -float in_band(float width,float dist, float perc,int side,int dir){ - - float t1,t2,alpha,percwidth; - if(width == 0) - return (float)side; - if(side == 1) - percwidth = width * perc; - else - percwidth = width * (1 - perc); - - if(width < dist) - return side; - - t1 = dist / width; //percentange of width that is - t2 = 1 / width; //amount of alpha per % point - - if(side == 1) - alpha = (t1*t2*100) + (1-perc); // add point's alpha contrib to current position in wipe - else - alpha = (1-perc) - (t1*t2*100); - - if(dir == 0) - alpha = 1-alpha; - return alpha; -} - -float check_zone(int x, int y, int xo, int yo, Sequence *seq, float facf0) { - - float posx, posy,hyp,hyp2,angle,hwidth,b1,b2,b3,pointdist; - /*some future stuff - float hyp3,hyp4,b4,b5 - */ - float temp1,temp2,temp3,temp4; //some placeholder variables - float halfx = xo/2; - float halfy = yo/2; - float widthf,output=0; - WipeVars *wipe = (WipeVars *)seq->effectdata; - int width; - - angle = wipe->angle; - if(angle < 0){ - x = xo-x; - //y = yo-y - } - angle = pow(fabs(angle)/45,log(xo)/log(2)); - - posy = facf0 * yo; - if(wipe->forward){ - posx = facf0 * xo; - posy = facf0 * yo; - } else{ - posx = xo - facf0 * xo; - posy = yo - facf0 * yo; - } - switch (wipe->wipetype) { - case DO_SINGLE_WIPE: - width = (int)(wipe->edgeWidth*((xo+yo)/2.0)); - hwidth = (float)width/2.0; - - if (angle == 0.0)angle = 0.000001; - b1 = posy - (-angle)*posx; - b2 = y - (-angle)*x; - hyp = fabs(angle*x+y+(-posy-angle*posx))/sqrt(angle*angle+1); - if(angle < 0){ - temp1 = b1; - b1 = b2; - b2 = temp1; - } - if(wipe->forward){ - if(b1 < b2) - output = in_band(width,hyp,facf0,1,1); - else - output = in_band(width,hyp,facf0,0,1); - } - else{ - if(b1 < b2) - output = in_band(width,hyp,facf0,0,1); - else - output = in_band(width,hyp,facf0,1,1); - } - break; - - - case DO_DOUBLE_WIPE: - if(!wipe->forward)facf0 = 1-facf0; // Go the other direction - - width = (int)(wipe->edgeWidth*((xo+yo)/2.0)); // calculate the blur width - hwidth = (float)width/2.0; - if (angle == 0)angle = 0.000001; - b1 = posy/2 - (-angle)*posx/2; - b3 = (yo-posy/2) - (-angle)*(xo-posx/2); - b2 = y - (-angle)*x; - - hyp = abs(angle*x+y+(-posy/2-angle*posx/2))/sqrt(angle*angle+1); - hyp2 = abs(angle*x+y+(-(yo-posy/2)-angle*(xo-posx/2)))/sqrt(angle*angle+1); - - temp1 = xo*(1-facf0/2)-xo*facf0/2; - temp2 = yo*(1-facf0/2)-yo*facf0/2; - pointdist = sqrt(temp1*temp1 + temp2*temp2); - - if(b2 < b1 && b2 < b3 ){ - if(hwidth < pointdist) - output = in_band(hwidth,hyp,facf0,0,1); - } - else if(b2 > b1 && b2 > b3 ){ - if(hwidth < pointdist) - output = in_band(hwidth,hyp2,facf0,0,1); - } - else{ - if( hyp < hwidth && hyp2 > hwidth ) - output = in_band(hwidth,hyp,facf0,1,1); - else if( hyp > hwidth && hyp2 < hwidth ) - output = in_band(hwidth,hyp2,facf0,1,1); - else - output = in_band(hwidth,hyp2,facf0,1,1) * in_band(hwidth,hyp,facf0,1,1); - } - if(!wipe->forward)output = 1-output; - break; - case DO_CLOCK_WIPE: - /* - temp1: angle of effect center in rads - temp2: angle of line through (halfx,halfy) and (x,y) in rads - temp3: angle of low side of blur - temp4: angle of high side of blur - */ - output = 1-facf0; - widthf = wipe->edgeWidth*2*3.14159; - temp1 = 2 * 3.14159 * facf0; - - if(wipe->forward){ - temp1 = 2*3.14159-temp1; - } - - x = x - halfx; - y = y - halfy; - - temp2 = asin(abs(y)/sqrt(x*x + y*y)); - if(x <= 0 && y >= 0) - temp2 = 3.14159 - temp2; - else if(x<=0 && y <= 0) - temp2 += 3.14159; - else if(x >= 0 && y <= 0) - temp2 = 2*3.14159 - temp2; - - if(wipe->forward){ - temp3 = temp1-(widthf/2)*facf0; - temp4 = temp1+(widthf/2)*(1-facf0); - } - else{ - temp3 = temp1-(widthf/2)*(1-facf0); - temp4 = temp1+(widthf/2)*facf0; - } - if (temp3 < 0) temp3 = 0; - if (temp4 > 2*3.14159) temp4 = 2*3.14159; - - - if(temp2 < temp3) - output = 0; - else if (temp2 > temp4) - output = 1; - else - output = (temp2-temp3)/(temp4-temp3); - if(x == 0 && y == 0){ - output = 1; - } - if(output != output) - output = 1; - if(wipe->forward) - output = 1 - output; - break; - /* BOX WIPE IS NOT WORKING YET */ - /* case DO_CROSS_WIPE: */ - /* BOX WIPE IS NOT WORKING YET */ - /* case DO_BOX_WIPE: - if(invert)facf0 = 1-facf0; - - width = (int)(wipe->edgeWidth*((xo+yo)/2.0)); - hwidth = (float)width/2.0; - if (angle == 0)angle = 0.000001; - b1 = posy/2 - (-angle)*posx/2; - b3 = (yo-posy/2) - (-angle)*(xo-posx/2); - b2 = y - (-angle)*x; - - hyp = abs(angle*x+y+(-posy/2-angle*posx/2))/sqrt(angle*angle+1); - hyp2 = abs(angle*x+y+(-(yo-posy/2)-angle*(xo-posx/2)))/sqrt(angle*angle+1); - - temp1 = xo*(1-facf0/2)-xo*facf0/2; - temp2 = yo*(1-facf0/2)-yo*facf0/2; - pointdist = sqrt(temp1*temp1 + temp2*temp2); - - if(b2 < b1 && b2 < b3 ){ - if(hwidth < pointdist) - output = in_band(hwidth,hyp,facf0,0,1); - } - else if(b2 > b1 && b2 > b3 ){ - if(hwidth < pointdist) - output = in_band(hwidth,hyp2,facf0,0,1); - } - else{ - if( hyp < hwidth && hyp2 > hwidth ) - output = in_band(hwidth,hyp,facf0,1,1); - else if( hyp > hwidth && hyp2 < hwidth ) - output = in_band(hwidth,hyp2,facf0,1,1); - else - output = in_band(hwidth,hyp2,facf0,1,1) * in_band(hwidth,hyp,facf0,1,1); - } - if(invert)facf0 = 1-facf0; - angle = -1/angle; - b1 = posy/2 - (-angle)*posx/2; - b3 = (yo-posy/2) - (-angle)*(xo-posx/2); - b2 = y - (-angle)*x; - - hyp = abs(angle*x+y+(-posy/2-angle*posx/2))/sqrt(angle*angle+1); - hyp2 = abs(angle*x+y+(-(yo-posy/2)-angle*(xo-posx/2)))/sqrt(angle*angle+1); - - if(b2 < b1 && b2 < b3 ){ - if(hwidth < pointdist) - output *= in_band(hwidth,hyp,facf0,0,1); - } - else if(b2 > b1 && b2 > b3 ){ - if(hwidth < pointdist) - output *= in_band(hwidth,hyp2,facf0,0,1); - } - else{ - if( hyp < hwidth && hyp2 > hwidth ) - output *= in_band(hwidth,hyp,facf0,1,1); - else if( hyp > hwidth && hyp2 < hwidth ) - output *= in_band(hwidth,hyp2,facf0,1,1); - else - output *= in_band(hwidth,hyp2,facf0,1,1) * in_band(hwidth,hyp,facf0,1,1); - } - - break;*/ - case DO_IRIS_WIPE: - if(xo > yo) yo = xo; - else xo = yo; - - if(!wipe->forward) - facf0 = 1-facf0; - - width = (int)(wipe->edgeWidth*((xo+yo)/2.0)); - hwidth = (float)width/2.0; - - temp1 = (halfx-(halfx)*facf0); - pointdist = sqrt(temp1*temp1 + temp1*temp1); - - temp2 = sqrt((halfx-x)*(halfx-x) + (halfy-y)*(halfy-y)); - if(temp2 > pointdist) - output = in_band(hwidth,fabs(temp2-pointdist),facf0,0,1); - else - output = in_band(hwidth,fabs(temp2-pointdist),facf0,1,1); - - if(!wipe->forward) - output = 1-output; - - break; - } - if (output < 0) output = 0; - else if(output > 1) output = 1; - return output; -} - -void init_wipe_effect(Sequence *seq) -{ - if(seq->effectdata)MEM_freeN(seq->effectdata); - seq->effectdata = MEM_callocN(sizeof(struct WipeVars), "wipevars"); -} - -void do_wipe_effect(Sequence *seq, float facf0, float facf1, int x, int y, unsigned int *rect1, unsigned int *rect2, unsigned int *out) -{ - int xo, yo; - char *rt1, *rt2, *rt; - rt1 = (char *)rect1; - rt2 = (char *)rect2; - rt = (char *)out; - - xo = x; - yo = y; - for(y=0;y<yo;y++) { - - for(x=0;x<xo;x++) { - float check = check_zone(x,y,xo,yo,seq,facf0); - if (check) { - if (rt1) { - rt[0] = (int)(rt1[0]*check)+ (int)(rt2[0]*(1-check)); - rt[1] = (int)(rt1[1]*check)+ (int)(rt2[1]*(1-check)); - rt[2] = (int)(rt1[2]*check)+ (int)(rt2[2]*(1-check)); - rt[3] = (int)(rt1[3]*check)+ (int)(rt2[3]*(1-check)); - } else { - rt[0] = 0; - rt[1] = 0; - rt[2] = 0; - rt[3] = 255; - } - } else { - if (rt2) { - rt[0] = rt2[0]; - rt[1] = rt2[1]; - rt[2] = rt2[2]; - rt[3] = rt2[3]; - } else { - rt[0] = 0; - rt[1] = 0; - rt[2] = 0; - rt[3] = 255; - } - } - - rt+=4; - if(rt1 !=NULL){ - rt1+=4; - } - if(rt2 !=NULL){ - rt2+=4; - } - } - } -} - -/* Glow Functions */ - -void RVBlurBitmap2 ( unsigned char* map, int width,int height,float blur, - int quality) -/* MUUUCCH better than the previous blur. */ -/* We do the blurring in two passes which is a whole lot faster. */ -/* I changed the math arount to implement an actual Gaussian */ -/* distribution. */ -/* */ -/* Watch out though, it tends to misbehaven with large blur values on */ -/* a small bitmap. Avoid avoid avoid. */ -/*=============================== */ -{ - unsigned char* temp=NULL,*swap; - float *filter=NULL; - int x,y,i,fx,fy; - int index, ix, halfWidth; - float fval, k, curColor[3], curColor2[3], weight=0; - - /* If we're not really blurring, bail out */ - if (blur<=0) - return; - - /* Allocate memory for the tempmap and the blur filter matrix */ - temp= MEM_mallocN( (width*height*4), "blurbitmaptemp"); - if (!temp) - return; - - /* Allocate memory for the filter elements */ - halfWidth = ((quality+1)*blur); - filter = (float *)MEM_mallocN(sizeof(float)*halfWidth*2, "blurbitmapfilter"); - if (!filter){ - MEM_freeN (temp); - return; - } - - /* Apparently we're calculating a bell curve */ - /* based on the standard deviation (or radius) */ - /* This code is based on an example */ - /* posted to comp.graphics.algorithms by */ - /* Blancmange (bmange@airdmhor.gen.nz) */ - - k = -1.0/(2.0*3.14159*blur*blur); - fval=0; - for (ix = 0;ix< halfWidth;ix++){ - weight = (float)exp(k*(ix*ix)); - filter[halfWidth - ix] = weight; - filter[halfWidth + ix] = weight; - } - filter[0] = weight; - - /* Normalize the array */ - fval=0; - for (ix = 0;ix< halfWidth*2;ix++) - fval+=filter[ix]; - - for (ix = 0;ix< halfWidth*2;ix++) - filter[ix]/=fval; - - /* Blur the rows */ - for (y=0;y<height;y++){ - /* Do the left & right strips */ - for (x=0;x<halfWidth;x++){ - index=(x+y*width)*4; - fx=0; - curColor[0]=curColor[1]=curColor[2]=0; - curColor2[0]=curColor2[1]=curColor2[2]=0; - - for (i=x-halfWidth;i<x+halfWidth;i++){ - if ((i>=0)&&(i<width)){ - curColor[0]+=map[(i+y*width)*4+GlowR]*filter[fx]; - curColor[1]+=map[(i+y*width)*4+GlowG]*filter[fx]; - curColor[2]+=map[(i+y*width)*4+GlowB]*filter[fx]; - - curColor2[0]+=map[(width-1-i+y*width)*4+GlowR] * - filter[fx]; - curColor2[1]+=map[(width-1-i+y*width)*4+GlowG] * - filter[fx]; - curColor2[2]+=map[(width-1-i+y*width)*4+GlowB] * - filter[fx]; - } - fx++; - } - temp[index+GlowR]=curColor[0]; - temp[index+GlowG]=curColor[1]; - temp[index+GlowB]=curColor[2]; - - temp[((width-1-x+y*width)*4)+GlowR]=curColor2[0]; - temp[((width-1-x+y*width)*4)+GlowG]=curColor2[1]; - temp[((width-1-x+y*width)*4)+GlowB]=curColor2[2]; - - } - /* Do the main body */ - for (x=halfWidth;x<width-halfWidth;x++){ - index=(x+y*width)*4; - fx=0; - curColor[0]=curColor[1]=curColor[2]=0; - for (i=x-halfWidth;i<x+halfWidth;i++){ - curColor[0]+=map[(i+y*width)*4+GlowR]*filter[fx]; - curColor[1]+=map[(i+y*width)*4+GlowG]*filter[fx]; - curColor[2]+=map[(i+y*width)*4+GlowB]*filter[fx]; - fx++; - } - temp[index+GlowR]=curColor[0]; - temp[index+GlowG]=curColor[1]; - temp[index+GlowB]=curColor[2]; - } - } - - /* Swap buffers */ - swap=temp;temp=map;map=swap; - - - /* Blur the columns */ - for (x=0;x<width;x++){ - /* Do the top & bottom strips */ - for (y=0;y<halfWidth;y++){ - index=(x+y*width)*4; - fy=0; - curColor[0]=curColor[1]=curColor[2]=0; - curColor2[0]=curColor2[1]=curColor2[2]=0; - for (i=y-halfWidth;i<y+halfWidth;i++){ - if ((i>=0)&&(i<height)){ - /* Bottom */ - curColor[0]+=map[(x+i*width)*4+GlowR]*filter[fy]; - curColor[1]+=map[(x+i*width)*4+GlowG]*filter[fy]; - curColor[2]+=map[(x+i*width)*4+GlowB]*filter[fy]; - - /* Top */ - curColor2[0]+=map[(x+(height-1-i)*width) * - 4+GlowR]*filter[fy]; - curColor2[1]+=map[(x+(height-1-i)*width) * - 4+GlowG]*filter[fy]; - curColor2[2]+=map[(x+(height-1-i)*width) * - 4+GlowB]*filter[fy]; - } - fy++; - } - temp[index+GlowR]=curColor[0]; - temp[index+GlowG]=curColor[1]; - temp[index+GlowB]=curColor[2]; - temp[((x+(height-1-y)*width)*4)+GlowR]=curColor2[0]; - temp[((x+(height-1-y)*width)*4)+GlowG]=curColor2[1]; - temp[((x+(height-1-y)*width)*4)+GlowB]=curColor2[2]; - } - /* Do the main body */ - for (y=halfWidth;y<height-halfWidth;y++){ - index=(x+y*width)*4; - fy=0; - curColor[0]=curColor[1]=curColor[2]=0; - for (i=y-halfWidth;i<y+halfWidth;i++){ - curColor[0]+=map[(x+i*width)*4+GlowR]*filter[fy]; - curColor[1]+=map[(x+i*width)*4+GlowG]*filter[fy]; - curColor[2]+=map[(x+i*width)*4+GlowB]*filter[fy]; - fy++; - } - temp[index+GlowR]=curColor[0]; - temp[index+GlowG]=curColor[1]; - temp[index+GlowB]=curColor[2]; - } - } - - - /* Swap buffers */ - swap=temp;temp=map;map=swap; - - /* Tidy up */ - MEM_freeN (filter); - MEM_freeN (temp); -} - - -/* Adds two bitmaps and puts the results into a third map. */ -/* C must have been previously allocated but it may be A or B. */ -/* We clamp values to 255 to prevent weirdness */ -/*=============================== */ -void RVAddBitmaps (unsigned char* a, unsigned char* b, unsigned char* c, int width, int height) -{ - int x,y,index; - - for (y=0;y<height;y++){ - for (x=0;x<width;x++){ - index=(x+y*width)*4; - c[index+GlowR]=MIN2(255,a[index+GlowR]+b[index+GlowR]); - c[index+GlowG]=MIN2(255,a[index+GlowG]+b[index+GlowG]); - c[index+GlowB]=MIN2(255,a[index+GlowB]+b[index+GlowB]); - c[index+GlowA]=MIN2(255,a[index+GlowA]+b[index+GlowA]); - } - } -} - -/* For each pixel whose total luminance exceeds the threshold, */ -/* Multiply it's value by BOOST and add it to the output map */ -void RVIsolateHighlights (unsigned char* in, unsigned char* out, int width, int height, int threshold, float boost, float clamp) -{ - int x,y,index; - int intensity; - - - for(y=0;y< height;y++) { - for (x=0;x< width;x++) { - index= (x+y*width)*4; - - /* Isolate the intensity */ - intensity=(in[index+GlowR]+in[index+GlowG]+in[index+GlowB]-threshold); - if (intensity>0){ - out[index+GlowR]=MIN2(255*clamp, (in[index+GlowR]*boost*intensity)/255); - out[index+GlowG]=MIN2(255*clamp, (in[index+GlowG]*boost*intensity)/255); - out[index+GlowB]=MIN2(255*clamp, (in[index+GlowB]*boost*intensity)/255); - out[index+GlowA]=MIN2(255*clamp, (in[index+GlowA]*boost*intensity)/255); - } - else{ - out[index+GlowR]=0; - out[index+GlowG]=0; - out[index+GlowB]=0; - out[index+GlowA]=0; - } - } - } -} - -void init_glow_effect(Sequence *seq) -{ - GlowVars *glow; - - if(seq->effectdata)MEM_freeN(seq->effectdata); - seq->effectdata = MEM_callocN(sizeof(struct GlowVars), "glowvars"); - - glow = (GlowVars *)seq->effectdata; - glow->fMini = 0.25; - glow->fClamp = 1.0; - glow->fBoost = 0.5; - glow->dDist = 3.0; - glow->dQuality = 3; - glow->bNoComp = 0; -} - - -//void do_glow_effect(Cast *cast, float facf0, float facf1, int xo, int yo, ImBuf *ibuf1, ImBuf *ibuf2, ImBuf *outbuf, ImBuf *use) -void do_glow_effect(Sequence *seq, float facf0, float facf1, int x, int y, unsigned int *rect1, unsigned int *rect2, unsigned int *out) -{ - unsigned char *outbuf=(unsigned char *)out; - unsigned char *inbuf=(unsigned char *)rect1; - GlowVars *glow = (GlowVars *)seq->effectdata; - - RVIsolateHighlights (inbuf, outbuf , x, y, glow->fMini*765, glow->fBoost, glow->fClamp); - RVBlurBitmap2 (outbuf, x, y, glow->dDist,glow->dQuality); - if (!glow->bNoComp) - RVAddBitmaps (inbuf , outbuf, outbuf, x, y); -} - void make_black_ibuf(ImBuf *ibuf) { - unsigned int *rect; + int *rect; + float *rect_float; int tot; - if(ibuf==0 || ibuf->rect==0) return; + if(ibuf==0 || (ibuf->rect==0 && ibuf->rect_float==0)) return; tot= ibuf->x*ibuf->y; + rect= ibuf->rect; - while(tot--) *(rect++)= 0; + rect_float = ibuf->rect_float; + if (rect) { + memset(rect, 0, tot * sizeof(char) * 4); + } + + if (rect_float) { + memset(rect_float, 0, tot * sizeof(float) * 4); + } } void multibuf(ImBuf *ibuf, float fmul) { char *rt; + float *rt_float; + int a, mul, icol; mul= (int)(256.0*fmul); a= ibuf->x*ibuf->y; rt= (char *)ibuf->rect; - while(a--) { - - icol= (mul*rt[0])>>8; - if(icol>254) rt[0]= 255; else rt[0]= icol; - icol= (mul*rt[1])>>8; - if(icol>254) rt[1]= 255; else rt[1]= icol; - icol= (mul*rt[2])>>8; - if(icol>254) rt[2]= 255; else rt[2]= icol; - icol= (mul*rt[3])>>8; - if(icol>254) rt[3]= 255; else rt[3]= icol; - - rt+= 4; + rt_float = ibuf->rect_float; + + if (rt) { + while(a--) { + + icol= (mul*rt[0])>>8; + if(icol>254) rt[0]= 255; else rt[0]= icol; + icol= (mul*rt[1])>>8; + if(icol>254) rt[1]= 255; else rt[1]= icol; + icol= (mul*rt[2])>>8; + if(icol>254) rt[2]= 255; else rt[2]= icol; + icol= (mul*rt[3])>>8; + if(icol>254) rt[3]= 255; else rt[3]= icol; + + rt+= 4; + } + } + if (rt_float) { + while(a--) { + rt_float[0] *= fmul; + rt_float[1] *= fmul; + rt_float[2] *= fmul; + rt_float[3] *= fmul; + + rt_float += 4; + } } } @@ -1627,7 +411,7 @@ void do_effect(int cfra, Sequence *seq, StripElem *se) StripElem *se1, *se2, *se3; float fac, facf; int x, y; - char *cp; + struct SeqEffectHandle sh = get_sequence_effect(seq); if(se->se1==0 || se->se2==0 || se->se3==0) { make_black_ibuf(se->ibuf); @@ -1653,47 +437,38 @@ void do_effect(int cfra, Sequence *seq, StripElem *se) do_seq_ipo(seq); fac= seq->facf0; facf= seq->facf1; - } - else if ( seq->type==SEQ_CROSS || seq->type==SEQ_GAMCROSS || seq->type==SEQ_PLUGIN || seq->type==SEQ_WIPE) { - fac= (float)(cfra - seq->startdisp); - facf= (float)(fac+0.5); - fac /= seq->len; - facf /= seq->len; - } - else { - fac= facf= 1.0; + } else { + sh.get_default_fac(seq, cfra, &fac, &facf); } if( G.scene->r.mode & R_FIELDS ); else facf= fac; - /* FIXME: This should be made available to external plugins too... */ - if (seq->type == SEQ_CROSS || seq->type == SEQ_GAMCROSS || - seq->type == SEQ_WIPE) { - if (fac == 0.0 && facf == 0.0) { - if (se1->ibuf==0) { - make_black_ibuf(se->ibuf); - return; - } - if (se->ibuf != se1->ibuf) { - IMB_freeImBuf(se->ibuf); - se->ibuf = se1->ibuf; - IMB_refImBuf(se->ibuf); - } + switch (sh.early_out(seq, fac, facf)) { + case 0: + break; + case 1: + if (se1->ibuf==0) { + make_black_ibuf(se->ibuf); return; - } else if (fac == 1.0 && facf == 1.0) { - if (se2->ibuf==0) { - make_black_ibuf(se->ibuf); - return; - } - if (se->ibuf != se2->ibuf) { - IMB_freeImBuf(se->ibuf); - se->ibuf = se2->ibuf; - IMB_refImBuf(se->ibuf); - } + } + if (se->ibuf != se1->ibuf) { + IMB_freeImBuf(se->ibuf); + se->ibuf = se1->ibuf; + IMB_refImBuf(se->ibuf); + } + return; + case 2: + if (se2->ibuf==0) { + make_black_ibuf(se->ibuf); return; - } - } - + } + if (se->ibuf != se2->ibuf) { + IMB_freeImBuf(se->ibuf); + se->ibuf = se2->ibuf; + IMB_refImBuf(se->ibuf); + } + return; + } if (se1->ibuf==0 || se2->ibuf==0 || se3->ibuf==0) { make_black_ibuf(se->ibuf); @@ -1703,78 +478,22 @@ void do_effect(int cfra, Sequence *seq, StripElem *se) x= se2->ibuf->x; y= se2->ibuf->y; - switch(seq->type) { - case SEQ_CROSS: - do_cross_effect(fac, facf, x, y, se1->ibuf->rect, se2->ibuf->rect, se->ibuf->rect); - break; - case SEQ_GAMCROSS: - do_gammacross_effect(fac, facf, x, y, se1->ibuf->rect, se2->ibuf->rect, se->ibuf->rect); - break; - case SEQ_ADD: - do_add_effect(fac, facf, x, y, se1->ibuf->rect, se2->ibuf->rect, se->ibuf->rect); - break; - case SEQ_SUB: - do_sub_effect(fac, facf, x, y, se1->ibuf->rect, se2->ibuf->rect, se->ibuf->rect); - break; - case SEQ_MUL: - do_mul_effect(fac, facf, x, y, se1->ibuf->rect, se2->ibuf->rect, se->ibuf->rect); - break; - case SEQ_ALPHAOVER: - do_alphaover_effect(fac, facf, x, y, se1->ibuf->rect, se2->ibuf->rect, se->ibuf->rect); - break; - case SEQ_OVERDROP: - do_drop_effect(fac, facf, x, y, se1->ibuf->rect, se2->ibuf->rect, se->ibuf->rect); - do_alphaover_effect(fac, facf, x, y, se1->ibuf->rect, se->ibuf->rect, se->ibuf->rect); - break; - case SEQ_ALPHAUNDER: - do_alphaunder_effect(fac, facf, x, y, se1->ibuf->rect, se2->ibuf->rect, se->ibuf->rect); - break; - case SEQ_WIPE: - do_wipe_effect(seq, fac, facf, x, y, se1->ibuf->rect, se2->ibuf->rect, se->ibuf->rect); - break; - case SEQ_GLOW: - do_glow_effect(seq, fac, facf, x, y, se1->ibuf->rect, se2->ibuf->rect, se->ibuf->rect); - break; - case SEQ_PLUGIN: - if(seq->plugin && seq->plugin->doit) { - - if((G.f & G_PLAYANIM)==0) waitcursor(1); - - if(seq->plugin->cfra) - *(seq->plugin->cfra)= frame_to_float(CFRA); - - cp = PIL_dynlib_find_symbol( - seq->plugin->handle, "seqname"); - - if(cp) strncpy(cp, seq->name+2, 22); - - if (seq->plugin->current_private_data) { - *seq->plugin->current_private_data - = seq->plugin->instance_private_data; - } - - if (seq->plugin->version<=2) { - if(se1->ibuf) IMB_convert_rgba_to_abgr(se1->ibuf); - if(se2->ibuf) IMB_convert_rgba_to_abgr(se2->ibuf); - if(se3->ibuf) IMB_convert_rgba_to_abgr(se3->ibuf); - } - - ((SeqDoit)seq->plugin->doit)( - seq->plugin->data, fac, facf, x, y, - se1->ibuf, se2->ibuf, se->ibuf, se3->ibuf); - - if (seq->plugin->version<=2) { - if(se1->ibuf) IMB_convert_rgba_to_abgr(se1->ibuf); - if(se2->ibuf) IMB_convert_rgba_to_abgr(se2->ibuf); - if(se3->ibuf) IMB_convert_rgba_to_abgr(se3->ibuf); - IMB_convert_rgba_to_abgr(se->ibuf); - } + if (!se1->ibuf->rect_float && se->ibuf->rect_float) { + IMB_float_from_rect(se1->ibuf); + } + if (!se2->ibuf->rect_float && se->ibuf->rect_float) { + IMB_float_from_rect(se2->ibuf); + } - if((G.f & G_PLAYANIM)==0) waitcursor(0); - } - break; + if (!se1->ibuf->rect && !se->ibuf->rect_float) { + IMB_rect_from_float(se1->ibuf); + } + if (!se2->ibuf->rect && !se->ibuf->rect_float) { + IMB_rect_from_float(se2->ibuf); } + sh.execute(seq, cfra, fac, facf, x, y, se1->ibuf, se2->ibuf, se3->ibuf, + se->ibuf); } StripElem *give_stripelem(Sequence *seq, int cfra) @@ -1927,8 +646,12 @@ static void do_seq_unref_cfra(ListBase *seqbase, int cfra) if(seq->seqbase.first) { - if(cfra< seq->start) do_seq_unref_cfra(&seq->seqbase, seq->start); - else if(cfra> seq->start+seq->len-1) do_seq_unref_cfra(&seq->seqbase, seq->start+seq->len-1); + if(cfra< seq->start) do_seq_unref_cfra( + &seq->seqbase, seq->start); + else if(cfra> seq->start+seq->len-1) + do_seq_unref_cfra( + &seq->seqbase, + seq->start+seq->len-1); else do_seq_unref_cfra(&seq->seqbase, cfra); } @@ -1951,16 +674,25 @@ static void do_seq_test_unref_cfra(ListBase *seqbase, int cfra) if(seq->seqbase.first) { - if(cfra< seq->start) do_seq_test_unref_cfra(&seq->seqbase, seq->start); - else if(cfra> seq->start+seq->len-1) do_seq_test_unref_cfra(&seq->seqbase, seq->start+seq->len-1); - else do_seq_test_unref_cfra(&seq->seqbase, cfra); + if(cfra< seq->start) + do_seq_test_unref_cfra( + &seq->seqbase, seq->start); + else if(cfra> seq->start+seq->len-1) + do_seq_test_unref_cfra( + &seq->seqbase, + seq->start+seq->len-1); + else do_seq_test_unref_cfra( + &seq->seqbase, cfra); } if (seq->curelem && seq->curelem->ibuf && seq->curelem->isneeded) { - if (IMB_cache_limiter_get_refcount(seq->curelem->ibuf)) { - fprintf(stderr, "refcount Arggh: %p, %d\n", - seq, seq->type); + if (IMB_cache_limiter_get_refcount( + seq->curelem->ibuf)) { + fprintf(stderr, + "sequence.c: imbuf-refcount " + "Arggh: %p, %d\n", + seq, seq->type); } } } @@ -1968,43 +700,36 @@ static void do_seq_test_unref_cfra(ListBase *seqbase, int cfra) } } +static void do_build_seq_depend(Sequence * seq, int cfra); + static void do_effect_depend(int cfra, Sequence * seq, StripElem *se) { float fac, facf; + struct SeqEffectHandle sh = get_sequence_effect(seq); if(seq->ipo && seq->ipo->curve.first) { do_seq_ipo(seq); fac= seq->facf0; facf= seq->facf1; - } else if ( seq->type == SEQ_CROSS - || seq->type == SEQ_GAMCROSS - || seq->type == SEQ_PLUGIN - || seq->type == SEQ_WIPE) { - fac= (float)(cfra - seq->startdisp); - facf= (float)(fac+0.5); - fac /= seq->len; - facf /= seq->len; } else { - fac= facf= 1.0; - } + sh.get_default_fac(seq, cfra, &fac, &facf); + } if( G.scene->r.mode & R_FIELDS ); else facf= fac; - /* FIXME: This should be made available to external plugins too... */ - if (seq->type == SEQ_CROSS || seq->type == SEQ_GAMCROSS || - seq->type == SEQ_WIPE) { - if (fac == 0.0 && facf == 0.0) { - do_build_seq_depend(seq->seq1, cfra); - } else if (fac == 1.0 && facf == 1.0) { - do_build_seq_depend(seq->seq2, cfra); - } else { - do_build_seq_depend(seq->seq1, cfra); - do_build_seq_depend(seq->seq2, cfra); - } - } else { + switch (sh.early_out(seq, fac, facf)) { + case 0: do_build_seq_depend(seq->seq1, cfra); do_build_seq_depend(seq->seq2, cfra); + break; + case 1: + do_build_seq_depend(seq->seq1, cfra); + break; + case 2: + do_build_seq_depend(seq->seq2, cfra); + break; } + do_build_seq_depend(seq->seq3, cfra); } @@ -2120,16 +845,22 @@ static void do_build_seq_ibuf(Sequence * seq, int cfra) if(seq->type==SEQ_IMAGE) { if(se->ok && se->ibuf==0) { + /* if playanim or render: + no waitcursor */ + if((G.f & G_PLAYANIM)==0) + waitcursor(1); - /* if playanim or render: no waitcursor */ - if((G.f & G_PLAYANIM)==0) waitcursor(1); - - strncpy(name, seq->strip->dir, FILE_MAXDIR-1); + strncpy(name, seq->strip->dir, + FILE_MAXDIR-1); strncat(name, se->name, FILE_MAXFILE); - BLI_convertstringcode(name, G.sce, G.scene->r.cfra); - se->ibuf= IMB_loadiffname(name, IB_rect); + BLI_convertstringcode(name, + G.sce, + G.scene->r.cfra); + se->ibuf= IMB_loadiffname(name, + IB_rect); - if((G.f & G_PLAYANIM)==0) waitcursor(0); + if((G.f & G_PLAYANIM)==0) + waitcursor(0); if(se->ibuf==0) se->ok= 0; else { @@ -2146,10 +877,6 @@ static void do_build_seq_ibuf(Sequence * seq, int cfra) } else if(seq->type==SEQ_MOVIE) { if(se->ok && se->ibuf==0) { - - /* if playanim r render: no waitcursor */ - if((G.f & G_PLAYANIM)==0) waitcursor(1); - if(seq->anim==0) { strncpy(name, seq->strip->dir, FILE_MAXDIR-1); strncat(name, seq->strip->stripdata->name, FILE_MAXFILE-1); @@ -2158,6 +885,9 @@ static void do_build_seq_ibuf(Sequence * seq, int cfra) seq->anim = openanim(name, IB_rect); } if(seq->anim) { + IMB_anim_set_preseek( + seq->anim, + seq->anim_preseek); se->ibuf = IMB_anim_absolute(seq->anim, se->nr); } @@ -2172,7 +902,6 @@ static void do_build_seq_ibuf(Sequence * seq, int cfra) if(seq->mul==0.0) seq->mul= 1.0; if(seq->mul != 1.0) multibuf(se->ibuf, seq->mul); } - if((G.f & G_PLAYANIM)==0) waitcursor(0); } } else if(seq->type==SEQ_SCENE && se->ibuf==0 && seq->scene) { // scene can be NULL after deletions @@ -2438,180 +1167,6 @@ ImBuf *give_ibuf_seq(int rectx, int recty, int cfra, int chanshown) } -static void rgb_to_yuv(float rgb[3], float yuv[3]) { - yuv[0]= 0.299*rgb[0] + 0.587*rgb[1] + 0.114*rgb[2]; - yuv[1]= 0.492*(rgb[2] - yuv[0]); - yuv[2]= 0.877*(rgb[0] - yuv[0]); - - /* Normalize */ - yuv[1]*= 255.0/(122*2.0); - yuv[1]+= 0.5; - - yuv[2]*= 255.0/(157*2.0); - yuv[2]+= 0.5; -} - -static void scope_put_pixel(unsigned char* table, unsigned char * pos) -{ - char newval = table[*pos]; - pos[0] = pos[1] = pos[2] = newval; - pos[3] = 255; -} - -static void wform_put_line(int w, - unsigned char * last_pos, unsigned char * new_pos) -{ - if (last_pos > new_pos) { - unsigned char* temp = new_pos; - new_pos = last_pos; - last_pos = temp; - } - - while (last_pos < new_pos) { - if (last_pos[0] == 0) { - last_pos[0] = last_pos[1] = last_pos[2] = 32; - last_pos[3] = 255; - } - last_pos += 4*w; - } -} - -struct ImBuf *make_waveform_view_from_ibuf(struct ImBuf * ibuf) -{ - struct ImBuf * rval = IMB_allocImBuf(ibuf->x + 3, 515, 32, IB_rect, 0); - int x,y; - unsigned char* src = (unsigned char*) ibuf->rect; - unsigned char* tgt = (unsigned char*) rval->rect; - int w = ibuf->x + 3; - int h = 515; - float waveform_gamma = 0.2; - unsigned char wtable[256]; - - for (x = 0; x < 256; x++) { - wtable[x] = (unsigned char) (pow(((float) x + 1)/256, - waveform_gamma)*255); - } - - for (y = 0; y < h; y++) { - unsigned char * last_p = 0; - - for (x = 0; x < w; x++) { - unsigned char * rgb = src + 4 * (ibuf->x * y + x); - float v = 1.0 * - ( 0.299*rgb[0] - + 0.587*rgb[1] - + 0.114*rgb[2]) / 255.0; - unsigned char * p = tgt; - p += 4 * (w * ((int) (v * (h - 3)) + 1) + x + 1); - - scope_put_pixel(wtable, p); - p += 4 * w; - scope_put_pixel(wtable, p); - - if (last_p != 0) { - wform_put_line(w, last_p, p); - } - last_p = p; - } - } - - for (x = 0; x < w; x++) { - unsigned char * p = tgt + 4 * x; - p[1] = p[3] = 255.0; - p[4 * w + 1] = p[4 * w + 3] = 255.0; - p = tgt + 4 * (w * (h - 1) + x); - p[1] = p[3] = 255.0; - p[-4 * w + 1] = p[-4 * w + 3] = 255.0; - } - - for (y = 0; y < h; y++) { - unsigned char * p = tgt + 4 * w * y; - p[1] = p[3] = 255.0; - p[4 + 1] = p[4 + 3] = 255.0; - p = tgt + 4 * (w * y + w - 1); - p[1] = p[3] = 255.0; - p[-4 + 1] = p[-4 + 3] = 255.0; - } - - return rval; -} - -static void vectorscope_put_cross(unsigned char r, unsigned char g, - unsigned char b, - char * tgt, int w, int h, int size) -{ - float rgb[3], yuv[3]; - char * p; - int x = 0; - int y = 0; - - rgb[0]= (float)r/255.0; - rgb[1]= (float)g/255.0; - rgb[2]= (float)b/255.0; - rgb_to_yuv(rgb, yuv); - - p = tgt + 4 * (w * (int) ((yuv[2] * (h - 3) + 1)) - + (int) ((yuv[1] * (w - 3) + 1))); - - if (r == 0 && g == 0 && b == 0) { - r = 255; - } - - for (y = -size; y <= size; y++) { - for (x = -size; x <= size; x++) { - char * q = p + 4 * (y * w + x); - q[0] = r; q[1] = g; q[2] = b; q[3] = 255; - } - } -} - -struct ImBuf *make_vectorscope_view_from_ibuf(struct ImBuf * ibuf) -{ - struct ImBuf * rval = IMB_allocImBuf(515, 515, 32, IB_rect, 0); - int x,y; - char* src = (char*) ibuf->rect; - char* tgt = (char*) rval->rect; - float rgb[3], yuv[3]; - int w = 515; - int h = 515; - float scope_gamma = 0.2; - unsigned char wtable[256]; - - for (x = 0; x < 256; x++) { - wtable[x] = (unsigned char) (pow(((float) x + 1)/256, - scope_gamma)*255); - } - - for (x = 0; x <= 255; x++) { - vectorscope_put_cross(255 , 0,255 - x, tgt, w, h, 1); - vectorscope_put_cross(255 , x, 0, tgt, w, h, 1); - vectorscope_put_cross(255- x, 255, 0, tgt, w, h, 1); - vectorscope_put_cross(0, 255, x, tgt, w, h, 1); - vectorscope_put_cross(0, 255 - x, 255, tgt, w, h, 1); - vectorscope_put_cross(x, 0, 255, tgt, w, h, 1); - } - - for (y = 0; y < h; y++) { - for (x = 0; x < w; x++) { - char * src1 = src + 4 * (ibuf->x * y + x); - char * p; - - rgb[0]= (float)src1[0]/255.0; - rgb[1]= (float)src1[1]/255.0; - rgb[2]= (float)src1[2]/255.0; - rgb_to_yuv(rgb, yuv); - - p = tgt + 4 * (w * (int) ((yuv[2] * (h - 3) + 1)) - + (int) ((yuv[1] * (w - 3) + 1))); - scope_put_pixel(wtable, p); - } - } - - vectorscope_put_cross(0, 0, 0, tgt, w, h, 3); - - return rval; -} - void free_imbuf_effect_spec(int cfra) { Sequence *seq; |