www.pudn.com > xiaobo.zip.zip > coder_bp_zt2.c


 
/***** 
 
coder_BP :  
 
	could get more speed out of arithc and soz 
 
	arithc could lose its struct and just code from locals 
 
ALPHA_REMAP does seem to help speed a bit.  The idea of it is to 
make most common symbols lowest in alpha order, so that the 
cheezy soz is as fast as possible 
 
*****/ 
 
#include  
#include  
#include  
#include  
#include  
#include "coder.h" 
 
extern int tune_param; 
 
static int bp_remap[] = {0,1,2,5,3,9,6,11,4,10,7,12,8,13,14,15}; 
static int bp_unmap[] = {0,1,2,4,8,3,6,10,12,5,9,7,11,13,14,15}; 
 
// #define bitModel(bit,P0,PT)		do { PT += INC; if (!(bit)) P0 += INC;  if ( PT > TOTMAX ) { PT >>= 1; P0 >>= 1; P0++; PT += 2; } } while(0) 
#define bitModel(bit,P0,PT)		do { PT += INC; P0 += ((bit)?0:INC);  if ( PT > TOTMAX ) { PT >>= 1; P0 >>= 1; P0++; PT += 2; } } while(0) 
 
#define bitEnc(bit,ari,P0,PT)	do { arithEncBit(ari,P0,PT,bit);	bitModel(bit,P0,PT); } while(0) 
#define bitDec(bit,ari,P0,PT)	do { bit = arithDecBit(ari,P0,PT);	bitModel(bit,P0,PT); } while(0) 
 
#define INC			20 
#define TOTMAX		4000 
 
#define ORDER1_CONTEXTS		5 
#define ORDER1_ALPHABET		16	//4 bits 
 
#define ORDER1_TOTMAX		15000 
#define ORDER1_INC			30 
 
void coderBPZT2_init(coder *c); 
void coderBPZT2_free(coder *c); 
void coderBPZT2_flush(coder *c); 
void coderBPZT2_encodeBandZT(coder *me,int *band,int width,int height,int bits,int fullw,int **rows); 
void coderBPZT2_decodeBandZT(coder *me,int *band,int width,int height,int bits,int fullw,int **rows); 
void coderBPZT2_decodeBandZT_eatZTs(coder *me,int *band,int width,int height,int bits,int fullw,int **rows); 
void coderBPZT2_decodeBandZT_noZTs(coder *me,int *band,int width,int height,int bits,int fullw,int **rows); 
void coderBPZT2_decodeBandZT_ZTs(coder *me,int *band,int width,int height,int bits,int fullw,int **rows); 
 
coder coderBPZT2 = { 
		"BP ZT 2", 
		coderBPZT2_init, 
		coderBPZT2_free, 
		NULL,NULL,NULL,NULL, 
		coderBPZT2_encodeBandZT, 
		coderBPZT2_decodeBandZT 
	}; 
 
typedef struct { 
	soz ** o1; 
	int zeros_p0[ORDER1_CONTEXTS],zeros_pt[ORDER1_CONTEXTS]; 
} myInfo; 
 
void coderBPZT2_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] = sozCreate(c->arith,ORDER1_ALPHABET,ORDER1_TOTMAX,ORDER1_INC)) == NULL ) 
			errexit("context creation failed!"); 
 
		d->zeros_p0[i] = 1; d->zeros_pt[i] = 2; 
	} 
} 
 
void coderBPZT2_flush(coder *c) 
{ 
myInfo *d; 
int i; 
	d = c->data; 
	for(i=0;io1[i]); 
		d->zeros_p0[i] = 1; d->zeros_pt[i] = 2; 
	} 
} 
 
void coderBPZT2_free(coder *c) 
{ 
	if ( c->data ) { 
		myInfo *d; 
		d = c->data; 
		if ( d->o1 ) { 
			int i; 
			for(i=0;io1[i] ) sozFree(d->o1[i]); 
			} 
		} 
		free(d); 
		c->data = NULL; 
	} 
} 
 
 
void coderBPZT2_encodeBandZT(coder *me,int *band,int width,int height,int bits,int fullw,int **rows) 
{ 
int x,y,context,block; 
int *dp,*dpn; 
soz **o1 = ((myInfo *)me->data)->o1; 
arithInfo *ari = me->arith; 
int donemask,nextmask,bitmask; 
int *zeros_p0,*zeros_pt; 
bool bottom; 
 
	zeros_p0 = ((myInfo *)me->data)->zeros_p0; 
	zeros_pt = ((myInfo *)me->data)->zeros_pt; 
 
	if ( width == (fullw >>1) ) bottom = true; 
	else bottom = false; 
 
	bitmask = 1<>1;y--;) { 
		dpn = dp + fullw; 
		for(x=width>>1;x--;) { 
			if ( dp[0] & FLAG_CHILD_ZERO ) { // the whole quartet is zero 
				dp[0] -= FLAG_CHILD_ZERO;	// it's a zerotree child, don't code 
				dp[1] -= FLAG_CHILD_ZERO;	// undo the evil unnecessary work of FindZeroTrees 
				dpn[0] -= FLAG_CHILD_ZERO; 
				dpn[1] -= FLAG_CHILD_ZERO; 
			} else { 
				context = ((dp[0] & donemask)?1:0) + ((dp[1] & donemask)?1:0) + ((dpn[0] & donemask)?1:0) + ((dpn[1] & donemask)?1:0); 
 
/*** 
				block  =  (( dp[0]  & bitmask )?1:0) 
						+ (( dp[1]  & bitmask )?2:0) 
						+ (( dpn[0] & bitmask )?4:0) 
						+ (( dpn[1] & bitmask )?8:0); 
****/ 
				block  =   ( (dp[0]  >>bits) & 1 ) 
						+ (( (dp[1]  >>bits) & 1 )<<1) 
						+ (( (dpn[0] >>bits) & 1 )<<2) 
						+ (( (dpn[1] >>bits) & 1 )<<3); 
 
 
				sozEncode(o1[context],bp_remap[block]); 
 
				if ( ! bottom ) { 
					/** code zerotree flags on any zero bits **/ 
					switch(block) { 
						case 15: 
							break; 
						case 14: 
							if ( dp[0] & FLAG_ISOLATED_ZERO ) {	dp[0] -= FLAG_ISOLATED_ZERO; bitEnc(0,ari,zeros_p0[context],zeros_pt[context]); } else { bitEnc(1,ari,zeros_p0[context],zeros_pt[context]); } 
							break; 
						case 13: 
							if ( dp[1] & FLAG_ISOLATED_ZERO ) {	dp[1] -= FLAG_ISOLATED_ZERO; bitEnc(0,ari,zeros_p0[context],zeros_pt[context]); } else { bitEnc(1,ari,zeros_p0[context],zeros_pt[context]); } 
							break; 
						case 12: 
							if ( dp[0] & FLAG_ISOLATED_ZERO ) {	dp[0] -= FLAG_ISOLATED_ZERO; bitEnc(0,ari,zeros_p0[context],zeros_pt[context]); } else { bitEnc(1,ari,zeros_p0[context],zeros_pt[context]); } 
							if ( dp[1] & FLAG_ISOLATED_ZERO ) {	dp[1] -= FLAG_ISOLATED_ZERO; bitEnc(0,ari,zeros_p0[context],zeros_pt[context]); } else { bitEnc(1,ari,zeros_p0[context],zeros_pt[context]); } 
							break; 
						case 11: 
							if ( dpn[0] & FLAG_ISOLATED_ZERO ) { dpn[0] -= FLAG_ISOLATED_ZERO; bitEnc(0,ari,zeros_p0[context],zeros_pt[context]); } else { bitEnc(1,ari,zeros_p0[context],zeros_pt[context]); } 
							break; 
						case 10: 
							if ( dp[0] & FLAG_ISOLATED_ZERO ) {	dp[0] -= FLAG_ISOLATED_ZERO; bitEnc(0,ari,zeros_p0[context],zeros_pt[context]); } else { bitEnc(1,ari,zeros_p0[context],zeros_pt[context]); } 
							if ( dpn[0] & FLAG_ISOLATED_ZERO ) { dpn[0] -= FLAG_ISOLATED_ZERO; bitEnc(0,ari,zeros_p0[context],zeros_pt[context]); } else { bitEnc(1,ari,zeros_p0[context],zeros_pt[context]); } 
							break; 
						case 9: 
							if ( dp[1] & FLAG_ISOLATED_ZERO ) {	dp[1] -= FLAG_ISOLATED_ZERO; bitEnc(0,ari,zeros_p0[context],zeros_pt[context]); } else { bitEnc(1,ari,zeros_p0[context],zeros_pt[context]); } 
							if ( dpn[0] & FLAG_ISOLATED_ZERO ) { dpn[0] -= FLAG_ISOLATED_ZERO; bitEnc(0,ari,zeros_p0[context],zeros_pt[context]); } else { bitEnc(1,ari,zeros_p0[context],zeros_pt[context]); } 
							break; 
						case 8: 
							if ( dp[0] & FLAG_ISOLATED_ZERO ) {	dp[0] -= FLAG_ISOLATED_ZERO; bitEnc(0,ari,zeros_p0[context],zeros_pt[context]); } else { bitEnc(1,ari,zeros_p0[context],zeros_pt[context]); } 
							if ( dp[1] & FLAG_ISOLATED_ZERO ) {	dp[1] -= FLAG_ISOLATED_ZERO; bitEnc(0,ari,zeros_p0[context],zeros_pt[context]); } else { bitEnc(1,ari,zeros_p0[context],zeros_pt[context]); } 
							if ( dpn[0] & FLAG_ISOLATED_ZERO ) { dpn[0] -= FLAG_ISOLATED_ZERO; bitEnc(0,ari,zeros_p0[context],zeros_pt[context]); } else { bitEnc(1,ari,zeros_p0[context],zeros_pt[context]); } 
							break; 
						case 7: 
							if ( dpn[1] & FLAG_ISOLATED_ZERO ) { dpn[1] -= FLAG_ISOLATED_ZERO; bitEnc(0,ari,zeros_p0[context],zeros_pt[context]); } else { bitEnc(1,ari,zeros_p0[context],zeros_pt[context]); } 
							break; 
						case 6: 
							if ( dp[0] & FLAG_ISOLATED_ZERO ) {	dp[0] -= FLAG_ISOLATED_ZERO; bitEnc(0,ari,zeros_p0[context],zeros_pt[context]); } else { bitEnc(1,ari,zeros_p0[context],zeros_pt[context]); } 
							if ( dpn[1] & FLAG_ISOLATED_ZERO ) { dpn[1] -= FLAG_ISOLATED_ZERO; bitEnc(0,ari,zeros_p0[context],zeros_pt[context]); } else { bitEnc(1,ari,zeros_p0[context],zeros_pt[context]); } 
							break; 
						case 5: 
							if ( dp[1] & FLAG_ISOLATED_ZERO ) {	dp[1] -= FLAG_ISOLATED_ZERO; bitEnc(0,ari,zeros_p0[context],zeros_pt[context]); } else { bitEnc(1,ari,zeros_p0[context],zeros_pt[context]); } 
							if ( dpn[1] & FLAG_ISOLATED_ZERO ) { dpn[1] -= FLAG_ISOLATED_ZERO; bitEnc(0,ari,zeros_p0[context],zeros_pt[context]); } else { bitEnc(1,ari,zeros_p0[context],zeros_pt[context]); } 
							break; 
						case 4: 
							if ( dp[0] & FLAG_ISOLATED_ZERO ) {	dp[0] -= FLAG_ISOLATED_ZERO; bitEnc(0,ari,zeros_p0[context],zeros_pt[context]); } else { bitEnc(1,ari,zeros_p0[context],zeros_pt[context]); } 
							if ( dp[1] & FLAG_ISOLATED_ZERO ) {	dp[1] -= FLAG_ISOLATED_ZERO; bitEnc(0,ari,zeros_p0[context],zeros_pt[context]); } else { bitEnc(1,ari,zeros_p0[context],zeros_pt[context]); } 
							if ( dpn[1] & FLAG_ISOLATED_ZERO ) { dpn[1] -= FLAG_ISOLATED_ZERO; bitEnc(0,ari,zeros_p0[context],zeros_pt[context]); } else { bitEnc(1,ari,zeros_p0[context],zeros_pt[context]); } 
							break; 
						case 3: 
							if ( dpn[0] & FLAG_ISOLATED_ZERO ) { dpn[0] -= FLAG_ISOLATED_ZERO; bitEnc(0,ari,zeros_p0[context],zeros_pt[context]); } else { bitEnc(1,ari,zeros_p0[context],zeros_pt[context]); } 
							if ( dpn[1] & FLAG_ISOLATED_ZERO ) { dpn[1] -= FLAG_ISOLATED_ZERO; bitEnc(0,ari,zeros_p0[context],zeros_pt[context]); } else { bitEnc(1,ari,zeros_p0[context],zeros_pt[context]); } 
							break; 
						case 2: 
							if ( dp[0] & FLAG_ISOLATED_ZERO ) {	dp[0] -= FLAG_ISOLATED_ZERO; bitEnc(0,ari,zeros_p0[context],zeros_pt[context]); } else { bitEnc(1,ari,zeros_p0[context],zeros_pt[context]); } 
							if ( dpn[0] & FLAG_ISOLATED_ZERO ) { dpn[0] -= FLAG_ISOLATED_ZERO; bitEnc(0,ari,zeros_p0[context],zeros_pt[context]); } else { bitEnc(1,ari,zeros_p0[context],zeros_pt[context]); } 
							if ( dpn[1] & FLAG_ISOLATED_ZERO ) { dpn[1] -= FLAG_ISOLATED_ZERO; bitEnc(0,ari,zeros_p0[context],zeros_pt[context]); } else { bitEnc(1,ari,zeros_p0[context],zeros_pt[context]); } 
							break; 
						case 1: 
							if ( dp[1] & FLAG_ISOLATED_ZERO ) {	dp[1] -= FLAG_ISOLATED_ZERO; bitEnc(0,ari,zeros_p0[context],zeros_pt[context]); } else { bitEnc(1,ari,zeros_p0[context],zeros_pt[context]); } 
							if ( dpn[0] & FLAG_ISOLATED_ZERO ) { dpn[0] -= FLAG_ISOLATED_ZERO; bitEnc(0,ari,zeros_p0[context],zeros_pt[context]); } else { bitEnc(1,ari,zeros_p0[context],zeros_pt[context]); } 
							if ( dpn[1] & FLAG_ISOLATED_ZERO ) { dpn[1] -= FLAG_ISOLATED_ZERO; bitEnc(0,ari,zeros_p0[context],zeros_pt[context]); } else { bitEnc(1,ari,zeros_p0[context],zeros_pt[context]); } 
							break; 
						case 0: 
							if ( dp[0] & FLAG_ISOLATED_ZERO ) {	dp[0] -= FLAG_ISOLATED_ZERO; bitEnc(0,ari,zeros_p0[context],zeros_pt[context]); } else { bitEnc(1,ari,zeros_p0[context],zeros_pt[context]); } 
							if ( dp[1] & FLAG_ISOLATED_ZERO ) {	dp[1] -= FLAG_ISOLATED_ZERO; bitEnc(0,ari,zeros_p0[context],zeros_pt[context]); } else { bitEnc(1,ari,zeros_p0[context],zeros_pt[context]); } 
							if ( dpn[0] & FLAG_ISOLATED_ZERO ) { dpn[0] -= FLAG_ISOLATED_ZERO; bitEnc(0,ari,zeros_p0[context],zeros_pt[context]); } else { bitEnc(1,ari,zeros_p0[context],zeros_pt[context]); } 
							if ( dpn[1] & FLAG_ISOLATED_ZERO ) { dpn[1] -= FLAG_ISOLATED_ZERO; bitEnc(0,ari,zeros_p0[context],zeros_pt[context]); } else { bitEnc(1,ari,zeros_p0[context],zeros_pt[context]); } 
							break; 
					} 
				} 
			} 
			dp += 2; dpn += 2; 
		} 
		dp += fullw + fullw - width; 
	} 
 
} 
 
void coderBPZT2_decodeBandZT(coder *me,int *band,int width,int height,int bits,int fullw,int **rows) 
{ 
bool bottom; 
 
	if ( width == (fullw >>1) ) bottom = true; 
	else bottom = false; 
 
 
	if ( bottom ) { 
		coderBPZT2_decodeBandZT_noZTs(me,band,width,height,bits,fullw,rows); 
	} else { 
		coderBPZT2_decodeBandZT_ZTs(me,band,width,height,bits,fullw,rows); 
	} 
 
} 
 
void coderBPZT2_decodeBandZT_noZTs(coder *me,int *band,int width,int height,int bits,int fullw,int **rows) 
{ 
int x,y,context,block; 
int *dp,*dpn; 
soz **o1 = ((myInfo *)me->data)->o1; 
arithInfo *ari = me->arith; 
int donemask,nextmask,bitmask; 
 
	bitmask = 1<data)->o1; 
arithInfo *ari = me->arith; 
int donemask,nextmask,bitmask; 
int offwidth,offheight,*children; 
int bit,tx,ty; 
int *zeros_p0,*zeros_pt; 
 
	zeros_p0 = ((myInfo *)me->data)->zeros_p0; 
	zeros_pt = ((myInfo *)me->data)->zeros_pt; 
 
	bitmask = 1<