www.pudn.com > xiaobo.zip.zip > coder_o1.c
/********* a straightforward order1 coder : code pel conditioned on the log2(parent) quite competitive S+P Lena lossless : 4.250 bpp **********/ #include#include #include #include #include #include #include extern int tune_param; #define ORDER1_TOTMAX 6000 #define ORDER1_INC 20 #define ORDER1_ALPHABET 16 #define ORDER1_ESCAPE (ORDER1_ALPHABET-1) #define CONTEXT_MAX 6 #define ORDER1_CONTEXTS (CONTEXT_MAX+1) #define CONTEXT(prev) (min(intlog2(abs(prev)+1),CONTEXT_MAX)) #define ORDER0_TOTMAX 2000 #define ORDER0_ALPHABET 50 #define ORDER0_ESCAPE (ORDER0_ALPHABET-1) #include "coder.h" void coderOone_encodeBand(coder *me,int *band,int w,int h,int fullw,int *parent); void coderOone_decodeBand(coder *me,int *band,int w,int h,int fullw,int *parent); typedef struct { ozero * o0; scontext ** o1; } myInfo; void coderOone_init(coder *c) { myInfo *d; int i; if ( (d = new(myInfo)) == NULL ) errexit("ozero init failed"); c->data = d; if ( (d->o0 = ozeroCreateMax(c->arith,ORDER0_ALPHABET,ORDER0_TOTMAX)) == NULL ) errexit("ozero init failed"); if ( (d->o1 = newarray(void *,ORDER1_CONTEXTS)) == NULL ) errexit("Order1_Init failed!"); for(i=0;i o1[i] = scontextCreate(c->arith,ORDER1_ALPHABET,0, ORDER1_TOTMAX,ORDER1_INC,true)) == NULL ) errexit("context creation failed!"); } } void coderOone_free(coder *c) { if ( c->data ) { myInfo *d; d = c->data; if ( d->o0 ) ozeroFree(d->o0); if ( d->o1 ) { int i; for(i=0;i o1[i] ) scontextFree(d->o1[i]); } } free(d); c->data = NULL; } } coder coderOone = { "order one", coderOone_init, coderOone_free, coderOone_encodeBand, coderOone_decodeBand }; void coderOone_encodeBand(coder *me,int *band,int width,int height,int fullw,int *parent) { int x,y,val,cntx,sign; int *dp,*pp; 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)]); val = dp[x]; if ( val == 0 ) { scontextEncode(o1[cntx],0); continue; } else if ( isneg(val) ) { sign = 1; val = -val; } else sign = 0; if ( val < ORDER1_ESCAPE ) { scontextEncode(o1[cntx],val); } else { scontextEncode(o1[cntx],ORDER1_ESCAPE); val -= ORDER1_ESCAPE; while( val >= ORDER0_ESCAPE ) { ozeroEncode(o0,ORDER0_ESCAPE); val -= ORDER0_ESCAPE; } ozeroEncode(o0,val); } arithBit(ari,sign); } if ( y & 1 ) pp += fullw; dp += fullw; } } void coderOone_decodeBand(coder *me,int *band,int width,int height,int fullw,int *parent) { int x,y,val,cntx,got; int *dp,*pp; 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)]); got = scontextDecode(o1[cntx]); if ( got == 0 ) { dp[x] = 0; continue; } else if ( got < ORDER1_ESCAPE ) { val = got; } else { val = ORDER1_ESCAPE; got = ozeroDecode(o0); while ( got == ORDER0_ESCAPE ) { val += ORDER0_ESCAPE; got = ozeroDecode(o0); } val += got; } if ( arithGetBit(ari) ) val = -val; dp[x] = val; } if ( y & 1 ) pp += fullw; dp += fullw; } }