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


#include  
#include  
#include  
#include  
#include  
 
#include "image.h" 
#include "coder.h" 
#include "codezt.h" 
#include "codeimage.h" 
#include "quantim.h" 
 
/****** 
 
coder.c has no idea what an "image" is. 
image.c has no idea what a "coder is. 
 
only this module (and main.c) know about both. 
 
********/ 
 
int packed_H_Size(image *im,const coder *coder_template,int levels); 
int packed_L_Size(image *im,int levels); 
int packedImageSize(image *im,const coder *coder_template,int levels); 
int packedImageStopErr(image *im,const coder *coder_template,int levels,int stopSize); 
void encodeDeltaIm(coder * encoder,image *im,image *wavelet); 
void encodeImage(coder * encoder,image *im,int levels); 
void decodeImage(coder * decoder,image *im,int levels); 
void encodeLL(coder * encoder,image *im); 
void decodeLL(coder * decoder,image *im); 
 
 
void encodeLL(coder * encoder,image *im) 
{ 
int p; 
	for(p=0;p<(im->planes);p++) 
		coder_encodeDPCM(encoder,im->data[p][0],im->width,im->height,0); 
} 
void decodeLL(coder * decoder,image *im) 
{ 
int p; 
	for(p=0;p<(im->planes);p++) 
		coder_decodeDPCM(decoder,im->data[p][0],im->width,im->height,0); 
} 
 
void encodeImage(coder * encoder,image *im,int levels) 
{ 
int p,l,sizeX,sizeY; 
int **rows; 
 
	if ( encoder->encodeSubbandBP ) 
		errexit("error : this coder is for wavelet packets only"); 
 
	if ( encoder->encodeBandZT ) { 
		encodeImageZT(encoder,im,levels); 
		return; 
	} 
 
	encoder->w->stopline = - 1; 
 
	/** the LL band is already sent **/ 
 
	if ( encoder->encodeBandBP ) { 
		int val,top_val,top_bitpn,bitmask; 
		int *dp,x,y; 
 
		/** <> ; different top_val per plane? **/ 
 
		top_val = 0; 
 
		for(p=0;p<(im->planes);p++) { 
			rows = im->data[p]; 
 
			sizeX = (im->width) >> levels; 
			sizeY = (im->height) >> levels; 
			for(y=0;ywidth;x++) { 
					val = *dp++; if ( val < 0 ) val = -val; 
					if ( val > top_val )  
						top_val = val; 
				} 
			} 
			dp = rows[y]; 
			for(x=(im->height-sizeY)*(im->width);x--;) { 
				val = *dp++; if ( val < 0 ) val = -val; 
				if ( val > top_val )  
					top_val = val; 
			} 
		} 
 
		for(top_bitpn=0;(1<<(top_bitpn+1))<=top_val;top_bitpn++) ; 
 
		cu_putExpanding_ari(top_bitpn,encoder->arith,16,8); 
		top_val = 1<=1;bitmask>>=1) { 
			for (l = levels; l > 0; l--) { 
				sizeX = (im->width) >> l; 
				sizeY = (im->height) >> l; 
 
				for(p=0;p<(im->planes);p++) { 
					rows = im->data[p]; 
 
					if ( ! coder_timetostop(encoder) ) 
						encoder->encodeBandBP(encoder,rows[0] + sizeX,	sizeX, sizeY, im->width, 
							rows[0] + (sizeX>>1),bitmask);  
					if ( ! coder_timetostop(encoder) ) 
						encoder->encodeBandBP(encoder,rows[sizeY],		sizeX, sizeY, im->width, 
							rows[(sizeY>>1)],bitmask); 
					if ( ! coder_timetostop(encoder) ) 
						encoder->encodeBandBP(encoder,rows[sizeY]+sizeX,	sizeX, sizeY, im->width, 
							rows[(sizeY>>1)]+ (sizeX>>1),bitmask); 
				} 
			} 
		} 
	} else { 
		for (l = levels; l > 0; l--) { 
			sizeX = (im->width) >> l; 
			sizeY = (im->height) >> l; 
 
			for(p=0;p<(im->planes);p++) { 
				rows = im->data[p]; 
 
				if ( ! coder_timetostop(encoder) ) 
					encoder->encodeBand(encoder,rows[0] + sizeX,	sizeX, sizeY, im->width, 
						rows[0] + (sizeX>>1));  
				if ( ! coder_timetostop(encoder) ) 
					encoder->encodeBand(encoder,rows[sizeY],		sizeX, sizeY, im->width, 
						rows[(sizeY>>1)]); 
				if ( ! coder_timetostop(encoder) ) 
					encoder->encodeBand(encoder,rows[sizeY]+sizeX,	sizeX, sizeY, im->width, 
						rows[(sizeY>>1)]+ (sizeX>>1));  
			} 
		} 
	} 
 
	if ( encoder->w->stopline < 0 ) encoder->w->stopline = im->height + 1; 
} 
 
void decodeImage(coder * decoder,image *im,int levels) 
{ 
int p,l,sizeX,sizeY; 
int **rows; 
 
	if ( decoder->decodeBandZT ) { 
		decodeImageZT(decoder,im,levels); 
		return; 
	} 
 
	if ( decoder->decodeBandBP ) { 
		int top_val,top_bitpn,bitmask; 
 
		top_bitpn = cu_getExpanding_ari(decoder->arith,16,8); 
		top_val = 1<=1;bitmask>>=1) { 
			for (l = levels; l > 0; l--) { 
				sizeX = (im->width) >> l; 
				sizeY = (im->height) >> l; 
 
				for(p=0;p<(im->planes);p++) { 
					rows = im->data[p]; 
 
					if ( ! coder_timetostopd(decoder,0) ) 
						decoder->decodeBandBP(decoder,rows[0] + sizeX,	sizeX, sizeY, im->width, 
							rows[0] + (sizeX>>1),bitmask);  
					if ( ! coder_timetostopd(decoder,0) ) 
						decoder->decodeBandBP(decoder,rows[sizeY],		sizeX, sizeY, im->width, 
							rows[(sizeY>>1)],bitmask); 
					if ( ! coder_timetostopd(decoder,0) ) 
						decoder->decodeBandBP(decoder,rows[sizeY]+sizeX,	sizeX, sizeY, im->width, 
							rows[(sizeY>>1)]+ (sizeX>>1),bitmask);  
				} 
			} 
		} 
	} else { 
 
		for (l = levels; l > 0; l--) { 
			sizeX = (im->width) >> l; 
			sizeY = (im->height) >> l; 
 
			for(p=0;p<(im->planes);p++) { 
				rows = im->data[p]; 
 
				if ( ! coder_timetostopd(decoder,0) ) 
					decoder->decodeBand(decoder,rows[0] + sizeX,	sizeX, sizeY, im->width, 
						rows[0] + (sizeX>>1));  
				if ( ! coder_timetostopd(decoder,0) ) 
					decoder->decodeBand(decoder,rows[sizeY],		sizeX, sizeY, im->width, 
						rows[(sizeY>>1)]); 
				if ( ! coder_timetostopd(decoder,0) ) 
					decoder->decodeBand(decoder,rows[sizeY]+sizeX,	sizeX, sizeY, im->width, 
						rows[(sizeY>>1)]+ (sizeX>>1));  
			} 
		} 
	} 
} 
 
 
 
 
void encodeDeltaIm(coder * encoder,image *im,image *wavelet) 
{ 
int p,sizeX,sizeY,r,x,y; 
int *context,*aptr,*bptr; 
 
	if ( ! encoder->encodeBand ) { 
		errputs("error : no encoder->encodeBand "); 
		return; 
	} 
 
	for(p=0;p<(im->planes);p++) { 
		sizeX = im->width>>1;	sizeY = im->height>>1; 
 
		context  = wavelet->data[p][sizeY] + sizeX; 
 
		aptr = context; bptr =wavelet->data[p][0] + sizeX; 
		for(y=0;ywidth - sizeX; bptr += im->width - sizeX; 
		} 
		aptr = context; bptr =wavelet->data[p][sizeY]; 
		for(y=0;ywidth - sizeX; bptr += im->width - sizeX; 
		} 
		encoder->encodeBand(encoder,im->data[p][0],im->width,im->height,im->width,context); 
 
		/** average the three big bands in wavelet **/ 
	} 
} 
 
int mseBand(int * plane,int sizeX,int sizeY,int fullW) 
{ 
int x,y; 
int *dp; 
int mse; 
 
	mse = 0; 
 
	dp = plane; 
	for(y=0;ytransform = transform; 
	smartfree(wave->qi); 
 
	wave->qi = doTransQuantIm(im,wave->levels,wave->transform, 
		qtype,qflags,quantizer, 
		stoplen,coder_template); 
	encodeWavelet(im,wave,coder_template,stoplen); 
} 
 
void imageWavelet(image *im,wavelet *wave) 
{ 
	decodeWavelet(im,wave); 
	deTransQuantIm(im,wave->levels,wave->transform,wave->qi); 
} 
 
image * makeImageWavelet(wavelet *wave) 
{ 
image *im; 
	if ( (im = newImage(wave->width,wave->height,wave->planes)) == NULL) return NULL; 
	imageWavelet(im,wave); 
return im; 
} 
 
wavelet * makeWavelet(image *im,const coder *coder_template,int levels,int stoplen) 
{ 
wavelet *wavelet; 
 
	if ( (wavelet = newWavelet(im,levels)) == NULL ) return NULL; 
	encodeWavelet(im,wavelet,coder_template,stoplen); 
 
return wavelet; 
} 
 
void encodeWaveletLL(image *im,wavelet *wavelet) 
{ 
coder *encoder; 
	encoder = coder_create_write(NULL,wavelet,LONG_MAX); 
	encodeLL(encoder,im); 
	coder_flush_write(encoder); 
	coder_destroy(encoder);  
} 
 
 
void decodeWaveletLL(wavelet *wavelet,image *im) 
{ 
coder *decoderLL; 
	if ( (decoderLL = coder_create_read(wavelet)) == NULL ) 
		errexit("decoder_create LL failed!"); 
 
	decodeLL(decoderLL,im); 
 
	coder_flush_read(decoderLL); 
	coder_destroy(decoderLL); 
} 
 
void encodeWavelet(image *im,wavelet *wavelet,const coder *coder_template,int stoplen) 
{ 
coder *encoder; 
	if ( (encoder = coder_create_write(coder_template,wavelet,stoplen)) == NULL ) 
		errexit("coder_create_write failed!"); 
 
	encoder->init(encoder); 
	encodeImage(encoder,im,wavelet->levels); 
	coder_flush_write(encoder); 
	encoder->free(encoder); 
	coder_destroy(encoder); 
} 
 
void decodeWavelet(image *im,wavelet *wavelet) 
{ 
coder *decoder; 
	if ( (decoder = coder_create_read(wavelet)) == NULL ) 
		errexit("decoder_create main failed!"); 
 
	decoder->init(decoder); 
 
	decodeImage(decoder,im,wavelet->levels); 
 
	decoder->free(decoder); 
	coder_flush_read(decoder); 
	coder_destroy(decoder); 
} 
 
void encodeWaveletAndLL(image *im,wavelet *wavelet,const coder *coder_template,int stoplen) 
{ 
coder *encoder; 
int p; 
 
	if ( (encoder = coder_create_write(coder_template,wavelet,stoplen)) == NULL ) 
		errexit("coder_create_write failed!"); 
 
	encoder->init(encoder); 
 
	for(p=0;p<(im->planes);p++) 
		coder_encodeDPCM(encoder,im->data[p][0], 
			(im->width)>>(wavelet->levels),(im->height)>>(wavelet->levels), 
			im->width - ((im->width)>>(wavelet->levels))); 
 
	encodeImage(encoder,im,wavelet->levels); 
	coder_flush_write(encoder); 
	encoder->free(encoder); 
	coder_destroy(encoder); 
} 
 
void decodeWaveletAndLL(image *im,wavelet *wavelet) 
{ 
coder *decoder; 
int p; 
 
	if ( (decoder = coder_create_read(wavelet)) == NULL ) 
		errexit("decoder_create main failed!"); 
 
	decoder->init(decoder); 
 
	for(p=0;p<(im->planes);p++) 
		coder_decodeDPCM(decoder,im->data[p][0], 
			(im->width)>>(wavelet->levels),(im->height)>>(wavelet->levels), 
			im->width - ((im->width)>>(wavelet->levels))); 
 
	decodeImage(decoder,im,wavelet->levels); 
 
	decoder->free(decoder); 
	coder_flush_read(decoder); 
	coder_destroy(decoder); 
} 
 
 
int packedImageStopErr(image *im,const coder *coder_template,int levels,int stopSize) 
{ 
int p,l,sizeX,sizeY,err; 
int **rows; 
coder *encoder; 
wavelet *wavelet; 
 
/** son of a bitch this is a pain in the ass **/ 
 
	stopSize -= packed_L_Size(im,levels); 
 
	wavelet = newWavelet(im,levels); 
	encoder = coder_create_write(coder_template,wavelet,stopSize); 
	encoder->init(encoder); 
 
	if ( ! encoder->encodeBand ) { 
		errputs("error : no encoder->encodeBand "); 
		return 0; 
	} 
 
	encoder->w->stopline = -1; 
 
	err = 0; 
 
	for(p=0;p<(im->planes);p++) { 
		rows = im->data[p]; 
		for (l = levels; l > 0; l--) { 
			sizeX = (im->width) >> l; 
			sizeY = (im->height) >> l; 
 
			if ( coder_timetostop(encoder) ) { 
				err += mseBand(rows[0] + sizeX,	sizeX, sizeY, im->width); 
			} else { 
				encoder->encodeBand(encoder,rows[0] + sizeX,	sizeX, sizeY, im->width, 
					rows[0] + (sizeX>>1));  
				if ( coder_timetostop(encoder) ) { 
					err += mseBand(rows[0] + sizeX + encoder->w->stopline*im->width,	sizeX, sizeY - encoder->w->stopline, im->width); 
				}				 
			} 
 
			if ( coder_timetostop(encoder) ) { 
				err += mseBand(rows[sizeY],	sizeX, sizeY, im->width); 
			} else { 
				encoder->encodeBand(encoder,rows[sizeY],		sizeX, sizeY, im->width, 
					rows[(sizeY>>1)]); 
				if ( coder_timetostop(encoder) ) { 
					err += mseBand(rows[sizeY] + encoder->w->stopline*im->width,	sizeX, sizeY - encoder->w->stopline, im->width); 
				}				 
			} 
 
			if ( coder_timetostop(encoder) ) { 
				err += mseBand(rows[sizeY] + sizeX,	sizeX, sizeY, im->width); 
			} else { 
				encoder->encodeBand(encoder,rows[sizeY]+sizeX,	sizeX, sizeY, im->width, 
					rows[(sizeY>>1)]+ (sizeX>>1));  
				if ( coder_timetostop(encoder) ) { 
					err += mseBand(rows[sizeY] + sizeX + encoder->w->stopline*im->width,	sizeX, sizeY - encoder->w->stopline, im->width); 
				}				 
			} 
		} 
	} 
 
	coder_flush_write(encoder); 
	encoder->free(encoder); 
	coder_destroy(encoder); 
	freeWavelet(wavelet); 
 
return err; 
} 
 
int packedImageSize(image *im,const coder *coder_template,int levels) 
{ 
return( packed_H_Size(im,coder_template,levels) + packed_L_Size(im,levels) ); 
} 
 
int packed_H_Size(image *im,const coder *coder_template,int levels) 
{ 
int complen; 
wavelet *wavelet; 
 
	wavelet = makeWavelet(im,coder_template,levels,LONG_MAX); 
	complen = wavelet->complen - 2; 
	freeWavelet(wavelet); 
 
return complen; 
} 
 
int packed_L_Size(image *im,int levels) 
{ 
int complen; 
image *ll_band; 
int ll_width,ll_height; 
wavelet *wavelet; 
 
	ll_width = im->width>>levels; 
	ll_height = im->height>>levels; 
 
	if ( (ll_band = newImage(ll_width,ll_height,im->planes)) == NULL ) 
		errexit("newImage failed"); 
 
	patchImage(im,ll_band,0,0,ll_width,ll_height,0,0); 
 
	wavelet = newWavelet(ll_band,0); 
 
	encodeWaveletLL(ll_band,wavelet); 
 
	complen = wavelet->complen - 2; 
 
	freeWavelet(wavelet); 
	freeImage(ll_band); 
 
return complen; 
} 
 
int packed_LLband_Size(image *ll_band) 
{ 
int complen; 
wavelet *wavelet; 
 
	wavelet = newWavelet(ll_band,0); 
 
	encodeWaveletLL(ll_band,wavelet); 
 
	complen = wavelet->complen - 2; 
 
	freeWavelet(wavelet); 
 
return complen; 
}