www.pudn.com > wavecode.rar > 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  
 
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;io1[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;io1[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,sign,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