www.pudn.com > EzwCode.zip > EzwCode.cpp


// EzwCode.cpp: implementation of the CEzwCode class. 
// 
////////////////////////////////////////////////////////////////////// 
 
#include "stdafx.h" 
#include "ImageCode.h" 
#include "EzwCode.h" 
 
#include  
 
#ifdef _DEBUG 
#undef THIS_FILE 
static char THIS_FILE[]=__FILE__; 
#define new DEBUG_NEW 
#endif 
 
#define NUL -1 
#define IZ  0 
#define ZTR 1 
#define POS 2 
#define NEG 3 
////////////////////////////////////////////////////////////////////// 
// Construction/Destruction 
////////////////////////////////////////////////////////////////////// 
 
CEzwCode::CEzwCode() 
{ 
	 
} 
 
CEzwCode::~CEzwCode() 
{ 
	//HeapFree(GetProcessHeap(),0,EzwDV); 
	//HeapFree(GetProcessHeap(),0,EzwSV); 
} 
 
bool CEzwCode::EzwQualitition(int minthr,int datheight,int datwidth) 
{ 
	int i,j,thr,tem,num[4]={0,0,0,0},totalnum=0; 
	//int *BufIn,*BufBigIn; 
	float pro[4];//各个符号出现的概率 
	//read data 
	//int *ptemp; 
	 EzwIn=(int *)HeapAlloc(GetProcessHeap(),0,datheight*datwidth*sizeof(int)); 
	 EzwBigIn=(int *)HeapAlloc(GetProcessHeap(),0,datheight*datwidth*sizeof(int)); 
	//ptemp=EzwIn; 
	CFile *Dat_File=new CFile(); 
	LPCTSTR lpszFilter="Disc Wavelet Trans Files(*.dwt)|*.dwt|任何文件|*.*||"; 
	CFileDialog *OpenDlg=new CFileDialog( TRUE, lpszFilter, "LENA",OFN_HIDEREADONLY|OFN_PATHMUSTEXIST|OFN_OVERWRITEPROMPT|OFN_NOCHANGEDIR, lpszFilter ); 
    if(OpenDlg->DoModal()==IDOK) 
		Dat_File->Open(OpenDlg->GetPathName(),CFile::modeRead|CFile::typeBinary,NULL); 
	else 
		return 0; 
	//int max=0; 
	for(i=0;iRead(&EzwIn[i*datwidth+j],sizeof(int)); 
			//EzwIn[i*datdidth,j 
			//ptemp++; 
			EzwBigIn[i*datwidth+j]=0; 
			//TRACE("(%d %d)",EzwIn[i+datwidth+j],EzwBigIn[i*datwidth+j]); 
			 
		} 
	delete OpenDlg; 
	Dat_File->Close(); 
	delete Dat_File; 
	//Produce DominateChart 
	FirstFactor(datheight,datwidth,EzwIn);//找到最大值max,log2(max)向上取整-1 
	 
	Thresholdnum=TreFstFtr-minthr+1; 
	 
	BufDv=(int *)HeapAlloc(GetProcessHeap(),0,Thresholdnum*datheight*datwidth*sizeof(int)); 
		 
		//生成对bufSv的二维数组索引: 
		EzwDV=new int*[Thresholdnum]; 
		for(i=0;i=0;thr--) 
		for(i=0;i=0;thr--) 
	{ 
		//处理主表 
		for(i=0;i0) 
							//为正数,记为P 
						{ 
							EzwDV[thr][i*datwidth+j]=POS; 
							num[POS]++; 
						} 
						else 
						{	//为负数,记为N 
							EzwDV[thr][i*datwidth+j]=NEG; 
							num[NEG]++; 
						} 
						//将重要数据转移到EzeBigIn数组中,原数置零 
						EzwBigIn[i*datwidth+j]=EzwIn[i*datwidth+j];//if not 0 this piont ready to produce sub-chart 
						EzwIn[i*datwidth+j]=0; 
					} 
		//Produce sub-chart 
		//处理附表 
		if((thr!=0)||(minthr!=0)) 
			//不是最后一次,最小阈值不为零 
			for(i=0;i=0;thr--) 
	{	 
		fprintf(fp,"\n\n***threshold=%d***\n",thr); 
		for(i=0;i IZ,ZTR,POS,NEG 
	for(i=0;i<4;i++) 
		EzwDVOfPro[i]=i;//存放主表中四个符号出现概率的顺序 
	for(i=0;i<4;i++) 
		totalnum+=num[i];//总符号数 
	for(i=0;i<4;i++) 
		pro[i]=(float)num[i]/totalnum;//各个符号出现的概率 
	//order Probability of dom chart value: IZ,ZTR,POS,NEG 
	for(i=0;i<3;i++) 
		for(j=i;j<4;j++) 
			if(pro[i]<=pro[j]) 
				//将主表中四个符号的出现顺序从大到小排序 
			{ 
				float temp=pro[i]; 
				tem=EzwDVOfPro[i]; 
				pro[i]=pro[j]; 
				EzwDVOfPro[i]=EzwDVOfPro[j]; 
				pro[j]=temp; 
				EzwDVOfPro[j]=tem; 
			} 
	for(i=0;i<4;i++) 
			TRACE("pro[%d]=%f,EzwDVOfPro[%d]=%d\n",i,pro[i],i,EzwDVOfPro[i]); 
	return 1; 
} 
 
bool CEzwCode::HuffmanEncode(int minthr,int datheight,int datwidth) 
{ 
	//build  output map:ZTR,POS,IZ,NEG->0,1,2,3 
	 
	int i,j,k,thr,OrdOfHuff[4]; 
	//int EzwDVOfPro[4]; 
	for(i=0;i<4;i++) 
		OrdOfHuff[EzwDVOfPro[i]]=i; 
	//输出1的个数,概率最大的为0个(ZTR) 
	//最小的为3个,合乎huffman编码的规律 
	//Write DV SV  to fp,in the sequence of common line and volumn 
	mask = 0x80; 
	output_byte = 0; 
	ones=0; 
	zeroes=0; 
 
	 
	CFile *pFile=new CFile(); 
	LPCTSTR lpszFilter="EZW Files(*.ezw)|*.ezw|任何文件|*.*||"; 
	CFileDialog *SaveDlg=new CFileDialog (FALSE, lpszFilter, "LENA",OFN_HIDEREADONLY|OFN_PATHMUSTEXIST|OFN_OVERWRITEPROMPT|OFN_NOCHANGEDIR,lpszFilter ); 
    if(SaveDlg->DoModal()==IDOK) 
		pFile->Open(SaveDlg->GetPathName(),CFile::modeCreate |CFile::modeWrite|CFile::typeBinary,NULL); 
	else 
	{ 
		::AfxMessageBox("cannot open file to write !"); 
		return 0; 
	} 
	//if((fp=fopen("Huffman1.ezw","wb"))!=NULL) 
	{ 
		TRACE("open file successfully !\n"); 
		//头文件 
		pFile->Write (&TreFstFtr,sizeof(TreFstFtr));//实际上是int型变量,最大阈值 
		//fwrite(&TreFstFtr,sizeof(TreFstFtr),1,fp); 
		//for(i=0;i<4;i++) 
		//	fwrite(&EzwDVOfPro[i],sizeof(int),1,fp); 
		pFile->Write (EzwDVOfPro,4*sizeof(int)); 
		//四种符号从大到小的顺序,整数表示,参照头文件中的定义 
		//文件数据 
		for(thr=TreFstFtr-minthr;thr>=0;thr--) 
		{ 
			//主表数据 
			for(i=0;i=0)) 
					{ 
						for(k=OrdOfHuff[EzwDV[thr][i*datwidth+j]];k>0;k--) 
							PutBit('1',pFile); 
						if((OrdOfHuff[EzwDV[thr][i*datwidth+j]]<3)&&(OrdOfHuff[EzwDV[thr][i*datwidth+j]]>=0)) 
							PutBit('0',pFile); 
					} 
			//附表数据 
			if((thr!=0)||(minthr!=0)) 
				for(i=0;iClose(); 
	delete pFile; 
	 
	return 1; 
} 
 
bool CEzwCode::PrtsIsZTR(int thr,int i,int j,int datheight,int datwidth) 
{	//判断某结点是否为零树的子孙 
	if((i==0)&&(j==0))//根节点,非零树子孙 
		return 0; 
	int k=(int)floor(i/2);//父节点 
	int l=(int)floor(j/2); 
	if(EzwDV[thr][k*datwidth+l]==ZTR)//查找主系数表 
		return 1; 
	else 
		return PrtsIsZTR(thr,k,l,datheight,datwidth);//递归调用 
} 
 
bool CEzwCode::ChldIsMin(int thr,int i, int j,int datheight,int datwidth) 
//用于判定某节点为零树还是孤立零点(子孙是否量化为0) 
{ 
	int k,l,ElgFactor=1; 
	while((i=(int)pow(2,thr)) 
					return 0; 
		i*=2; 
		j*=2; 
		ElgFactor+=1; 
	} 
	return 1; 
} 
 
void CEzwCode::FirstFactor(int datheight,int datwidth,int *Ez) 
{	//寻找最大量化阈值 
	int max=0; 
	for(int i=0;imax) 
			{ 
				max=abs(Ez[i*datwidth+j]); 
				TRACE("(%d %d)",Ez[i*datwidth+j],max); 
			} 
	TreFstFtr=int(ceil(log10(max)/log10(2))-1); 
	//找到最大值max,log2(max)向上取整-1; 
	TRACE("the max is %d ,the TreFstFtr is %d\n",max,TreFstFtr); 
} 
 
int CEzwCode::CalSV( int nowthr,int i,int j,int datheight,int datwidth) 
{ 
	//计算附表值 
	//三个门限值,此时阈值的1 1.5 2倍 
	int low=(int)(pow(2,nowthr)); 
	int middle=(int)(pow(2,nowthr)*1.5); 
	int high=(int)(pow(2,nowthr)*2); 
	while(high<=(int)pow(2,TreFstFtr+1))//不大于最高阈值 
	{ 
		if((abs(EzwBigIn[i*datwidth+j])>=low)&&(abs(EzwBigIn[i*datwidth+j])=middle) 
				return 1;//大于中门限 
			else 
				return 0;//小于中门限 
		low+=int(pow(2,nowthr));//实际价值有待研究 
		//TRACE("I do not thick I can get here!\n"); 
		middle+=int(pow(2,nowthr)); 
		high+=int(pow(2,nowthr)); 
	} 
	return -1;//处错 
} 
 
bool CEzwCode::PutBit(char bit,CFile *pf) 
{  
	//以一个字节为单位输出数据 
	//开始掩模   mask=128=1000 0000 
	//开始output_byte=0  =0000 0000 
	//TRACE("the mask is %d",int(mask)); 
	if (bit=='1')  
	{ 
		output_byte |= mask;//位或 
		ones++; 
	} 
	else  
		zeroes++; 
	//ones zeros 用于计算压缩率 
	mask >>= 1;//右移一位 
	if (mask==0)  
	{	 
		//每8位输出一次,并把mask和output_byte初始化 
		pf->Write(&output_byte,sizeof(output_byte)); 
		//fwrite(&output_byte,sizeof(output_byte),1,fp); 
		output_byte = 0; 
		mask = 0x80; 
	} 
	return 1; 
} 
 
//////////////////// 
int CEzwCode::BitToEzwDV(CFile *pf) 
{ 
	//Reads a code from the input stream,output DV 
	switch (GetBit(pf)) //need to change to common style of cal 
	{ 
		case '1': 
			switch (GetBit(pf))  
			{ 
				case '0':  
					return (1); 
				case '1': 
					switch (GetBit(pf))  
					{ 
						case '0':  
							return (2); 
						case '1': 
							return (3);	 
					} 
			} 
			break; 
		case '0': 
	 		return (0); 
			break; 
 
	} 
	//You should never get here. 
	return 1;	 
	//出错 
} 
 
int CEzwCode::BitToEzwSV(CFile *pf) 
{ 
	//Reads a code from the input stream,output SV 
	switch (GetBit(pf)) //need to change to common style of cal 
	{ 
		case '1': 
	 		return (1); 
			break; 
		case '0': 
	 		return (0); 
			break; 
 
	} 
	//You should never get here. 
	return 0; 
} 
 
char CEzwCode::GetBit(CFile *pf) 
{	 
	//以一个字节为单位读入数据 
	 
	unsigned char bit; 
 
	if (mask==0) 
	{ 
		//每8位读一次 
		pf->Read (&input_byte,sizeof(input_byte)); 
		mask = 0x80;//128=1000 0000 
	} 
 
	if ((input_byte&mask)==0)  
	{ 
		bit = '0'; 
		zeroes++; 
	} 
	else  
	{ 
		bit = '1'; 
		ones++; 
	} 
 
	mask >>= 1; 
 
	return (bit); 
} 
 
bool CEzwCode::HuffmanDecode(int minthr,int datheight,int datwidth) 
{ 
	int i,j,thr,Thresholdnum; 
	//int EzwDVOfPro[4]; 
	bool *EzwSVFlag=(bool *)HeapAlloc(GetProcessHeap(),0,datheight*datwidth*sizeof(bool)); 
	//EzwSVFlag=new bool [datheight*datwidth];//判断是否存在附表的标志位数组 
	input_byte = 0; 
	mask = 0; 
	ones=0; 
	zeroes=0; 
	 
	CFile *pFile=new CFile(); 
	LPCTSTR lpszFilter="EZW Files(*.ezw)|*.ezw|任何文件|*.*||"; 
	CFileDialog *SaveDlg=new CFileDialog (TRUE, lpszFilter, "LENA",OFN_HIDEREADONLY|OFN_PATHMUSTEXIST|OFN_OVERWRITEPROMPT|OFN_NOCHANGEDIR,lpszFilter ); 
    if(SaveDlg->DoModal()==IDOK) 
		pFile->Open(SaveDlg->GetPathName(),CFile::modeRead|CFile::typeBinary,NULL); 
	else 
	{ 
		::AfxMessageBox("cannot open file to read !"); 
		return 0; 
	} 
	 
	//if((fp=fopen("Huffman1.ezw","rb"))!=NULL) 
	{ 
		//读头文件 
		pFile->Read (&TreFstFtr,sizeof(TreFstFtr));//读最大量化阈值 
		Thresholdnum=TreFstFtr-minthr+1; 
		BufDv=(int *)HeapAlloc(GetProcessHeap(),0,Thresholdnum*datheight*datwidth*sizeof(int)); 
		 
		//生成对BufDv的二维数组索引: 
		EzwDV=new int*[Thresholdnum]; 
		for(i=0;i=0;thr--) 
				{ 
					EzwDV[thr][i*datwidth+j]=NUL; 
					EzwSV[thr][i*datwidth+j]=-1; 
				} 
			} 
		//for(i=0;i<4;i++) 
			//读入概率分配表,整数表示,参照头文件中的定义 
			pFile->Read (EzwDVOfPro,4*sizeof(int)); 
		for(thr=TreFstFtr-minthr;thr>=0;thr--) 
		{ 
			//读主表 
			for(i=0;iClose(); 
	delete pFile; 
	return 1; 
} 
 
bool CEzwCode::EzwInverseQualitition(int minthr,int datheight,int datwidth) 
{ 
	//零树反量化 
	int i,j,thr,*FlagOut,*EzwOut; 
	FlagOut=(int *)HeapAlloc(GetProcessHeap(),0,datheight*datwidth*sizeof(int)); 
	EzwOut=(int *)HeapAlloc(GetProcessHeap(),0,datheight*datwidth*sizeof(int)); 
	for(i=0;i=0;thr--) 
		for(i=0;i=0;thr--) 
		for(i=0;iDoModal()==IDOK) 
		SaveFile->Open(SaveDlg->GetPathName(),CFile::modeCreate |CFile::modeWrite|CFile::typeBinary,NULL); 
	else 
		return 0; 
	for(i=0;iWrite(&EzwOut[i*datwidth+j],sizeof(int)); 
			//TRACE("out[%d][%d]=%d\n",i,j,EzwOut[i*datwidth+j]); 
		} 
	delete SaveDlg; 
	SaveFile->Close(); 
	delete SaveFile; 
	//delete []EzwOut; 
	HeapFree(GetProcessHeap(),0,EzwOut); 
	return 1; 
}