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;i Read(&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;i 0) //为正数,记为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;i Close(); 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;i max) { 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;i Close(); 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;i DoModal()==IDOK) SaveFile->Open(SaveDlg->GetPathName(),CFile::modeCreate |CFile::modeWrite|CFile::typeBinary,NULL); else return 0; for(i=0;i Write(&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; }