www.pudn.com > xiaobo.zip.zip > codeR_o1_sb.c
/********* Order1 SB : context-code MSB position like order1+1 , then code residual bits. (o1_sb is good on 'circles' and golf data; competitive with bitplane and order2) S+P (512) Lossless : Lena Zelda Kuha Checa(256) Order1 : 4.250 3.948 3.534 3.406 Order1+1: 4.207 3.911 3.517 3.310 Order1sb: 4.216 3.920 3.510 3.305 We seem to beat 1+1 on the very-compressible files, while we lose on the less compressible files (though this is not a uniform trend; for example we have identical performance on Barbara at 4.678 bpp) SB seams to always beat 1+1 slightly on non-lossless packing, but this is a moot point because BitPlane stomps them both for lossy; (bitplane is behind even plain order1 for lossless; very strange) (bitplane on the lossy and order1+1 on the deltas is the best for lossy+delta , but that's again moot because S+P stomps on lossy+delta). **********/ #include#include #include #include #include #include extern int tune_param; #define ORDER1_TOTMAX 10000 #define ORDER1_INC 30 #define ORDER1_RAWS 2 #define ORDER1_ALPHABET (16 + ORDER1_RAWS) /** # of bits **/ #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 16000 /** totally irrelevant **/ #define ORDER0_ALPHABET 2 /** binary **/ #define ORDER0_INC 10 // #define CODER_ADAPT /** doesn't help **/ #include "coder.h" void coderO1_SB_encodeBand(coder *me,int *band,int w,int h,int fullw,int *parent); void coderO1_SB_decodeBand(coder *me,int *band,int w,int h,int fullw,int *parent); typedef struct { scontext * o0; scontext * sign_sc[3]; scontext ** o1; arithInfo *ari; } myInfo; void coderO1_SB_init(coder *c) { myInfo *d; int i; if ( (d = new(myInfo)) == NULL ) errexit("ozero init failed"); c->data = d; d->ari = c->arith; if ( (d->o0 = scontextCreate(c->arith,ORDER0_ALPHABET,0, ORDER0_TOTMAX,ORDER0_INC,true)) == 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_SB_free(coder *c) { if ( c->data ) { myInfo *d; int i; d = c->data; if ( d->o0 ) scontextFree(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_SB = { "SigBit", coderO1_SB_init, coderO1_SB_free, coderO1_SB_encodeBand, coderO1_SB_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)); } static void encode_val(myInfo *mi,int sym,int context) { if ( sym < ORDER1_RAWS ) { scontextEncode(mi->o1[context],sym); } else { int bits,msb; sym -= (ORDER1_RAWS-1); /** can't use zero **/ bits = intlog2(sym); msb = (1< o1[context],bits+ORDER1_RAWS); /** sym < msb now **/ msb>>=1; for(;msb>=1;msb>>=1) { scontextEncode(mi->o0,(sym&msb)?1:0); } } } static int decode_val(myInfo *mi,int bits,int context) { if ( bits < ORDER1_RAWS ) { return bits; } else { int msb,sym,top; bits -= ORDER1_RAWS; msb = 1< >1;top>=1;top>>=1) { if ( scontextDecode(mi->o0) ) sym += top; } sym += msb + ORDER1_RAWS - 1; return sym; } } static void coder_scaledown(myInfo *mi) { int i; scontextHalve(mi->o0); for(i=0;i<3;i++) scontextHalve(mi->sign_sc[i]); for(i=0;i o1[i]); } void coderO1_SB_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; myInfo *mi = ((myInfo *)me->data); scontext **sign_sc = ((myInfo *)me->data)->sign_sc; scontext **o1 = ((myInfo *)me->data)->o1; #ifdef CODER_ADAPT coder_scaledown(mi); #endif dp = band; pp = parent; for(y=0;y data); scontext **sign_sc = ((myInfo *)me->data)->sign_sc; scontext **o1 = ((myInfo *)me->data)->o1; #ifdef CODER_ADAPT coder_scaledown(mi); #endif dp = band; pp = parent; for(y=0;y