www.pudn.com > wavecode.rar > coder_nop.c
// #define BIG_SIGN_CONTEXT , hurts !? /***** *****/ #include#include #include #include #include #include "coder.h" #include "subbands.h" extern int tune_param; #define VAL_CONTEXTS 20 #define VAL_CONTEXT_MAX (VAL_CONTEXTS -1) #define SHAPE_BASE VAL_CONTEXTS #define SHAPE(x) (SHAPE_BASE<<(x)) #define NUM_SHAPES 4 #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) #define AddSignContext(context,val,mask) do { context *= 3; if( abs(val)&(mask) ) { if ( (val) > 0 ) context ++; else context += 2; } } while(0) typedef struct { int p0,pt; } binContext; void coderNOP_init(coder *c); void coderNOP_free(coder *c); void coderNOP_encodeSubbandBP(coder *me,subband_leaf *sb,int); void coderNOP_decodeSubbandBP(coder *me,subband_leaf *sb,int); typedef struct { binContext signs[SIGN_CONTEXTS]; binContext stats_array[NUM_CONTEXTS]; } myInfo; coder coderNOP = { "BPB No Parent", coderNOP_init, coderNOP_free, NULL,NULL,NULL,NULL,NULL,NULL, coderNOP_encodeSubbandBP, coderNOP_decodeSubbandBP }; void coderNOP_init(coder *c) { myInfo *d; int i; if ( (d = new(myInfo)) == NULL ) errexit("ozero init failed"); c->data = d; for(i=0;i stats_array[i].p0 = P0_INIT+1; d->stats_array[i].pt = 2+P0_INIT+P1_INIT; } for(i=0;i signs[i].p0 = 100; d->signs[i].pt = 200; } } void coderNOP_free(coder *c) { if ( c->data ) { myInfo *d; d = c->data; free(d); c->data = NULL; } } /********** 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; static binContext *stats_array; static binContext *statptr; static int donemask,nextmask; static int *sister_x,*sister_y,sister_trans; static void getStats(int *dp,int x,int y,int width,int height,int fullw) { int shapes; int N,W,NE,NW,S,E,X3,X4; /*** elaborate context-making ***/ VD = abs(*dp)&donemask; // current val already done if ( y == 0 ) { N = NW = NE = VD; if ( x == 0 ) W = VD; else W = abs(dp[-1]) & nextmask; } else if ( x == 0 ) { W = NW = 0; N = abs(dp[-fullw]) & nextmask; NE = abs(dp[1-fullw]) & nextmask; } else { N = abs(dp[-fullw]) & nextmask; W = abs(dp[-1]) & nextmask; NW = abs(dp[-1-fullw]) & nextmask; if ( x == (width-1) ) NE = VD; else NE = abs(dp[1-fullw]) & nextmask; } if ( y < (height-1) ) S = abs(dp[fullw]) & donemask; else S = VD; if ( x < (width-1) ) E = abs(dp[1]) & donemask; else E = VD; shapes = 0; if ( N > VD ) shapes += SHAPE(0); if ( W > VD ) shapes += SHAPE(1); if ( S > VD ) shapes += SHAPE(2); if ( E > VD ) shapes += SHAPE(3); if ( sister_x ) { switch(sister_trans) { case 0: X3 = abs( sister_x[ x + fullw*y ] ) & nextmask; X4 = abs( sister_y[ x + fullw*y ] ) & nextmask; break; case 1: X3 = abs( sister_x[ y + fullw*x ] ) & nextmask; X4 = abs( sister_y[ x + fullw*y ] ) & nextmask; break; case 2: X3 = abs( sister_x[ x + fullw*y ] ) & nextmask; X4 = abs( sister_y[ y + fullw*x ] ) & nextmask; break; case 3: X3 = abs( sister_x[ y + fullw*x ] ) & nextmask; X4 = abs( sister_y[ y + fullw*x ] ) & nextmask; break; } } else { if ( y > 1 ) X3 = abs(dp[-fullw-fullw]) & nextmask; else X3 = VD; //NN X4 = 0; } statptr = &stats_array[ min(VAL_CONTEXT_MAX, ((VD + N + W + NW + NE + S + E + X3 + X4)>>2)) + shapes]; } static void codeBand_init(coder *me,subband_leaf *sb) { myInfo *d; d = (myInfo *)me->data; if ( sb->cntx1 && sb->cntx1shift == 0 && sb->cntx2 && sb->cntx2shift == 0 ) { assert(sb->width == sb->cntx1->width); assert(sb->width == sb->cntx2->width); sister_x = sb->cntx1->band; sister_y = sb->cntx2->band; sister_trans = 0; if ( sb->cntx1->transposed != sb->transposed ) sister_trans |= 1; if ( sb->cntx2->transposed != sb->transposed ) sister_trans |= 2; } else { sister_x = sister_y = NULL; } stats_array = d->stats_array; } void coderNOP_encodeSubbandBP(coder *me,subband_leaf *sb,int bitmask) { int *band,width,height,fullw; int x,y,bit; int *dp,*dpn; arithInfo *ari = me->arith; binContext *signs = ((myInfo *)me->data)->signs; band = sb->band; width = sb->width; height = sb->height; fullw = sb->rowpad + width; codeBand_init(me,sb); for(x= bitmask,nextmask=0; x p0,statptr->pt,bit); bitModel(bit,statptr->p0,statptr->pt); if ( bit & !VD ) { int context; /** code the sign **/ context = 0; if ( x < (width-1) ) AddSignContext(context,dp[x+1],donemask); else context *= 3; if ( x > 0 ) AddSignContext(context,dp[x-1],nextmask); else context *= 3; if ( y < (height-1) ) AddSignContext(context,dp[x+fullw],donemask); else context *= 3; if ( y > 0 ) AddSignContext(context,dp[x-fullw],nextmask); else context *= 3; #ifdef BIG_SIGN_CONTEXT if ( y > 0 && x > 0 ) AddSignContext(context,dp[x-fullw-1],nextmask); else context *= 3; if ( y > 0 && x < (width-1) ) AddSignContext(context,dp[x-fullw+1],nextmask); else context *= 3; #endif bitEnc( (isneg(dp[x])?1:0) ,ari,signs[context].p0,signs[context].pt); } } dp += fullw; } } void coderNOP_decodeSubbandBP(coder *me,subband_leaf *sb,int bitmask) { int *band,width,height,fullw; int x,y,bit; int *dp,*dpn; arithInfo *ari = me->arith; binContext *signs = ((myInfo *)me->data)->signs; band = sb->band; width = sb->width; height = sb->height; fullw = sb->rowpad + width; codeBand_init(me,sb); for(x= bitmask,nextmask=0; x p0,statptr->pt); bitModel(bit,statptr->p0,statptr->pt); if ( bit ) { if ( isneg(dp[x]) ) dp[x] -= bitmask; else dp[x] += bitmask; if ( ! VD ) { int context; /** code the sign **/ context = 0; if ( x < (width-1) ) AddSignContext(context,dp[x+1],donemask); else context *= 3; if ( x > 0 ) AddSignContext(context,dp[x-1],nextmask); else context *= 3; if ( y < (height-1) ) AddSignContext(context,dp[x+fullw],donemask); else context *= 3; if ( y > 0 ) AddSignContext(context,dp[x-fullw],nextmask); else context *= 3; #ifdef BIG_SIGN_CONTEXT if ( y > 0 && x > 0 ) AddSignContext(context,dp[x-fullw-1],nextmask); else context *= 3; if ( y > 0 && x < (width-1) ) AddSignContext(context,dp[x-fullw+1],nextmask); else context *= 3; #endif bitDec(bit,ari,signs[context].p0,signs[context].pt); if ( bit ) dp[x] = - dp[x]; } } } dp += fullw; } }