www.pudn.com > xiaobo.zip.zip > coder_o1p1.c
//#define SIGN_JUST_XOR /** much worse **/ /********* a straightforward order1 coder : code pel conditioned on the log2(parent) "order1+1" also uses log2(neighbors) in the context Order1 : S+P Lena lossless : 4.250 bpp Order1+1: : 4.207 bpp **********/ #include#include #include #include #include #include #include extern int tune_param; #define ORDER1_TOTMAX 10000 #define ORDER1_INC 15 #define ORDER1_ESCAPE 12 #define ORDER1_ALPHABET (ORDER1_ESCAPE+1) #define CN_MAX_PREV 4 #define CN_MAX_PARENT 4 #define CODE_CONTEXTS (1 + CN_MAX_PREV + (CN_MAX_PREV+1)*CN_MAX_PARENT) #define ORDER0_TOTMAX 2000 /** totally irrelevant **/ #define ORDER0_ESCAPE 1 /** optimal at 1 !!! a unary code!!! **/ #define ORDER0_ALPHABET (ORDER0_ESCAPE+1) #include "coder.h" void coderO1_1_encodeBand(coder *me,int *band,int w,int h,int fullw,int *parent); void coderO1_1_decodeBand(coder *me,int *band,int w,int h,int fullw,int *parent); typedef struct { ozero * o0; scontext * sign_sc[3]; scontext ** o1; } myInfo; void coderO1_1_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"); for(i=0;i<3;i++) { if ( (d->sign_sc[i] = scontextCreate(c->arith,2,0,1000,10,true)) == NULL ) errexit("sign ozero init failed"); } if ( (d->o1 = newarray(void *,CODE_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 coderO1_1_free(coder *c) { if ( c->data ) { myInfo *d; int i; d = c->data; if ( d->o0 ) ozeroFree(d->o0); for(i=0;i<3;i++) { if ( d->sign_sc[i] ) scontextFree(d->sign_sc[i]); } if ( d->o1 ) { for(i=0;i o1[i] ) scontextFree(d->o1[i]); } } free(d); c->data = NULL; } } coder coderO1_1 = { "o1+1", coderO1_1_init, coderO1_1_free, coderO1_1_encodeBand, coderO1_1_decodeBand }; static void mcontext(int *cur_ptr,int parent,int x,int y,int width,int height,int fullw, int *cntx_ptr,int *sign_ptr) { int neighbors; /** cur_ptr[0] is about to be coded **/ if ( x==0 ) { if ( y == 0 ) { neighbors = 0; } else { neighbors = (cur_ptr[-fullw] + cur_ptr[-fullw+1]) >> 1; } } else if ( y == 0 ) { neighbors = cur_ptr[-1]; } else if ( x == (width-1) ) { neighbors = (cur_ptr[-1] + cur_ptr[-fullw] + cur_ptr[-fullw] + cur_ptr[-fullw-1]) >> 2; } else { neighbors = (cur_ptr[-1] + cur_ptr[-fullw] + cur_ptr[-fullw+1] + cur_ptr[-fullw-1]) >> 2; } if ( neighbors == 0 ) *sign_ptr = 2; else if ( isneg(neighbors) ) *sign_ptr = 1; else *sign_ptr = 0; parent = abs(parent); neighbors = abs(neighbors); parent = intlog2(parent+1); neighbors = intlog2(neighbors); *cntx_ptr = min(CN_MAX_PREV,neighbors) + (CN_MAX_PREV+1)*(min(CN_MAX_PARENT,parent)); } void coderO1_1_encodeBand(coder *me,int *band,int width,int height,int fullw,int *parent) { int x,y,val,cntx,sign,sign_cntx; int *dp,*pp,*dpp,*ppp; ozero *o0 = ((myInfo *)me->data)->o0; scontext **sign_sc = ((myInfo *)me->data)->sign_sc; scontext **o1 = ((myInfo *)me->data)->o1; arithInfo *ari = me->arith; dp = band; pp = parent; for(y=0;y = ORDER0_ESCAPE ) { ozeroEncode(o0,ORDER0_ESCAPE); val -= ORDER0_ESCAPE; } ozeroEncode(o0,val); } #ifdef SIGN_JUST_XOR if ( sign_cntx != 2 ) sign ^= sign_cntx; scontextEncode(sign_sc[0],sign); #else scontextEncode(sign_sc[sign_cntx],sign); #endif // SIGN_JUST_XOR } if ( y & 1 ) pp += fullw; dp += fullw; } } void coderO1_1_decodeBand(coder *me,int *band,int width,int height,int fullw,int *parent) { int x,y,val,cntx,got,sign_cntx; int *dp,*pp,*dpp,*ppp; ozero *o0 = ((myInfo *)me->data)->o0; scontext **sign_sc = ((myInfo *)me->data)->sign_sc; scontext **o1 = ((myInfo *)me->data)->o1; arithInfo *ari = me->arith; dp = band; pp = parent; for(y=0;y