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

📄 decompressdoc.cpp

📁 这是用提升小波变换与嵌入零树编码实现的256色灰度BMP图像压缩与解压缩的程序。
💻 CPP
📖 第 1 页 / 共 5 页
字号:
}

void CDecompressDoc::D97Trans(int height, int width, int **data, int *max, int *min)
{
	//行变换
	int i,j;
    int** s=new int*[width>>1];
	int** d=new int*[width>>1];
	for(i=0;i<(width>>1);i++)
	{
		s[i]=new int[height];
		d[i]=new int[height];
	}
	LineSplit(data,s,d,height,width);
	D97Forecast(s,d,height,width);
	for(i=0;i<height;i++)
	{
		for(j=0;j<width>>1;j++)
		{
			data[i][2*j]=s[j][i];
			data[i][2*j+1]=d[j][i];
		}
	}
    for(i=0;i<(width>>1);i++)
	{
		delete [] s[i];
		delete [] d[i];
	}
	delete [] s;
	delete [] d;

	//列变换
    s=new int*[height>>1];
	d=new int*[height>>1];
	for(i=0;i<(height>>1);i++)
	{
		s[i]=new int[width];
		d[i]=new int[width];
	}
	RowSplit(data,s,d,height,width);
	D97Forecast(s,d,width,height);
	for(i=0;i<height>>1;i++)
	{
		for(j=0;j<width;j++)
		{
			data[2*i][j]=s[i][j];
			data[2*i+1][j]=d[i][j];
			if(data[2*i][j]>*max)
				*max=data[2*i][j];
			else if(data[2*i][j]<*min)
				*min=data[2*i][j];
			if(data[2*i+1][j]>*max)
				*max=data[2*i+1][j];
			else if(data[2*i+1][j]<*min)
				*min=data[2*i+1][j];
		}
	}
	 for(i=0;i<(height>>1);i++)
	{
		delete [] s[i];
		delete [] d[i];
	}
	delete [] s;
	delete [] d;
}


//D97变换预测提升
void CDecompressDoc::D97Forecast(int **s, int **d, int height, int width)
{
	double temp;
	int ttemp;
	double a=-1.586134342;
	double b=-0.05298011854;
	double c=0.8829110762;
	double D=0.4435068522;
	int i,j;
    
	for(i=0;i<width>>1;i++)
	{
		for(j=0;j<height;j++)
		{
			temp=a*(s[i][j]+s[(i+1)%(width>>1)][j])+0.5;
			ttemp=temp;
			d[i][j]=d[i][j]+ttemp;
		}
	}
	for(i=0;i<width>>1;i++)
	{
		for(j=0;j<height;j++)
		{
			if(i==0)
				temp=b*(d[i][j]+d[(width>>1)-1][j])+0.5;
			else
			    temp=b*(d[i][j]+d[i-1][j])+0.5;
			ttemp=temp;
			s[i][j]=s[i][j]+ttemp;
		}
	}
	for(i=0;i<width>>1;i++)
	{
		for(j=0;j<height;j++)
		{
			temp=c*(s[i][j]+s[(i+1)%(width>>1)][j])+0.5;
			ttemp=temp;
            d[i][j]=d[i][j]+ttemp;
		}
	}
    for(i=0;i<width>>1;i++)
	{
		for(j=0;j<height;j++)
		{
			if(i==0)
				temp=D*(d[i][j]+d[(width>>1)-1][j])+0.5;
			else
				temp=D*(d[i][j]+d[i-1][j])+0.5;
			ttemp=temp;
		    s[i][j]=s[i][j]+ttemp;
		}
	}
}
void CDecompressDoc::OnD97Two() 
{
	// TODO: Add your command handler code here
	int linewidth;
	int max, min;  //记录变换后像素的最大最小值
    int** image;   //用于变换的整型图象数据
	int** secondimage;  //存放用于第二层变换的图象数据
	//int temp;  //临时存放映射后的值,再转化为BYTE型
	
	linewidth=(pbi->bmiHeader.biWidth*pbi->bmiHeader.biBitCount+31)/32*4;
    JiFlag=1;  //D97小波
    //生成对lpBuf的二维数组索引
	image=new int*[pbi->bmiHeader.biHeight];
	for(int i=0;i<pbi->bmiHeader.biHeight;i++)
	{
		image[i]=new int[linewidth];
	//	image[i]=(int*)(lpBuf+i*linewidth);
	}
	for(int ii=pbi->bmiHeader.biHeight-1; ii>=0; ii--)
	{
		for(int jj=0; jj<linewidth; jj++)
			image[ii][jj]=*(lpBuf+(pbi->bmiHeader.biHeight-1-ii)*linewidth+jj);
	} 
    max=min=image[0][0];
	D97Trans(pbi->bmiHeader.biHeight,linewidth,image,&max,&min);
	GetCoefficient(image,pbi->bmiHeader.biHeight,linewidth);
	secondimage=new int*[pbi->bmiHeader.biHeight>>1];
	for(int h=0;h<pbi->bmiHeader.biHeight>>1;h++)
	{
		secondimage[h]=new int[linewidth>>1];
	}
	for(int m=0;m<pbi->bmiHeader.biHeight>>1;m++)
	{
		for(int n=0;n<linewidth>>1;n++)
			secondimage[m][n]=image[2*m][2*n];
	}
	D97Trans(pbi->bmiHeader.biHeight>>1,linewidth>>1,secondimage,&max,&min);
	GetCoefficient(secondimage,pbi->bmiHeader.biHeight>>1,linewidth>>1);
    Two_ToLpshowbuf(image,secondimage, &max, &min);
	scale=2;
    //释放内存
	for(int z=0;z<pbi->bmiHeader.biHeight>>1;z++)
	{
		delete [] image[2*z];
		delete [] image[2*z+1];
		delete [] secondimage[z];
	}
	delete [] image;
	delete [] secondimage;

    UpdateAllViews(NULL, 0, NULL);
}

void CDecompressDoc::OnD97Three() 
{
	// TODO: Add your command handler code here
	int linewidth;
	int max, min;  //记录变换后像素的最大最小值
    int** image;   //用于变换的整型图象数据
	int** secondimage;  //存放用于第二层变换的图象数据
	int** threeimage;   //存放用于第三层变换的图象数据
	//int temp;  //临时存放映射后的值,再转化为BYTE型
	linewidth=(pbi->bmiHeader.biWidth*pbi->bmiHeader.biBitCount+31)/32*4;
    JiFlag=1; //D97小波
    //生成对lpBuf的二维数组索引
	image=new int*[pbi->bmiHeader.biHeight];
	for(int i=0;i<pbi->bmiHeader.biHeight;i++)
	{
		image[i]=new int[linewidth];
	//	image[i]=(int*)(lpBuf+i*linewidth);
	}
	for(int ii=pbi->bmiHeader.biHeight-1; ii>=0; ii--)
	{
		for(int jj=0; jj<linewidth; jj++)
			image[ii][jj]=*(lpBuf+(pbi->bmiHeader.biHeight-1-ii)*linewidth+jj);
	} 
    max=min=image[0][0];
	D97Trans(pbi->bmiHeader.biHeight,linewidth,image,&max,&min);
	GetCoefficient(image,pbi->bmiHeader.biHeight,linewidth);
	secondimage=new int*[pbi->bmiHeader.biHeight>>1];
	for(int h=0;h<pbi->bmiHeader.biHeight>>1;h++)
	{
		secondimage[h]=new int[linewidth>>1];
	}
	for(int m=0;m<pbi->bmiHeader.biHeight>>1;m++)
	{
		for(int n=0;n<linewidth>>1;n++)
			secondimage[m][n]=image[2*m][2*n];
	}
	D97Trans(pbi->bmiHeader.biHeight>>1,linewidth>>1,secondimage,&max,&min);
	GetCoefficient(secondimage,pbi->bmiHeader.biHeight>>1,linewidth>>1);
    threeimage=new int*[pbi->bmiHeader.biHeight>>2];
	for(int hh=0;hh<pbi->bmiHeader.biHeight>>2;hh++)
	{
		threeimage[hh]=new int[linewidth>>2];
	}
	for(int mm=0;mm<pbi->bmiHeader.biHeight>>2;mm++)
	{
		for(int nn=0;nn<linewidth>>2;nn++)
			threeimage[mm][nn]=secondimage[2*mm][2*nn];
	}
	D97Trans(pbi->bmiHeader.biHeight>>2,linewidth>>2,threeimage,&max,&min);
	GetCoefficient(threeimage,pbi->bmiHeader.biHeight>>2,linewidth>>2);
	Three_ToLpshowbuf(image,secondimage,threeimage,&max,&min);
	scale=3;
	//释放内存
	for(int z=0;z<pbi->bmiHeader.biHeight>>2;z++)
	{
		delete [] image[4*z];
		delete [] image[4*z+1];
		delete [] image[4*z+2];
		delete [] image[4*z+3];
		delete [] secondimage[2*z];
		delete [] secondimage[2*z+1];
		delete [] threeimage[z];
	}
	delete [] image;
	delete [] secondimage;
	delete [] threeimage;

    UpdateAllViews(NULL, 0, NULL);
}

//D97四层变换
void CDecompressDoc::OnD97Four() 
{
	// TODO: Add your command handler code here
	int linewidth=(pbi->bmiHeader.biWidth*pbi->bmiHeader.biBitCount+31)/32*4;
	int max,min;
	int** image;   //用于变换的整型图象数据
	int** secondimage;  //存放用于第二层变换的图象数据
	int** threeimage;   //存放用于第三层变换的图象数据
	int** fourimage;   //存放用于第四层变换的图象数据
	JiFlag=1;  //D97小波
	
    //生成对lpBuf的二维数组索引
	image=new int*[pbi->bmiHeader.biHeight];
	for(int i=0;i<pbi->bmiHeader.biHeight;i++)
	{
		image[i]=new int[linewidth];
	//	image[i]=(int*)(lpBuf+i*linewidth);
	}
	for(int ii=pbi->bmiHeader.biHeight-1; ii>=0; ii--)
	{
		for(int jj=0; jj<linewidth; jj++)
			image[ii][jj]=*(lpBuf+(pbi->bmiHeader.biHeight-1-ii)*linewidth+jj);
	}
	max=min=image[0][0];
    D97Trans(pbi->bmiHeader.biHeight,linewidth,image,&max,&min);
	GetCoefficient(image,pbi->bmiHeader.biHeight,linewidth);
	secondimage=new int*[pbi->bmiHeader.biHeight>>1];
	for(int h=0;h<pbi->bmiHeader.biHeight>>1;h++)
	{
		secondimage[h]=new int[linewidth>>1];
	}
	for(int m=0;m<pbi->bmiHeader.biHeight>>1;m++)
	{
		for(int n=0;n<linewidth>>1;n++)
			secondimage[m][n]=image[2*m][2*n];
	}
	D97Trans(pbi->bmiHeader.biHeight>>1,linewidth>>1,secondimage,&max,&min);
	GetCoefficient(secondimage,pbi->bmiHeader.biHeight>>1,linewidth>>1);
	threeimage=new int*[pbi->bmiHeader.biHeight>>2];
	for(int hh=0;hh<pbi->bmiHeader.biHeight>>2;hh++)
	{
		threeimage[hh]=new int[linewidth>>2];
	}
	for(int mm=0;mm<pbi->bmiHeader.biHeight>>2;mm++)
	{
		for(int nn=0;nn<linewidth>>2;nn++)
			threeimage[mm][nn]=secondimage[2*mm][2*nn];
	}
	D97Trans(pbi->bmiHeader.biHeight>>2,linewidth>>2,threeimage,&max,&min);
	GetCoefficient(threeimage,pbi->bmiHeader.biHeight>>2,linewidth>>2);
	fourimage=new int*[pbi->bmiHeader.biHeight>>3];
	for(hh=0;hh<pbi->bmiHeader.biHeight>>3;hh++)
	{
		fourimage[hh]=new int[linewidth>>3];
	}
	for(mm=0;mm<pbi->bmiHeader.biHeight>>3;mm++)
	{
		for(int nn=0;nn<linewidth>>3;nn++)
			fourimage[mm][nn]=threeimage[2*mm][2*nn];
	}
	D97Trans(pbi->bmiHeader.biHeight>>3,linewidth>>3,fourimage,&max,&min);
	GetCoefficient(fourimage,pbi->bmiHeader.biHeight>>3,linewidth>>3);
	Four_ToLpshowbuf(image,secondimage,threeimage,fourimage,&max,&min);
	scale=4;

	//释放内存
	for(int z=0;z<pbi->bmiHeader.biHeight>>3;z++)
	{
		delete [] image[8*z];
		delete [] image[8*z+1];
		delete [] image[8*z+2];
		delete [] image[8*z+3];
		delete [] image[8*z+4];
		delete [] image[8*z+5];
		delete [] image[8*z+6];
		delete [] image[8*z+7];
		delete [] secondimage[4*z];
		delete [] secondimage[4*z+1];
	    delete [] secondimage[4*z+2];
		delete [] secondimage[4*z+3];
		delete [] threeimage[2*z];
        delete [] threeimage[2*z+1];
		delete [] fourimage[z];
	}
	delete [] image;
	delete [] secondimage;
	delete [] threeimage;
	delete [] fourimage;

    UpdateAllViews(NULL, 0, NULL);


}
void CDecompressDoc::OnFileSaveAs() 
{
	// TODO: Add your command handler code here
	CString fileName;
	CFile file;

	CString szSaveFilter="BMP Files(*.bmp)|*.bmp|任何文件|*.*||";
	CFileDialog FileDlg(FALSE, "*.bmp",NULL, OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,szSaveFilter,NULL);
	if(FileDlg.DoModal()==IDOK)
	{
		fileName=FileDlg.GetPathName();
		if(file.Open(fileName, CFile::modeCreate | CFile::modeWrite, NULL)==0)
		{
			AfxMessageBox("无法打开文件!", MB_OK, 0);
			return;
		}
		file.Write(&bf,sizeof(bf));
		file.Write(&bi, sizeof(bi));
		file.Write(quad,sizeof(RGBQUAD)*numQuad);
		file.Write(lpshowbuf,bi.biSizeImage);
		file.Close();
	
	}

}


void CDecompressDoc::GetCoefficient(int **date, int height, int width)
{
	for(int i=0;i<height>>1;i++)
	{
		for(int j=0;j<width>>1;j++)
		{
			Coefficient[i][j]=date[2*i][2*j];
			Coefficient[i][j+(width>>1)]=date[2*i][2*j+1];
			Coefficient[i+(height>>1)][j]=date[2*i+1][2*j];
			Coefficient[i+(height>>1)][j+(width>>1)]=date[2*i+1][2*j+1];
		}
	}
}

void CDecompressDoc::OnEZWEncode() 
{
	// TODO: Add your command handler code here
	    CScanNumDlg dlg;
	    dlg.DoModal();
	    int ScanNum=dlg.m_ScanNum;
	    //ChangeMatrix();
	    int linewidth=(pbi->bmiHeader.biWidth*pbi->bmiHeader.biBitCount+31)/32*4;
	    clock_t start, finish;
		double duration;
		start=clock();
	    int max=0;
	    int T1;  //初始阈值
        CNode** AllNode=new CNode*[pbi->bmiHeader.biHeight];
        for(int k=0;k<pbi->bmiHeader.biHeight;k++)
		{
		    AllNode[k]=new CNode[linewidth];
		}
        for(int i=0;i<pbi->bmiHeader.biHeight;i++)
		{
		    for(int j=0;j<linewidth;j++)
			{
			    AllNode[i][j].x=i;
			    AllNode[i][j].y=j;
			    AllNode[i][j].importflag=0;
			    AllNode[i][j].flag=0;
			    AllNode[i][j].coef=Coefficient[i][j];
			    if(AllNode[i][j].coef>max)
				    max=AllNode[i][j].coef;
			    if(i<pbi->bmiHeader.biHeight>>scale && j<linewidth>>scale)
                    AllNode[i][j].scale=scale+1;
			    for(int l=scale-1;l>=0;l--)
				{
				    if(i<pbi->bmiHeader.biHeight>>l && i>=pbi->bmiHeader.biHeight>>(l+1) && j<linewidth>>(l+1))
					{
					    AllNode[i][j].orientation=2;
					    AllNode[i][j].scale=l+1;
					}
			        else if(i<pbi->bmiHeader.biHeight>>l && i>=pbi->bmiHeader.biHeight>>(l+1) && j<linewidth>>l && j>=linewidth>>(l+1))
					{
					    AllNode[i][j].orientation=3;
					    AllNode[i][j].scale=l+1;
					}
				    else if(i<pbi->bmiHeader.biHeight>>(l+1) && j<linewidth>>l && j>=linewidth>>(l+1))
					{
					    AllNode[i][j].orientation=1;
					    AllNode[i][j].scale=l+1;
					}

				}
			}
		}
	    int log=0;
	    while(max>0)
		{
		    max=max>>1;
            log++;
		}
	    T1=1<<(log-1);   //得到初始的阈值
	    //第一次扫描
	    int ScanFlag=1;
		int zhycoefflength=0;
		int T;  //每次扫描的阈值
		int tt;
		CArray <BYTE,BYTE> zhubiao;  //主表
	    zhubiao.SetSize(100,50);
		CArray <BYTE,BYTE> fubiao;  //辅表
		fubiao.SetSize(20,50);
		CArray <int,int> zhycoeff; //用来存放重要系数
		zhycoeff.SetSize(20,50);
		CArray <int,int> tempcoeff;//用来暂时存放前一次扫描所得重要系数
		tempcoeff.SetSize(20,50);
		for(ScanFlag=1;ScanFlag<=ScanNum;ScanFlag++)
		{
			
			T=T1>>(ScanFlag-1);
			zhycoeff.Copy(tempcoeff);
			zhycoefflength=SecondScan(AllNode,T,zhubiao,fubiao,zhycoeff,ScanFlag,zhycoefflength);
            ofstream ofile;
			ofile.open("d:\\zhubiao1.txt");
			ofile<<"the size is"<<zhubiao.GetSize()<<endl;
			for(tt=0;tt<zhubiao.GetSize();tt++)
			{
				ofile<<zhubiao.GetAt(tt);
			    if(((tt+1)%10)==0)
				    ofile<<"  ";
			    if(((tt+1)%100)==0)

⌨️ 快捷键说明

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