www.pudn.com > xiaobo.zip.zip > coder_bpbf.c
/***** BP Binary Fast *****/ #include#include #include #include #include "coder.h" extern int tune_param; #define VAL_CONTEXTS 16 #define VAL_CONTEXT_MAX (VAL_CONTEXTS -1) #define SHAPE_BASE VAL_CONTEXTS #define SHAPE(x) (SHAPE_BASE<<(x)) #define NUM_SHAPES 2 #define NUM_CONTEXTS (VAL_CONTEXTS< TOTMAX ) { PT >>= 1; P0 >>= 1; P0++; PT += 2; } } while(0) #define bitEnc(bit,ari,P0,PT) do { arithEncBit(ari,P0,PT,bit); bitModel(bit,P0,PT); } while(0) #define bitDec(bit,ari,P0,PT) do { bit = arithDecBit(ari,P0,PT); bitModel(bit,P0,PT); } while(0) void coderBPBF_encodeBandBP(coder *me,int *band,int w,int h,int fullw,int *parent,int); void coderBPBF_decodeBandBP(coder *me,int *band,int w,int h,int fullw,int *parent,int); typedef struct { int signs_p0[SIGN_CONTEXTS]; int signs_pt[SIGN_CONTEXTS]; int stats_p0[NUM_CONTEXTS]; int stats_pt[NUM_CONTEXTS]; } myInfo; void coderBPBF_init(coder *c) { myInfo *d; int i; if ( (d = new(myInfo)) == NULL ) errexit("ozero init failed"); c->data = d; for(i=0;i stats_p0[i] = P0_INIT+1; d->stats_pt[i] = 2+P0_INIT+P1_INIT; } for(i=0;i signs_p0[i] = 100; d->signs_pt[i] = 200; } } void coderBPBF_free(coder *c) { if ( c->data ) { myInfo *d; d = c->data; free(d); c->data = NULL; } } coder coderBPBF = { "BP Bin Fast", coderBPBF_init, coderBPBF_free, NULL,NULL, coderBPBF_encodeBandBP, coderBPBF_decodeBandBP }; /********** lazy way to pass the state from getStats to fixStats and also interacts with the codeBand() these are re-initialized at each codeBand() call, so this is quite re-entrant as long as we aren't multi-threaded (that is, no more than one call to codeBand() at a time) *********/ static int VD,donemask,nextmask,sign_context; static int mcontext(int *dp,int pp,int x,int y,int fullw) { int P,N,W; int context; /** <> all these absolute values are painfully slow ***/ VD = abs(*dp)&donemask; // current val already done P = abs(pp)&nextmask; sign_context = 0; if ( y == 0 ) { N = VD; if ( x == 0 ) W = VD; else W = abs(dp[-1]) & nextmask; if ( W ) { if ( isneg(dp[-1]) ) sign_context += 3; else sign_context += 6; } } else if ( x == 0 ) { W = VD; N = abs(dp[-fullw]) & nextmask; if ( N ) { if ( isneg(dp[-fullw]) ) sign_context += 1; else sign_context += 2; } } else { N = abs(dp[-fullw]) & nextmask; W = abs(dp[-1]) & nextmask; if ( N ) { if ( isneg(dp[-fullw]) ) sign_context += 1; else sign_context += 2; } if ( W ) { if ( isneg(dp[-1]) ) sign_context += 3; else sign_context += 6; } } context = min(VAL_CONTEXT_MAX, ((VD + P + N + W)>>2)); if ( N > VD ) context += VAL_CONTEXTS; if ( W > VD ) context += VAL_CONTEXTS+VAL_CONTEXTS; return context; } void coderBPBF_encodeBandBP(coder *me,int *band,int width,int height,int fullw,int *parent,int bitmask) { int x,y,bit,context; int *dp,*pp; arithInfo *ari = me->arith; int *signs_p0,*signs_pt; int *stats_p0,*stats_pt; stats_p0 = ((myInfo *)me->data)->stats_p0; stats_pt = ((myInfo *)me->data)->stats_pt; signs_p0 = ((myInfo *)me->data)->signs_p0; signs_pt = ((myInfo *)me->data)->signs_pt; for(x=bitmask,nextmask=0; x<(1<<29) ;x<<=1) nextmask += x; donemask = nextmask - bitmask; dp = band; pp = parent; for(y=0;y >1],x,y,fullw); bit = (abs(dp[x])&bitmask)?1:0; bitEnc(bit,ari,stats_p0[context],stats_pt[context]); if ( bit && !VD ) { bitEnc( signbit(dp[x]) ,ari,signs_p0[sign_context],signs_pt[sign_context]); } } if ( y&1 ) pp += fullw; dp += fullw; } } void coderBPBF_decodeBandBP(coder *me,int *band,int width,int height,int fullw,int *parent,int bitmask) { int x,y,bit,context; int *dp,*pp; arithInfo *ari = me->arith; int *signs_p0,*signs_pt; int *stats_p0,*stats_pt; stats_p0 = ((myInfo *)me->data)->stats_p0; stats_pt = ((myInfo *)me->data)->stats_pt; signs_p0 = ((myInfo *)me->data)->signs_p0; signs_pt = ((myInfo *)me->data)->signs_pt; for(x=bitmask,nextmask=0; x<(1<<29) ;x<<=1) nextmask += x; donemask = nextmask - bitmask; dp = band; pp = parent; for(y=0;y >1],x,y,fullw); bitDec(bit,ari,stats_p0[context],stats_pt[context]); if ( bit ) { if ( ! VD ) { bitDec(bit,ari,signs_p0[sign_context],signs_pt[sign_context]); if ( bit ) dp[x] = - bitmask; else dp[x] = bitmask; } else { if ( isneg(dp[x]) ) dp[x] -= bitmask; else dp[x] += bitmask; } } } if ( y&1 ) pp += fullw; dp += fullw; } }