⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 codeimage.c

📁 好东西呢
💻 C
字号:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <crblib/inc.h>
#include <crblib/codeutil.h>

#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;y<sizeY;y++) {
				dp = rows[y] + sizeX;
				for(x=sizeX;x<im->width;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<<top_bitpn;

		for(bitmask = top_val;bitmask>=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<<top_bitpn;

		for(bitmask = top_val;bitmask>=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,x,y; //,r
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;y<sizeY;y++) {
			for(x=sizeX;x--;) *aptr++ += *bptr++;
			aptr += im->width - sizeX; bptr += im->width - sizeX;
		}
		aptr = context; bptr =wavelet->data[p][sizeY];
		for(y=0;y<sizeY;y++) {
			for(x=sizeX;x--;) *aptr++ += *bptr++;
			aptr += im->width - 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;y<sizeY;y++) {
		for(x=0;x<sizeX;x++) {
			mse += (*dp) * (*dp);	dp++;
		}
		dp += fullW - sizeX;
	}

return mse;
}

void waveletImage(image *im,wavelet *wave,int transform,
		int qtype,int qflags,double quantizer,
		const coder *coder_template,int stoplen)
{
	wave->transform = 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;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -