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

📄 decompressdoc.cpp

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

#include "stdafx.h"
#include "Decompress.h"

#include "DecompressDoc.h"
#include "ScanNumDlg.h"

#include <math.h>
#include <time.h>
#include <Afx.h>

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CDecompressDoc

IMPLEMENT_DYNCREATE(CDecompressDoc, CDocument)

BEGIN_MESSAGE_MAP(CDecompressDoc, CDocument)
	//{{AFX_MSG_MAP(CDecompressDoc)
	ON_COMMAND(ID_FILE_OPEN, OnFileOpen)
	ON_COMMAND(ID_FileClose, OnFileClose)
	ON_COMMAND(ID_HaarOne, OnHaarOne)
	ON_COMMAND(ID_HaarTwo, OnHaarTwo)
	ON_COMMAND(ID_HaarThree, OnHaarThree)
	ON_COMMAND(ID_D97One, OnD97One)
	ON_COMMAND(ID_D97Two, OnD97Two)
	ON_COMMAND(ID_D97Three, OnD97Three)
	ON_COMMAND(ID_FILE_SAVE_AS, OnFileSaveAs)
	ON_COMMAND(ID_EZW_Encode, OnEZWEncode)
	ON_COMMAND(ID_EZW_Decode, OnEZWDecode)
	ON_COMMAND(ID_HaarFour, OnHaarFour)
	ON_COMMAND(ID_D97Four, OnD97Four)
	ON_COMMAND(ID_FourFind, OnFourFind)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CDecompressDoc construction/destruction

CDecompressDoc::CDecompressDoc()
{
	// TODO: add one-time construction code here
    scale=0;
	code.SetSize(500,200);
	codeId=0;
}

CDecompressDoc::~CDecompressDoc()
{
	if(flag==1)
	{
		for(int i=0;i<pbi->bmiHeader.biHeight;i++)
			delete []Coefficient[i];
		delete []Coefficient;
		HeapFree(GetProcessHeap(), 0, pbi);
		HeapFree(GetProcessHeap(), 0, lpBuf);
        HeapFree(GetProcessHeap(), 0, lpshowbuf);
		
	}
	code.RemoveAll();
}

BOOL CDecompressDoc::OnNewDocument()
{
	if (!CDocument::OnNewDocument())
		return FALSE;

	// TODO: add reinitialization code here
	// (SDI documents will reuse this document)

	return TRUE;
}



/////////////////////////////////////////////////////////////////////////////
// CDecompressDoc serialization

void CDecompressDoc::Serialize(CArchive& ar)
{
	if (ar.IsStoring())
	{
		// TODO: add storing code here
	}
	else
	{
		// TODO: add loading code here
	}
}

/////////////////////////////////////////////////////////////////////////////
// CDecompressDoc diagnostics

#ifdef _DEBUG
void CDecompressDoc::AssertValid() const
{
	CDocument::AssertValid();
}

void CDecompressDoc::Dump(CDumpContext& dc) const
{
	CDocument::Dump(dc);
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CDecompressDoc commands

void CDecompressDoc::OnFileOpen() 
{
	// TODO: Add your command handler code here
	LPCTSTR lpszFilter="BMP Files(*.bmp)|*.bmp|任何文件|*.*||";
	CFileDialog dlg(TRUE, lpszFilter, NULL, OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT, lpszFilter, NULL);
	CString filename;
	CFile file;
	//BITMAPFILEHEADER bf;

	//打开文件对话框
	if(dlg.DoModal()==IDOK)
	{
		filename=dlg.GetPathName();
		if(file.Open(filename, CFile::modeRead|CFile::shareDenyNone, NULL)==0)
		{
			//读取文件失败
			AfxMessageBox("无法打开文件!", MB_OK, 0);
			return;
		}

		//读取文件头
		file.Read(&bf,sizeof(bf));
		//判断是否是BMP文件
		if(bf.bfType!=0x4d42)  //'BM'
		{
			AfxMessageBox("非BMP文件!", MB_OK, 0);
			return;
		}

		//判断文件是否损坏
		if(file.GetLength()!=bf.bfSize)
		{
			AfxMessageBox("文件已损坏,请检查!", MB_OK, 0);
			return;
		}
		

		//读文件信息头
		file.Read(&bi, sizeof(bi));
   
		//计算调色板数目
		numQuad=0;
		if(bi.biBitCount<24)
		{
			numQuad=1<<bi.biBitCount;
		}

		//为图像信息pbi申请空间
		pbi=(BITMAPINFO*)HeapAlloc(GetProcessHeap(), 0, sizeof(BITMAPINFOHEADER)+numQuad*sizeof(RGBQUAD));
		memcpy(pbi, &bi, sizeof(bi));
		quad=(RGBQUAD*)((BYTE*)pbi+sizeof(BITMAPINFOHEADER));
		int linewidth=(pbi->bmiHeader.biWidth*pbi->bmiHeader.biBitCount+31)/32*4;
		Coefficient=new int*[pbi->bmiHeader.biHeight];
		for(int i=0;i<pbi->bmiHeader.biHeight;i++)
			Coefficient[i]=new int[linewidth];
		

		//读取调色板
		if(numQuad!=0)
		{
			file.Read(quad, sizeof(RGBQUAD)*numQuad);
		}
        
		//检测调色板是否为整数型
		
		//AfxMessageBox("第一个值是:"+quad->rgbBlue,MB_OK,0);
		//为图像数据申请空间
		bi.biSizeImage=bf.bfSize-bf.bfOffBits;
		lpBuf=(BYTE*)HeapAlloc(GetProcessHeap(), 0, bi.biSizeImage);
		//读取图像数据
		file.Read(lpBuf, bi.biSizeImage);

		//图像读取完毕,关闭文件,设置标志
		file.Close();
		flag=1;
		lpshowbuf=NULL;
		PrepareShowdata();

		//将BMP图像显示出来
		UpdateAllViews(NULL, 0, NULL);
	}
	
}

BOOL CDecompressDoc::PrepareShowdata()
{   
	BYTE** image;
	BYTE** originimage;
	int i,j;
	int linewidth;
	//char *ch;
   // int size;
	

	if(lpshowbuf!=NULL)
		HeapFree(GetProcessHeap(), 0, lpshowbuf);
	
	//申请内存
	
		linewidth=(pbi->bmiHeader.biWidth*pbi->bmiHeader.biBitCount+31)/32*4;
		pbi->bmiHeader.biSizeImage=linewidth*pbi->bmiHeader.biHeight;
		lpshowbuf=(BYTE*)HeapAlloc(GetProcessHeap(), 0, sizeof(BYTE)*pbi->bmiHeader.biSizeImage);
		
		//生成对lpshowbuf的二维数组索引
	    image=new BYTE*[pbi->bmiHeader.biHeight];
		for(i=0;i<pbi->bmiHeader.biHeight;i++)
		image[i]=lpshowbuf+i*linewidth;
		originimage=new BYTE*[pbi->bmiHeader.biHeight];
	    for(i=0;i<pbi->bmiHeader.biHeight;i++)
		originimage[i]=lpBuf+i*linewidth;



	//赋值
	if(bi.biBitCount<24)  //含有调色板的情况
	{
		//BYTE temp;
		for(i=0;i<pbi->bmiHeader.biHeight;i++)
			for(j=0;j<linewidth;j++)
			{
				image[i][j]=originimage[i][j];
				//image[i][j*3]=quad[temp].rgbBlue;
				//image[i][j*3+1]=quad[temp].rgbGreen;
				//image[i][j*3+2]=quad[temp].rgbRed;
			}
        //for(DWORD i=0;i<(3*pbi->bmiHeader.biSizeImage);i++)
		//ch[i]=lpshowbuf[i];
	}

	
	else if(pbi->bmiHeader.biBitCount==24)     //24位真彩色
	{
		for(i=0;i<pbi->bmiHeader.biHeight;i++)
			for(j=0;j<pbi->bmiHeader.biWidth;j++)
			{
				image[i][j*3]=originimage[i][j*3];
				image[i][j*3+1]=originimage[i][j*3+1];
				image[i][j*3+2]=originimage[i][j*3+2];
			}
			//for(DWORD i=0;i<pbi->bmiHeader.biSizeImage;i++)
				//str[i].Format("%d",lpshowbuf[i]);
				//ch[i]=lpshowbuf[i];
	}
	//str=ch;
	//AfxMessageBox(str,MB_OK,0);
	//CFile file;
	//if(file.Open("d:\\openfile.txt",CFile::modeRead|CFile::shareDenyNone, NULL)==0)
	//	file.Write(lpshowbuf,pbi->bmiHeader.biSizeImage);
    //ofstream ofile("d:\\openfile1.txt",ios::in,filebuf::openprot);
	//for(long ii=0;ii<pbi->bmiHeader.biSizeImage;ii++)
	//{
	//	int in=(int)lpshowbuf[ii];
	//	if(ii%3==0)
	//		ofile<<' ';
	  //  ofile<<in;
	//}
	//    ofile.close();


	delete []image;    
	return TRUE;

}

void CDecompressDoc::OnFileClose() 
{
	// TODO: Add your command handler code here
	if(flag==1)
		lpshowbuf=NULL;
	UpdateAllViews(NULL, 0, NULL);

}

void CDecompressDoc::OnHaarOne() 
{
	// TODO: Add your command handler code here
	int linewidth;
	int max, min;  //记录变换后像素的最大最小值
    int** image;   //用于变换的整型图象数据
	//int temp;  //临时存放映射后的值,再转化为BYTE型
	
	linewidth=(pbi->bmiHeader.biWidth*pbi->bmiHeader.biBitCount+31)/32*4;
	JiFlag=0;  //Haar小波

    //生成对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];

	HaarTrans(pbi->bmiHeader.biHeight,linewidth,image,&max,&min);
	GetCoefficient(image,pbi->bmiHeader.biHeight,linewidth);
	One_ToLpshowbuf(image, &max, &min);
    scale=1;
	
	//释放内存
    for(int z=0;z<pbi->bmiHeader.biHeight;z++)
	{
		delete [] image[z];
	}
	delete [] image;

    UpdateAllViews(NULL, 0, NULL);
}

void CDecompressDoc::HaarTrans(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);//实现分裂
    HaarForecast(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);
	HaarForecast(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;
}

//行变换中的分裂
void CDecompressDoc::LineSplit(int **data, int **s, int **d, int height, int width)
{
	for(int i=0;i<height;i++)
	{
	    for(int j=0;j<width>>1;j++)
		{
		    s[j][i]=data[i][2*j];
		    d[j][i]=data[i][2*j+1];
		}
	}
}

//列变换中的分裂
void CDecompressDoc::RowSplit(int** data, int** s, int** d, int height, int width)
{
	for(int i=0;i<height>>1;i++)
	{
		for(int j=0;j<width;j++)
		{
			s[i][j]=data[2*i][j];
			d[i][j]=data[2*i+1][j];
		}
	}
}

//Haar变换中的预测和提升
void CDecompressDoc::HaarForecast(int **s, int **d, int height, int width)
{
	int i,j;
	for(i=0;i<(width>>1);i++)
	{
		for(j=0;j<height;j++)
		{
			d[i][j]=d[i][j]-s[i][j];
		}
	}
	for(i=0;i<(width>>1);i++)
	{
		for(j=0;j<height;j++)
		{
			s[i][j]=s[i][j]+d[i][j]/2;
		}
	}
}
void CDecompressDoc::One_ToLpshowbuf(int **OneImage, int *max, int *min)
{
	int temp;
	int linewidth=(pbi->bmiHeader.biWidth*pbi->bmiHeader.biBitCount+31)/32*4;
	//把所有变换后的像素值映射到0-255,且把变换后的值正确的存入lpshowbuf中
	for(int mm=0;mm<pbi->bmiHeader.biHeight;mm++)
	{
		for(int nn=0;nn<linewidth;nn++)
			OneImage[mm][nn]=(OneImage[mm][nn]-*min)*255/(*max-*min);
	}
	for(int m=0; m<pbi->bmiHeader.biHeight>>1; m++)
	{
		for(int n=0; n<linewidth>>1; n++)
		{
			temp=OneImage[2*m][2*n];
			//lpshowbuf[m*linewidth+n]=(BYTE)image[2*m][n];
			lpshowbuf[(pbi->bmiHeader.biHeight-1-m)*linewidth+n]=(BYTE)temp;
			temp=OneImage[2*m][2*n+1];
			lpshowbuf[((pbi->bmiHeader.biHeight>>1)-1-m)*linewidth+n]=(BYTE)temp;
			temp=OneImage[2*m+1][2*n];
			lpshowbuf[(pbi->bmiHeader.biHeight-1-m)*linewidth+(linewidth>>1)-1+n]=(BYTE)temp;
			temp=OneImage[2*m+1][2*n+1];
			lpshowbuf[((pbi->bmiHeader.biHeight>>1)-1-m)*linewidth+(linewidth>>1)-1+n]=(BYTE)temp;
		}
	}

}

void CDecompressDoc::OnHaarTwo() 

⌨️ 快捷键说明

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