www.pudn.com > wavecode.rar > coder_bp_sorted.c


 
 
/***** 
 
same as the plain old EZ coder_bp.c but we send the quartets in order 
of their parents' magnitude. 
 
sorting usually HURTS compression !? 
 
I thought it would help & mean that TOTMAX could be lower, and the 
parent could be taken out of the context. 
 
sorting *does* help some when we stop early, about 0.1 PSNR or 0.05 RMSE 
	but even this isn't always the case (!) 
 
happily the qsort() is blazing fast and hardly hurts time significantly 
 
*****/ 
 
#include  
#include  
#include  
#include  
#include  
 
extern int tune_param; 
 
#define ORDER1_CONTEXTS		10 
#define ORDER1_ALPHABET		16	//4 bits 
 
#define ORDER1_TOTMAX		14000 
#define ORDER1_INC			30 
 
#include "coder.h" 
 
void coderBPsorted_encodeBandBP(coder *me,int *band,int w,int h,int fullw,int *parent,int); 
void coderBPsorted_decodeBandBP(coder *me,int *band,int w,int h,int fullw,int *parent,int); 
 
typedef struct { 
	scontext ** o1; 
} myInfo; 
 
void coderBPsorted_init(coder *c) 
{ 
myInfo *d; 
int i; 
 
	if ( (d = new(myInfo)) == NULL ) 
		errexit("ozero init failed"); 
 
	c->data = d; 
 
	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 coderBPsorted_free(coder *c) 
{ 
	if ( c->data ) { 
		myInfo *d; 
		d = c->data; 
		if ( d->o1 ) { 
			int i; 
			for(i=0;io1[i] ) scontextFree(d->o1[i]); 
			} 
		} 
		free(d); 
		c->data = NULL; 
	} 
} 
 
coder coderBPsorted = { 
		"BP sorted", 
		coderBPsorted_init, 
		coderBPsorted_free, 
		NULL,NULL, 
		coderBPsorted_encodeBandBP, 
		coderBPsorted_decodeBandBP 
	}; 
 
typedef struct { 
	int parent; 
	int *blockptr; 
} sortType; 
 
int sortTypeCmp(const void * s1,const void *s2) 
{ 
int ret = (((sortType *)s2)->parent - ((sortType *)s1)->parent ); 
	if	( ret == 0 ) { 
		ret = (int)(((sortType *)s2)->blockptr - ((sortType *)s1)->blockptr ); 
	} 
return ret; 
} 
 
void coderBPsorted_encodeBandBP(coder *me,int *band,int width,int height,int fullw,int *parent,int bitmask) 
{ 
int x,y,val,cntx; 
int *dp,*pp,*dpn; 
int context,block,par,A,B,C,D,nparents; 
scontext **o1 = ((myInfo *)me->data)->o1; 
arithInfo *ari = me->arith; 
int donemask,nextmask; 
sortType *sortBlock,*sortPtr; 
 
	for(x= bitmask,nextmask=0; x>2; 
 
	if ( (sortBlock = newarray(sortType,nparents)) == NULL ) 
		{ coder_didstop(me,0); return; } 
 
	sortPtr = sortBlock; 
	for(y=0;y>1)*fullw; 
		for(x=0;xparent = abs(*pp) & nextmask; 
			sortPtr->blockptr = dp; 
			sortPtr++; pp++; dp += 2; 
		} 
	} 
 
	qsort((void *)sortBlock,nparents,sizeof(sortType),sortTypeCmp); 
 
	sortPtr = sortBlock; 
	for(x=0;xblockptr;		dpn = dp + fullw; 
 
		A = abs(dp[0]);		B = abs(dp[1]); 
		C = abs(dpn[0]);	D = abs(dpn[1]); 
 
		context = ((A & donemask)?1:0) + ((B & donemask)?1:0) + ((C & donemask)?1:0) + ((D & donemask)?1:0); 
		if ( sortPtr->parent ) context += 5; 
 
		block = 0; // 4 bits 
		if ( A & bitmask ) block += 1; 
		if ( B & bitmask ) block += 2; 
		if ( C & bitmask ) block += 4; 
		if ( D & bitmask ) block += 8; 
 
		scontextEncode(o1[context],block); 
 
		/** send signs when we see the first 'on' bit **/ 
 
		if ( (A & nextmask) == bitmask ) arithBit(ari, signbit(dp[0]) ); 
		if ( (B & nextmask) == bitmask ) arithBit(ari, signbit(dp[1]) ); 
		if ( (C & nextmask) == bitmask ) arithBit(ari, signbit(dpn[0])); 
		if ( (D & nextmask) == bitmask ) arithBit(ari, signbit(dpn[1])); 
 
		sortPtr++;	 
	} 
 
	free(sortBlock); 
} 
 
void coderBPsorted_decodeBandBP(coder *me,int *band,int width,int height,int fullw,int *parent,int bitmask) 
{ 
int x,y,val,cntx,sign; 
int *dp,*pp,*dpn; 
int top_val,top_bitpn; 
int context,block,A,B,C,D; 
scontext **o1 = ((myInfo *)me->data)->o1; 
arithInfo *ari = me->arith; 
int donemask,nextmask,nparents; 
sortType *sortBlock,*sortPtr; 
 
	for(x= bitmask,nextmask=0; x>2; 
 
	if ( (sortBlock = newarray(sortType,nparents)) == NULL ) 
		return; 
 
	sortPtr = sortBlock; 
	for(y=0;y>1)*fullw; 
		for(x=0;xparent = abs(*pp) & nextmask; 
			sortPtr->blockptr = dp; 
			sortPtr++; pp++; dp += 2; 
		} 
	} 
 
	qsort((void *)sortBlock,nparents,sizeof(sortType),sortTypeCmp); 
 
	// read it out 
 
	sortPtr = sortBlock; 
	for(x=0;xblockptr;		dpn = dp + fullw; 
 
		A = abs(dp[0]);		B = abs(dp[1]); 
		C = abs(dpn[0]);	D = abs(dpn[1]); 
		context = ((A & donemask)?1:0) + ((B & donemask)?1:0) + ((C & donemask)?1:0) + ((D & donemask)?1:0); 
		if ( sortPtr->parent ) context += 5; 
 
		block = scontextDecode(o1[context]); 
 
		if ( block & 1 ) {  
			if ( !A ) dp[0] = arithGetBit(ari)? -bitmask: bitmask; 
			else if ( isneg(dp[0]) ) dp[0] -= bitmask; else dp[0] += bitmask; 
		} 
		if ( block & 2 ) {  
			if ( !B ) dp[1] = arithGetBit(ari)? -bitmask: bitmask; 
			else if ( isneg(dp[1]) ) dp[1] -= bitmask; else dp[1] += bitmask; 
		} 
		if ( block & 4 ) {  
			if ( !C ) dpn[0] = arithGetBit(ari)? -bitmask: bitmask; 
			else if ( isneg(dpn[0]) ) dpn[0] -= bitmask; else dpn[0] += bitmask; 
		} 
		if ( block & 8 ) {  
			if ( !D ) dpn[1] = arithGetBit(ari)? -bitmask: bitmask; 
			else if ( isneg(dpn[1]) ) dpn[1] -= bitmask; else dpn[1] += bitmask; 
		} 
 
		sortPtr++; 
	} 
 
	free(sortBlock); 
}