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


 
// <> "stop" functionality needed 
 
//#define WRITE_ZT 
#define WRITE_ZT_PLANE 7 
 
#include  
#include  
#include  
#include  
#include  
#include  
#include "coder.h" 
#include "image.h" 
 
#define SIGN_CONTEXTS		4 
 
#define TOTMAX			4000 
#define INC				30 
 
#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 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) 
 
typedef struct { 
	arithInfo *ari; 
	int signs_p0[SIGN_CONTEXTS],signs_pt[SIGN_CONTEXTS]; 
} signInfo; 
 
void * initSigns(arithInfo *ari); 
void freeSigns(void *sign_coder); 
 
void encodeSigns(signInfo *me,int *band,int w,int h,int fullw,int *parent); 
void decodeSigns(signInfo *me,int *band,int w,int h,int fullw,int *parent); 
 
void * initSigns(arithInfo *ari) 
{ 
signInfo *d; 
int i; 
 
	if ( (d = new(signInfo)) == NULL ) 
		errexit("ozero init failed"); 
 
	d->ari = ari; 
 
	for(i=0;isigns_p0[i] = 100; 
		d->signs_pt[i] = 200; 
	} 
return d; 
} 
 
void freeSigns(signInfo *d) 
{ 
	if ( d ) { 
		free(d); 
	} 
} 
 
void encodeSigns(signInfo *me,int *band,int width,int height,int fullw,int *parent) 
{ 
int x,y,context; //,V; 
int *dp; 
arithInfo *ari; 
int *signs_p0,*signs_pt; 
 
	ari = me->ari; 
	signs_p0 = me->signs_p0; 
	signs_pt = me->signs_pt; 
 
	dp = band; 
 
	for(x=0;xari; 
	signs_p0 = me->signs_p0; 
	signs_pt = me->signs_pt; 
 
	dp = band; 
 
	for(x=0;xwidth; 
	for(p=0;pplanes;p++) { 
 
		for(l=1;lwidth) >>l; 
			h = (im->height)>>l; 
			wt = w>>1; 
			ht = h>>1; 
			fmband = im->data[p][h *offy] + w *offx; 
			toband = im->data[p][ht*offy] + wt*offx; 
 
			fmp = fmband; top = toband; 
			for(y=0;yencodeBandZT ) errexit("don't call imageZT unless you mean it!"); 
 
	top_val = 0; 
 
	for(p=0;pplanes;p++) { 
		rows = im->data[p]; 
 
		/** global pre-pass : remove signs & find top_val **/ 
 
		sizeX = (im->width) >> levels; 
		sizeY = (im->height) >> levels; 
		for(y=0;y<(im->height);y++) { 
			dp = rows[y]; 
			if ( y < sizeY ) { x = sizeX; dp += sizeX; } 
			else x = 0; 
			for(;x<(im->width);x++) { 
				if ( isneg(*dp) ) *dp = 1 - (*dp + *dp); 
				else *dp += *dp; 
				if ( *dp > top_val ) top_val = *dp; 
				dp++; 
			} 
		} 
	} 
 
	for(top_bitpn=0;(1<<(top_bitpn+1))<=top_val;top_bitpn++) ; 
 
	cu_putExpanding_ari(top_bitpn,encoder->arith,16,8); 
 
	for(bits = top_bitpn;bits>=1;bits--) { 
		findZeroTrees(im,bits,levels,1,0); 
		findZeroTrees(im,bits,levels,0,1); 
		findZeroTrees(im,bits,levels,1,1); 
 
#ifdef WRITE_ZT 
		if ( bits == WRITE_ZT_PLANE ) {	/** write out a zero tree map **/ 
			image *zt_im; 
			int r,*ptr,bitmask; 
			zt_im = copyImage(im); 
 
			for(p=0;p>im->planes;p++) { 
				ptr = zt_im->data[p][0][0]; bitmask = 1<plane_size;r--;) { 
					if ( *ptr & bitmask ) *ptr++ = 255; 
					else {  
						*ptr = ((*ptr>>(CODE_MAX_BPN+1))<<6); ptr++;  
					} 
					/** 256 is on 
						128	is isolated 
						 64 is child 
						  0 is root 
					****/ 
 
					ptr[-1] -= 0x80; 
				} 
			} 
 
			writeImageFile("zerotree.raw",zt_im); 
 
			freeImage(zt_im); 
		} 
#endif			/** end zero-tree writing **/ 
 
		for (l = levels; l > 0; l--) { 
			sizeX = (im->width) >> l; 
			sizeY = (im->height) >> l; 
 
			for(p=0;pplanes;p++) { 
				rows = im->data[p]; 
 
				encoder->encodeBandZT(encoder,rows[0] + sizeX,	sizeX, sizeY,bits,im->width,rows);  
				encoder->encodeBandZT(encoder,rows[sizeY],		sizeX, sizeY,bits,im->width,rows);  
				encoder->encodeBandZT(encoder,rows[sizeY]+sizeX,sizeX, sizeY,bits,im->width,rows);  
			} 
		} 
	} 
 
	sign_coder = initSigns(encoder->arith);			 
	for(p=0;pplanes;p++) { 
		rows = im->data[p]; 
		for (l = levels; l > 0; l--) { 
			sizeX = (im->width) >> l; 
			sizeY = (im->height) >> l; 
			encodeSigns(sign_coder,rows[0] + sizeX	,	sizeX, sizeY, im->width,rows[0] + (sizeX>>1)); 
			encodeSigns(sign_coder,rows[sizeY]		,	sizeX, sizeY, im->width,rows[(sizeY>>1)]); 
			encodeSigns(sign_coder,rows[sizeY]+sizeX,	sizeX, sizeY, im->width,rows[(sizeY>>1)]+ (sizeX>>1)); 
		} 
	} 
	freeSigns(sign_coder); 
} 
 
void decodeImageZT(coder * decoder,image *im,int levels) 
{ 
int l,sizeX,sizeY,x,y,*dp; 
int **rows; 
int top_bitpn,bits,p; 
void *sign_coder; 
 
	top_bitpn = cu_getExpanding_ari(decoder->arith,16,8); 
 
	for(bits = top_bitpn;bits>=1;bits--) { 
		for (l = levels; l > 0; l--) { 
			for(p=0;pplanes;p++) { 
				rows = im->data[p]; 
 
				sizeX = (im->width) >> l; 
				sizeY = (im->height) >> l; 
 
				decoder->decodeBandZT(decoder,rows[0] + sizeX,	sizeX, sizeY,bits,im->width,rows);  
				decoder->decodeBandZT(decoder,rows[sizeY],		sizeX, sizeY,bits,im->width,rows); 
				decoder->decodeBandZT(decoder,rows[sizeY]+sizeX,sizeX, sizeY,bits,im->width,rows); 
			} 
		} 
	} 
 
	sign_coder = initSigns(decoder->arith); 
	for(p=0;pplanes;p++) { 
		rows = im->data[p]; 
		for (l = levels; l > 0; l--) { 
			sizeX = (im->width) >> l; 
			sizeY = (im->height) >> l; 
 
			decodeSigns(sign_coder,rows[0] + sizeX	,	sizeX, sizeY, im->width,rows[0] + (sizeX>>1)); 
			decodeSigns(sign_coder,rows[sizeY]		,	sizeX, sizeY, im->width,rows[(sizeY>>1)]); 
			decodeSigns(sign_coder,rows[sizeY]+sizeX,	sizeX, sizeY, im->width,rows[(sizeY>>1)]+ (sizeX>>1)); 
		} 
	} 
	freeSigns(sign_coder); 
 
		/** global post-pass : restore signs  
		*	(<> decodeSigns could do this for us, but that would require him to 
		*		do an if() when he builds contexts)  
		**/ 
	 
	for(p=0;pplanes;p++) { 
		rows = im->data[p]; 
		sizeX = (im->width) >> levels; 
		sizeY = (im->height) >> levels; 
		for(y=0;yheight;y++) { 
			dp = rows[y]; 
			if ( y < sizeY ) { x = sizeX; dp += sizeX; } 
			else x = 0; 
			for(;xwidth;x++) { 
				if ( *dp & 1 ) *dp++ = - ((*dp)>>1); 
				else *dp++ >>= 1; 
			} 
		} 
	} 
}