www.pudn.com > wavecode.rar > coder_sm.c
/***** SigMap : send "significance map" then residual values the sigmap is a mask of five entries : "0,1,-1, positive > 1, negative < -1" it is order-1 context coded bases on the the parents' sigmap entry. if one of the later two escapes is sent, their magnitude is coded (the residual) with an order-1 context coder based on the parents MSB (log2 of value) (we use a truncated alphabet then do order-minus-1 on the rest) could try better ways to code residuals ----- S+P Lena lossless : 4.255 bpp ******/ #include#include #include #include #include #include extern int tune_param; /*** some convenient debug routines: ** #define SEND_TAG() if(0); else { arithEncode(ari,43,44,77); } ** #define GET_TAG() if(0); else { int got; got = arithGet(ari,77); arithDecode(ari,43,44,77); if ( got != 43 ) errexit("tag failure"); } ********/ #define CNTX_CAP 10 /** I'm very surprised that this tunes so high! **/ #define SIGMAP_CONTEXTS (CNTX_CAP+CNTX_CAP+1) #define SIGMAP_ALPHABET 5 /** 0,1,-1,pos,neg **/ #define SIGMAP_TOTMAX 5000 #define SIGMAP_INC 30 #define ORDER0_CNTXMAX 8 #define ORDER0_CONTEXTS (ORDER0_CNTXMAX+1) #define ORDER0_TOTMAX 500 #define ORDER0_ALPHABET 25 #define ORDER0_ESCAPE (ORDER0_ALPHABET-1) #include "coder.h" void coderSigMap_encodeBand(coder *me,int *band,int w,int h,int fullw,int *parent); void coderSigMap_decodeBand(coder *me,int *band,int w,int h,int fullw,int *parent); typedef struct { ozero ** o0; scontext ** o1; } myInfo; void coderSigMap_init(coder *c) { myInfo *d; int i; if ( (d = new(myInfo)) == NULL ) errexit("ozero init failed"); c->data = d; if ( (d->o0 = newarray(void *,ORDER0_CONTEXTS)) == NULL ) errexit("Order0_Init failed!"); for(i=0;i o0[i] = ozeroCreateMax(c->arith,ORDER0_ALPHABET,ORDER0_TOTMAX)) == NULL ) errexit("ozero init failed"); if ( (d->o1 = newarray(void *,SIGMAP_CONTEXTS)) == NULL ) errexit("Order1_Init failed!"); for(i=0;i o1[i] = scontextCreate(c->arith,SIGMAP_ALPHABET,0, SIGMAP_TOTMAX,SIGMAP_INC,true)) == NULL ) errexit("context creation failed!"); } void coderSigMap_free(coder *c) { if ( c->data ) { myInfo *d; d = c->data; if ( d->o0 ) { int i; for(i=0;i o0[i] ) ozeroFree(d->o0[i]); free(d->o0); } if ( d->o1 ) { int i; for(i=0;i o1[i] ) scontextFree(d->o1[i]); } } free(d); c->data = NULL; } } coder coderSigMap = { "SigMap", coderSigMap_init, coderSigMap_free, coderSigMap_encodeBand, coderSigMap_decodeBand }; void coderSigMap_encodeBand(coder *me,int *band,int width,int height,int fullw,int *parent) { int x,y,val,cntx; int *dp,*pp; int par_val,par_sig; ozero **o0 = ((myInfo *)me->data)->o0; scontext **o1 = ((myInfo *)me->data)->o1; arithInfo *ari = me->arith; dp = band; pp = parent; for(y=0;y >1]; par_val = abs(par_sig); par_sig = max(- CNTX_CAP,min(CNTX_CAP,par_sig)); par_sig += CNTX_CAP; val = dp[x]; switch(val) { case 0: scontextEncode(o1[par_sig],0); break; case 1: scontextEncode(o1[par_sig],1); break; case -1: scontextEncode(o1[par_sig],2); break; default: if ( isneg(val) ){ scontextEncode(o1[par_sig],3); val = -val; } else scontextEncode(o1[par_sig],4); val -= 2; cntx = min(ORDER0_CNTXMAX, intlog2(par_val) ); if ( val < ORDER0_ESCAPE ) ozeroEncode(o0[cntx],val); else { ozeroEncode(o0[cntx],ORDER0_ESCAPE); encode_m1(ari,val - ORDER0_ESCAPE); } break; } } if ( y&1 ) pp += fullw; dp += fullw; } } void coderSigMap_decodeBand(coder *me,int *band,int width,int height,int fullw,int *parent) { int x,y,val,cntx,sign; int *dp,*pp; int par_val,par_sig; ozero **o0 = ((myInfo *)me->data)->o0; scontext **o1 = ((myInfo *)me->data)->o1; arithInfo *ari = me->arith; dp = band; pp = parent; for(y=0;y >1]; par_val = abs(par_sig); par_sig = max(- CNTX_CAP,min(CNTX_CAP,par_sig)); par_sig += CNTX_CAP; switch( scontextDecode(o1[par_sig]) ) { case 0: dp[x] = 0; break; case 1: dp[x] = 1; break; case 2: dp[x] = -1; break; case 3: sign = -1; goto decode_val; case 4: sign = 1; decode_val: cntx = min(ORDER0_CNTXMAX, intlog2(par_val) ); val = ozeroDecode(o0[cntx]); if( val == ORDER0_ESCAPE ) val += decode_m1(ari); dp[x] = sign * (val + 2); break; default: errexit("decoded past alphabet!"); } } if ( y&1 ) pp += fullw; dp += fullw; } }