www.pudn.com > wavecode.rar > coder_zf.c
/***** ZeroFlag coder: codes bytewise but only using binary arithcoders. sends "is byte == 0" (conditioned on activity of N and W) then sign (conditioned on signs of N and W) then (abs(byte)-1) using a unary adaptive binary code fast AND excellent compression *****/ #include#include #include #include #include #include "coder.h" extern int tune_param; #define VAL_CONTEXTS 16 #define VAL_CONTEXT_MAX (VAL_CONTEXTS -1) #define NUM_CONTEXTS VAL_CONTEXTS #define TAIL_CONTEXTS VAL_CONTEXTS #define SIGN_CONTEXTS 4 #define TOTMAX 4000 #define INC 30 #define P0_INIT 8 #define P1_INIT 0 #define bitModel(bit,P0,PT) do { PT += INC; if (!(bit)) P0 += INC; if ( PT > 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 coderZF_encodeBand(coder *me,int *band,int w,int h,int fullw,int *parent); void coderZF_decodeBand(coder *me,int *band,int w,int h,int fullw,int *parent); typedef struct { int signs_p0[SIGN_CONTEXTS]; int signs_pt[SIGN_CONTEXTS]; int stats_p0[NUM_CONTEXTS]; int stats_pt[NUM_CONTEXTS]; int tails_p0[TAIL_CONTEXTS]; int tails_pt[TAIL_CONTEXTS]; } myInfo; void coderZF_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; } for(i=0;i tails_p0[i] = 100; d->tails_pt[i] = 2000; } } void coderZF_free(coder *c) { if ( c->data ) { myInfo *d; d = c->data; free(d); c->data = NULL; } } coder coderZF = { "ZeroFlag", coderZF_init, coderZF_free, coderZF_encodeBand, coderZF_decodeBand }; static int sign_context; /** cheesy way to return two values **/ static int mcontext(int *dp,int x,int y,int fullw) { if ( y == 0 ) { if ( x > 0 ) { int W; W = dp[-1]; if ( isneg(W) ) { sign_context = 2; W = - W; } else sign_context =0; return min(VAL_CONTEXT_MAX, (W>>1)); } else { sign_context = 0 ; return 0; } } else if ( x == 0 ) { int N; N = dp[-fullw]; if ( isneg(N) ) { sign_context = 1; N = - N; } else sign_context = 0; return min(VAL_CONTEXT_MAX, (N>>1)); } else { int N,W; N = dp[-fullw]; W = dp[-1]; if ( isneg(N) ) { sign_context = 1; N = - N; } else sign_context = 0; if ( isneg(W) ) { sign_context += 2; W = - W; } return min(VAL_CONTEXT_MAX, ((N + W)>>2)); } } void coderZF_encodeBand(coder *me,int *band,int width,int height,int fullw,int *parent) { int x,y,context,V; int *dp; arithInfo *ari; int *signs_p0,*signs_pt; int *tails_p0,*tails_pt; int *stats_p0,*stats_pt; ari = me->arith; 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; tails_p0 = ((myInfo *)me->data)->tails_p0; tails_pt = ((myInfo *)me->data)->tails_pt; dp = band; for(y=0;y 0 ) { bitEnc(0,ari,signs_p0[sign_context],signs_pt[sign_context]); V--; } else { bitEnc(1,ari,signs_p0[sign_context],signs_pt[sign_context]); V = - V -1; } /* send remainder */ while(V--) bitEnc(1,ari,tails_p0[context],tails_pt[context]); bitEnc(0,ari,tails_p0[context],tails_pt[context]); break; } } } dp += fullw; } } void coderZF_decodeBand(coder *me,int *band,int width,int height,int fullw,int *parent) { int x,y,bit,sign,context,V; int *dp; arithInfo *ari; int *signs_p0,*signs_pt; int *stats_p0,*stats_pt; int *tails_p0,*tails_pt; ari = me->arith; 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; tails_p0 = ((myInfo *)me->data)->tails_p0; tails_pt = ((myInfo *)me->data)->tails_pt; dp = band; for(y=0;y