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;io1[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;io1[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;io1[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;ydata); 
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