www.pudn.com > xiaobo.zip.zip > coder_sm_b.c
/***** SM2 : send "significance map" then residual values SM2 2 : code the sigmap as four symbols (0,1,2,other) and send signs raw code a quartet (with same parent) smashed together = 8 bits (advantage : a bit faster, and gathers implicitly the dependence on neighbors disadvantage : larger alphabet thins statistics) neither of these helped; this coder is left in as a lesson --- (btw using "scontext" for a 256-char alphabet is really inappropriate; we should correctly use the normal "context" coder with an escape down to an order0) ******/ #include#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 4 #define SIGMAP_CONTEXTS (CNTX_CAP+1) #define SIGMAP_ALPHABET 256 /** 8 bits **/ #define SIGMAP_TOTMAX 15000 #define SIGMAP_INC 10 #define ORDER0_CNTXMAX 8 #define ORDER0_CONTEXTS (ORDER0_CNTXMAX+1) #define ORDER0_TOTMAX 500 #define ORDER0_ALPHABET 25 #define ORDER0_ESCAPE (ORDER0_ALPHABET-1) #define SIG_CNTX(val) min(CNTX_CAP,intlog2(val+1)) /** min(CNTX_CAP,val) **/ #define O0_CNTX(val) min(ORDER0_CNTXMAX, intlog2(val)) #include "coder.h" void coderSM2_encodeBand(coder *me,int *band,int w,int h,int fullw,int *parent); void coderSM2_decodeBand(coder *me,int *band,int w,int h,int fullw,int *parent); typedef struct { ozero ** o0; scontext ** o1; } myInfo; void coderSM2_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 coderSM2_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 coderSM2 = { "SigMap 2", coderSM2_init, coderSM2_free, coderSM2_encodeBand, coderSM2_decodeBand }; static void encode_val(arithInfo *ari,ozero *o0,int val) { if ( isneg(val) ) { arithBit(ari,1); val = -val; } else arithBit(ari,0); if ( val < 3 ) return; val -= 3; if ( val < ORDER0_ESCAPE ) ozeroEncode(o0,val); else { ozeroEncode(o0,ORDER0_ESCAPE); encode_m1(ari,val - ORDER0_ESCAPE); } } static int decode_val(arithInfo *ari,ozero *o0) { int sign,val; if ( arithGetBit(ari) ) sign = -1; else sign = 1; val = ozeroDecode(o0); if( val == ORDER0_ESCAPE ) val += decode_m1(ari); val += 3; return val*sign; } void coderSM2_encodeBand(coder *me,int *band,int width,int height,int fullw,int *parent) { int x,y,A,B,C,D,block; int *dp,*pp,*dpn; int par_val,par_sig,cntx; 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_sig = SIG_CNTX(par_val); cntx = O0_CNTX(par_val); A = dp[x]; B = dp[x+1]; C = dpn[x]; D = dpn[x+1]; block = 0; switch(abs(A)) { case 0: break; case 1: block += 1; break; case 2: block += 2; break; default: block +=3; break; } block <<= 2; switch(abs(B)) { case 0: break; case 1: block += 1; break; case 2: block += 2; break; default: block +=3; break; } block <<= 2; switch(abs(C)) { case 0: break; case 1: block += 1; break; case 2: block += 2; break; default: block +=3; break; } block <<= 2; switch(abs(D)) { case 0: break; case 1: block += 1; break; case 2: block += 2; break; default: block +=3; break; } scontextEncode(o1[par_sig],block); if (D) encode_val(ari,o0[cntx],D); if (C) encode_val(ari,o0[cntx],C); if (B) encode_val(ari,o0[cntx],B); if (A) encode_val(ari,o0[cntx],A); } pp += fullw; dp += fullw + fullw; } } void coderSM2_decodeBand(coder *me,int *band,int width,int height,int fullw,int *parent) { int x,y,block,val; int *dp,*pp,*dpn; int par_val,par_sig,cntx; 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_sig = SIG_CNTX(par_val); cntx = O0_CNTX(par_val); block = scontextDecode(o1[par_sig]); /** go backwards, D,C,B,A **/ switch(block&3) { case 0: val=0; break; case 1: if(arithGetBit(ari)) val=-1; else val=1; break; case 2: if(arithGetBit(ari)) val=-2; else val=2; break; case 3: val = decode_val(ari,o0[cntx]); break; } dpn[x+1] = val; block >>= 2; switch(block&3) { case 0: val=0; break; case 1: if(arithGetBit(ari)) val=-1; else val=1; break; case 2: if(arithGetBit(ari)) val=-2; else val=2; break; case 3: val = decode_val(ari,o0[cntx]); break; } dpn[x] = val; block >>= 2; switch(block&3) { case 0: val=0; break; case 1: if(arithGetBit(ari)) val=-1; else val=1; break; case 2: if(arithGetBit(ari)) val=-2; else val=2; break; case 3: val = decode_val(ari,o0[cntx]); break; } dp[x+1] = val; block >>= 2; switch(block&3) { case 0: val=0; break; case 1: if(arithGetBit(ari)) val=-1; else val=1; break; case 2: if(arithGetBit(ari)) val=-2; else val=2; break; case 3: val = decode_val(ari,o0[cntx]); break; } dp[x] = val; block >>= 2; } pp += fullw; dp += fullw + fullw; } }