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;io1[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;io1[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; 
	} 
}