diff options
author | Peter Schlaile <peter@schlaile.de> | 2006-10-31 01:28:06 +0300 |
---|---|---|
committer | Peter Schlaile <peter@schlaile.de> | 2006-10-31 01:28:06 +0300 |
commit | e8a58eb0f9731600fde13898ec5d329258801a64 (patch) | |
tree | def19ca5d7585b8713520152eff7a833179428ef /source/blender/src/seqeffects.c | |
parent | 55d16189906c6a62d6f43233cc75a06858d0f507 (diff) |
== Sequencer ==
Bugfixes: Fixed partially bug #5030
Added patch: #4992 Basic Transforms
This adds basic transform capabilities (rotate, scale, shift) to the
sequencer.
Diffstat (limited to 'source/blender/src/seqeffects.c')
-rw-r--r-- | source/blender/src/seqeffects.c | 292 |
1 files changed, 291 insertions, 1 deletions
diff --git a/source/blender/src/seqeffects.c b/source/blender/src/seqeffects.c index 41f8f4cb846..02ad7f44a4a 100644 --- a/source/blender/src/seqeffects.c +++ b/source/blender/src/seqeffects.c @@ -1383,7 +1383,8 @@ static void do_mul_effect_byte(float facf0, float facf1, int x, int y, fac3= (int)(256.0*facf1); /* formula: - * fac*(a*b) + (1-fac)*a => fac*a*(b-1)+a + * fac*(a*b) + (1-fac)*a => fac*a*(b-1)+axaux= c*px + py*s ;//+centx + yaux= -s*px + c*py;//+centy */ while(y--) { @@ -1890,6 +1891,289 @@ static void do_wipe_effect(Sequence * seq,int cfra, (char*) out->rect); } } +/* ********************************************************************** + transform + ********************************************************************** */ +static void init_transform_effect(Sequence *seq) +{ + TransformVars *scale; + + if(seq->effectdata)MEM_freeN(seq->effectdata); + seq->effectdata = MEM_callocN(sizeof(struct TransformVars), "transformvars"); + + scale = (TransformVars *)seq->effectdata; + scale->ScalexIni = 1; + scale->ScaleyIni = 1; + scale->ScalexFin = 1; + scale->ScaleyFin = 1; + + scale->xIni=0; + scale->xFin=0; + scale->yIni=0; + scale->yFin=0; + + scale->rotIni=0; + scale->rotFin=0; + +} + +static void free_transform_effect(Sequence *seq) +{ + if(seq->effectdata)MEM_freeN(seq->effectdata); + seq->effectdata = 0; +} + +static void copy_transform_effect(Sequence *dst, Sequence *src) +{ + dst->effectdata = MEM_dupallocN(src->effectdata); +} + +/* function assumes out to be zero'ed, only does RGBA */ +static void bilinear_interpolation_transform_float(ImBuf *in, float *out, float u, float v) +{ + float *row1, *row2, *row3, *row4, a, b; + float a_b, ma_b, a_mb, ma_mb; + float empty[4]= {0.0f, 0.0f, 0.0f, 0.0f}; + int y1, y2, x1, x2; + + x1= (int)floor(u); + x2= (int)ceil(u); + y1= (int)floor(v); + y2= (int)ceil(v); + + /* sample area entirely outside image? */ + if(x2<0 || x1>in->x-1 || y2<0 || y1>in->y-1) + return; + + /* sample including outside of edges of image */ + if(x1<0 || y1<0) row1= empty; + else row1= in->rect_float + in->x * y1 * 4 + 4*x1; + + if(x1<0 || y2>in->y-1) row2= empty; + else row2= in->rect_float + in->x * y2 * 4 + 4*x1; + + if(x2>in->x-1 || y1<0) row3= empty; + else row3= in->rect_float + in->x * y1 * 4 + 4*x2; + + if(x2>in->x-1 || y2>in->y-1) row4= empty; + else row4= in->rect_float + in->x * y2 * 4 + 4*x2; + + a= u-floor(u); + b= v-floor(v); + a_b= a*b; ma_b= (1.0f-a)*b; a_mb= a*(1.0f-b); ma_mb= (1.0f-a)*(1.0f-b); + + out[0]= ma_mb*row1[0] + a_mb*row3[0] + ma_b*row2[0]+ a_b*row4[0]; + out[1]= ma_mb*row1[1] + a_mb*row3[1] + ma_b*row2[1]+ a_b*row4[1]; + out[2]= ma_mb*row1[2] + a_mb*row3[2] + ma_b*row2[2]+ a_b*row4[2]; + out[3]= ma_mb*row1[3] + a_mb*row3[3] + ma_b*row2[3]+ a_b*row4[3]; +} + + +static void do_transform_effect_float(Sequence * seq,float facf0, int x, int y, + struct ImBuf *ibuf1,float *out) +{ + int xo, yo, xi, yi; + float xs,ys,factxScale,factyScale,tx,ty,rad,s,c,xaux,yaux,factRot,px,py; + TransformVars *scale; + + scale = (TransformVars *)seq->effectdata; + xo = x; + yo = y; + + /*factor scale*/ + factxScale = scale->ScalexIni + (scale->ScalexFin - scale->ScalexIni) * facf0; + factyScale = scale->ScaleyIni + (scale->ScaleyFin - scale->ScaleyIni) * facf0; + + /*Factor translate*/ + tx = scale->xIni+(xo / 2.0f) + (scale->xFin-(xo / 2.0f) - scale->xIni+(xo / 2.0f)) * facf0; + ty = scale->yIni+(yo / 2.0f) + (scale->yFin-(yo / 2.0f) - scale->yIni+(yo / 2.0f)) * facf0; + + /*factor Rotate*/ + factRot = scale->rotIni + (scale->rotFin - scale->rotIni) * facf0; + rad = (M_PI * factRot) / 180.0f; + s= sin(rad); + c= cos(rad); + + for (yi = 0; yi < yo; yi++) { + for (xi = 0; xi < xo; xi++) { + /*tranlate point*/ + px = xi-tx; + py = yi-ty; + + /*rotate point with center ref*/ + xaux = c*px + py*s ; + yaux = -s*px + c*py; + + /*scale point with center ref*/ + xs = xaux / factxScale; + ys = yaux / factyScale; + + /*undo reference center point */ + xs += (xo / 2.0f); + ys += (yo / 2.0f); + + /*interpolate*/ + bilinear_interpolation_transform_float(ibuf1,out, xs,ys); + + out+=4; + } + } + +} + +/* function assumes out to be zero'ed, only does RGBA */ +static void bilinear_interpolation_transform_byte(unsigned char *in, unsigned char *out, float u, float v,int x,int y) +{ + float a, b; + float a_b, ma_b, a_mb, ma_mb; + int y1, y2, x1, x2; + + int row1R,row1G,row1B,row1A; + int row2R,row2G,row2B,row2A; + int row3R,row3G,row3B,row3A; + int row4R,row4G,row4B,row4A; + + x1= (int)floor(u); + x2= (int)ceil(u); + y1= (int)floor(v); + y2= (int)ceil(v); + + /* sample area entirely outside image? */ + if(x2<0 || x1>x-1 || y2<0 || y1>y-1) + return; + + /* sample including outside of edges of image */ + if(x1<0 || y1<0){ + row1R = 0; + row1G = 0; + row1B = 0; + row1A = 0; + } + else{ + row1R= in[x * y1 * 4 + 4 * x1]; + row1G= in[x * y1 * 4 + 4 * x1 + 1]; + row1B= in[x * y1 * 4 + 4 * x1 + 2]; + row1A= in[x * y1 * 4 + 4 * x1 + 3]; + } + + if(x1<0 || y2>y-1){ + row2R = 0; + row2G = 0; + row2B = 0; + row2A = 0; + } + else{ + row2R= in[x * y2 * 4 + 4 * x1]; + row2G= in[x * y2 * 4 + 4 * x1 + 1]; + row2B= in[x * y2 * 4 + 4 * x1 + 2]; + row2A= in[x * y2 * 4 + 4 * x1 + 3]; + } + + if(x2>x-1 || y1<0){ + row3R = 0; + row3G = 0; + row3B = 0; + row3A = 0; + } + else{ + row3R= in[x * y1 * 4 + 4 * x2]; + row3G= in[x * y1 * 4 + 4 * x2 + 1]; + row3B= in[x * y1 * 4 + 4 * x2 + 2]; + row3A= in[x * y1 * 4 + 4 * x2 + 3]; + } + + if(x2>x-1 || y2>y-1){ + row4R = 0; + row4G = 0; + row4B = 0; + row4A = 0; + } + else{ + row4R= in[x * y2 * 4 + 4 * x2]; + row4G= in[x * y2 * 4 + 4 * x2 + 1]; + row4B= in[x * y2 * 4 + 4 * x2 + 2]; + row4A= in[x * y2 * 4 + 4 * x2 + 3]; + } + + a= u-floor(u); + b= v-floor(v); + a_b= a*b; ma_b= (1-a)*b; a_mb= a*(1-b); ma_mb= (1-a)*(1-b); + + out[0]= (int)(ma_mb*row1R + a_mb*row3R + ma_b*row2R + a_b*row4R); + out[1]= (int)(ma_mb*row1G + a_mb*row3G + ma_b*row2G + a_b*row4G); + out[2]= (int)(ma_mb*row1B + a_mb*row3B + ma_b*row2B + a_b*row4B); + out[3]= (int)(ma_mb*row1A + a_mb*row3A + ma_b*row2A + a_b*row4A); +} + +static void do_transform_effect_byte(Sequence * seq,float facf0, int x, int y, + unsigned char *ibuf1,unsigned char *out) +{ + int xo, yo, xi, yi; + float xs,ys,factxScale,factyScale,tx,ty,rad,s,c,xaux,yaux,factRot,px,py; + TransformVars *scale; + + scale = (TransformVars *)seq->effectdata; + xo = x; + yo = y; + + /*factor scale*/ + factxScale = scale->ScalexIni + (scale->ScalexFin - scale->ScalexIni) * facf0; + factyScale = scale->ScaleyIni + (scale->ScaleyFin - scale->ScaleyIni) * facf0; + + /*Factor translate*/ + tx = scale->xIni+(xo / 2.0f) + (scale->xFin-(xo / 2.0f) - scale->xIni+(xo / 2.0f)) * facf0; + ty = scale->yIni+(yo / 2.0f) + (scale->yFin-(yo / 2.0f) - scale->yIni+(yo / 2.0f)) * facf0; + + /*factor Rotate*/ + factRot = scale->rotIni + (scale->rotFin - scale->rotIni) * facf0; + rad = (M_PI * factRot) / 180.0f; + s= sin(rad); + c= cos(rad); + + for (yi = 0; yi < yo; yi++) { + for (xi = 0; xi < xo; xi++) { + /*tranlate point*/ + px = xi-tx; + py = yi-ty; + + /*rotate point with center ref*/ + xaux = c*px + py*s ; + yaux = -s*px + c*py; + + /*scale point with center ref*/ + xs = xaux / factxScale; + ys = yaux / factyScale; + + /*undo reference center point */ + xs += (xo / 2.0f); + ys += (yo / 2.0f); + + /*interpolate*/ + bilinear_interpolation_transform_byte(ibuf1,out, xs,ys,x,y); + + out+=4; + } + } + +} +static void do_transform_effect(Sequence * seq,int cfra, + float facf0, float facf1, int x, int y, + struct ImBuf *ibuf1, struct ImBuf *ibuf2, + struct ImBuf *ibuf3, struct ImBuf *out) +{ + if (out->rect_float) { + do_transform_effect_float(seq, + facf0,x, y, + ibuf1, + out->rect_float); + } else { + do_transform_effect_byte(seq, + facf0,x, y, + (unsigned char*) ibuf1->rect, + (unsigned char*) out->rect); + } +} + /* ********************************************************************** GLOW @@ -2552,6 +2836,12 @@ struct SeqEffectHandle get_sequence_effect(Sequence * seq) rval.copy = copy_glow_effect; rval.execute = do_glow_effect; break; + case SEQ_TRANSFORM: + rval.init = init_transform_effect; + rval.free = free_transform_effect; + rval.copy = copy_transform_effect; + rval.execute = do_transform_effect; + break; case SEQ_PLUGIN: rval.init_plugin = init_plugin; rval.load = load_plugin; |