www.pudn.com > wavecode.rar > coder_o2.c
/********* Order2 : o2 on MSB's 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 order2 : 4.222 3.928 3.511 3.308 We're uniformly beaten by the order1 coders. This is strong evidence that we can do no better than order1. (sigh) -> this is not quite right. height data (golf courses) and digitial images (circles & crosses .256) are better under order2 ------ todos : 1. different order0 for each bit-position of residuals, ? (since the lowest bit-pos will be very random, highers should be more zero-skewed) 2. different order1 contexts? average of neighbor & parent? **********/ #include#include #include #include #include extern int tune_param; // #define SMEAR_PARENT // hurts 0.03 !? #define ORDER2_TOTMAX 6000 #define ORDER2_INC 30 #define ORDER2_ESCINC 30 #define ORDER1_TOTMAX 10000 #define ORDER1_INC 30 #define MSB_RAWS 1 #define MSB_ALPHABET (18 + MSB_RAWS) /** # of bits **/ #define O2_MAX_PREV 3 #define O2_MAX_PARENT 5 #define O2_CONTEXTS (1 + O2_MAX_PREV + (O2_MAX_PREV+1)*O2_MAX_PARENT) #define O1_MAX_PARENT 2 /** zero seems optimal, which makes this into order-1, not order-2 ! **/ #define O1_CONTEXTS (O1_MAX_PARENT+1) #define ORDER0_TOTMAX 16000 /** totally irrelevant **/ #define ORDER0_ALPHABET 2 /** binary **/ #define ORDER0_INC 10 #include "coder.h" void coderO2_encodeBand(coder *me,int *band,int w,int h,int fullw,int *parent); void coderO2_decodeBand(coder *me,int *band,int w,int h,int fullw,int *parent); typedef struct { scontext *o0; scontext *sign_sc[3]; scontext **o1,**o2; arithInfo *ari; } myInfo; void coderO2_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 *,O1_CONTEXTS)) == NULL ) errexit("Order1_Init failed!"); for(i=0;i o1[i] = scontextCreate(c->arith,MSB_ALPHABET,0, ORDER1_TOTMAX,ORDER1_INC,true)) == NULL ) errexit("context o1 creation failed!"); } if ( (d->o2 = newarray(void *,O2_CONTEXTS)) == NULL ) errexit("Order2_Init failed!"); for(i=0;i o2[i] = scontextCreate(c->arith,MSB_ALPHABET, ORDER2_ESCINC,ORDER2_TOTMAX,ORDER2_INC,false)) == NULL ) errexit("context o2 creation failed!"); } } void coderO2_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]); } } if ( d->o2 ) { for(i=0;i o2[i] ) scontextFree(d->o2[i]); } } free(d); c->data = NULL; } } coder coderO2 = { "order 2", coderO2_init, coderO2_free, coderO2_encodeBand, coderO2_decodeBand }; static void mcontext(int *cur_ptr,int *parent_ptr,int x,int y,int width,int height,int fullw, int *cntx1_ptr,int *cntx2_ptr,int *sign_ptr) { int neighbors,parent; /** 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; #ifdef SMEAR_PARENT if ( x >= 2 && x < (width-2) ) { parent = abs(parent_ptr[0] + parent_ptr[0] + parent_ptr[-1] + parent_ptr[1] + 2); parent >>= 2; } else { parent = abs(*parent_ptr); } #else parent = abs(*parent_ptr); #endif // SMEAR_PARENT *cntx1_ptr = min(O1_MAX_PARENT,parent); neighbors = abs(neighbors); parent = intlog2(parent+1); neighbors = intlog2(neighbors); *cntx2_ptr = min(O2_MAX_PREV,neighbors) + (O2_MAX_PREV+1)*(min(O2_MAX_PARENT,parent)); } static void encode_val(myInfo *mi,int sym,int cntx1,int cntx2) { if ( sym < MSB_RAWS ) { if ( ! scontextEncode(mi->o2[cntx2],sym) ) scontextEncode(mi->o1[cntx1],sym); } else { int bits,msb; sym -= (MSB_RAWS-1); /** can't use zero **/ bits = intlog2(sym); msb = (1< o2[cntx2],bits) ) scontextEncode(mi->o1[cntx1],bits); /** sym < msb now **/ msb>>=1; for(;msb>=1;msb>>=1) { scontextEncode(mi->o0,(sym&msb)?1:0); } } } static int decode_val(myInfo *mi,int cntx1,int cntx2) { int bits; if ( (bits = scontextDecode(mi->o2[cntx2])) == - 1) { bits = scontextDecode(mi->o1[cntx1]); scontextAdd(mi->o2[cntx2],bits); } if ( bits < MSB_RAWS ) { return bits; } else { int msb,sym,top; bits -= MSB_RAWS; msb = 1< >1;top>=1;top>>=1) { if ( scontextDecode(mi->o0) ) sym += top; } sym += msb + MSB_RAWS - 1; return sym; } } void coderO2_encodeBand(coder *me,int *band,int width,int height,int fullw,int *parent) { int x,y,val,cntx1,cntx2,sign,sign_cntx; int *dp,*pp,*dpp,*ppp; myInfo *mi = ((myInfo *)me->data); scontext **sign_sc = ((myInfo *)me->data)->sign_sc; dp = band; pp = parent; for(y=0;y data); scontext **sign_sc = ((myInfo *)me->data)->sign_sc; dp = band; pp = parent; for(y=0;y