www.pudn.com > xiaobo.zip.zip > coder_bpbf_zt.c
/***** BP Binary Fast ZeroTree *****/ //#define ZT_STATS #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 coderBPBFZT_encodeBandZT(coder *me,int *band,int width,int height,int bits,int fullw,int **rows); void coderBPBFZT_decodeBandZT(coder *me,int *band,int width,int height,int bits,int fullw,int **rows); typedef struct { int stats_p0[NUM_CONTEXTS],stats_pt[NUM_CONTEXTS]; int zeros_p0[NUM_CONTEXTS],zeros_pt[NUM_CONTEXTS]; } myInfo; void coderBPBFZT_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; d->zeros_p0[i] = 1; d->zeros_pt[i] = 2; } } void coderBPBFZT_free(coder *c) { if ( c->data ) { myInfo *d; d = c->data; free(d); c->data = NULL; } } coder coderBPBFZT = { "BP Bin Fast ZT", coderBPBFZT_init, coderBPBFZT_free, NULL,NULL,NULL,NULL, coderBPBFZT_encodeBandZT, coderBPBFZT_decodeBandZT }; /********** 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; static int mcontext(int *dp,int x,int y,int fullw) { int N,W; int context; VD = (*dp)&donemask; // current val already done if ( y == 0 ) { N = VD; if ( x == 0 ) W = VD; else W = (dp[-1]) & nextmask; } else if ( x == 0 ) { W = VD; N = (dp[-fullw]) & nextmask; } else { N = (dp[-fullw]) & nextmask; W = (dp[-1]) & nextmask; } context = min(VAL_CONTEXT_MAX, ((VD + N + W)>>2)); /** shapes help almost 0.1 bpp **/ if ( N > VD ) context += VAL_CONTEXTS; if ( W > VD ) context += VAL_CONTEXTS+VAL_CONTEXTS; return context; } void coderBPBFZT_encodeBandZT(coder *me,int *band,int width,int height,int bits,int fullw,int **rows) { int x,y,bit,context; int *dp; arithInfo *ari = me->arith; int *stats_p0,*stats_pt; int *zeros_p0,*zeros_pt; int bitmask; bool bottom; #ifdef ZT_STATS int zt_kids=0,zt_root=0,zt_on=0,zt_isolated=0; #endif stats_p0 = ((myInfo *)me->data)->stats_p0; stats_pt = ((myInfo *)me->data)->stats_pt; zeros_p0 = ((myInfo *)me->data)->zeros_p0; zeros_pt = ((myInfo *)me->data)->zeros_pt; if ( width == (fullw >>1) ) bottom = true; else bottom = false; bitmask = 1< arith; int *stats_p0,*stats_pt; int *zeros_p0,*zeros_pt; int bitmask; int offwidth,offheight; bool bottom; stats_p0 = ((myInfo *)me->data)->stats_p0; stats_pt = ((myInfo *)me->data)->stats_pt; zeros_p0 = ((myInfo *)me->data)->zeros_p0; zeros_pt = ((myInfo *)me->data)->zeros_pt; if ( width == (fullw >>1) ) bottom = true; else bottom = false; offheight = (band - rows[0])/fullw; offwidth = (band - rows[0]) - fullw*offheight; bitmask = 1< could unroll as a switch on levels while( bx < fullw && by < fullw ) { for(tx=bx;tx<(bx+n);tx+=2) { for(ty=by;ty<(by+n);ty+=2) { rows[ty ][tx ] += FLAG_ALREADY_DECODED; rows[ty ][tx+1] += FLAG_ALREADY_DECODED; rows[ty+1][tx ] += FLAG_ALREADY_DECODED; rows[ty+1][tx+1] += FLAG_ALREADY_DECODED; } } bx += bx; by += by; n += n; } } } } } dp += fullw; } }