📄 hicdoc.cpp
字号:
// HICDoc.cpp : implementation of the CHICDoc class
//
#include "stdafx.h"
#include "HIC.h"
#include "ARITHCoding.h"
#include "HICDoc.h"
#include "SPIHTCoder.h"
#include "math.h"
#include "Dwt.h"
#include "IntDwt53.h"
#include "LiftDwt97.h"
#include "Parameter.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CHICDoc
IMPLEMENT_DYNCREATE(CHICDoc, CDocument)
BEGIN_MESSAGE_MAP(CHICDoc, CDocument)
//{{AFX_MSG_MAP(CHICDoc)
ON_COMMAND(ID_ARITHMETICCODING, OnArithmeticcoding)
ON_COMMAND(ID_ARITHMETICDCODING, OnArithmeticdcoding)
ON_COMMAND(ID_IMAGEOPEN, OnImageopen)
ON_COMMAND(ID_SPIHTCODER, OnSpihtcoder)
ON_COMMAND(ID_SPIHTDCODER, OnSpihtdcoder)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CHICDoc construction/destruction
CHICDoc::CHICDoc()
{
// TODO: add one-time construction code here
}
CHICDoc::~CHICDoc()
{
}
BOOL CHICDoc::OnNewDocument()
{
if (!CDocument::OnNewDocument())
return FALSE;
// TODO: add reinitialization code here
// (SDI documents will reuse this document)
return TRUE;
}
/////////////////////////////////////////////////////////////////////////////
// CHICDoc serialization
void CHICDoc::Serialize(CArchive& ar)
{
if (ar.IsStoring())
{
// TODO: add storing code here
}
else
{
// TODO: add loading code here
}
}
/////////////////////////////////////////////////////////////////////////////
// CHICDoc diagnostics
#ifdef _DEBUG
void CHICDoc::AssertValid() const
{
CDocument::AssertValid();
}
void CHICDoc::Dump(CDumpContext& dc) const
{
CDocument::Dump(dc);
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CHICDoc commands
/*****************************************************************
算术编码程序
******************************************************************/
void CHICDoc::OnArithmeticcoding()
{
// TODO: Add your command handler code here
CFile file;
CARITHCoding AC_Code;
/*定义存放源文件数据的指针数组*/
BYTE *lpImageBuf;
lpImageBuf = (BYTE*)new char[iwidth*iheight];
/*要进行算术编码的源文件路径*/
CString strPathname1="E:\\lena.raw";
/*算术编码后的输出文件路径*/
CString strPathname2="E:\\lena.ac";
if(!file.Open(strPathname1,CFile::modeReadWrite))
{
AfxMessageBox("Can not Open File!");
return;
}
if((AC_Code.fp_out=fopen(strPathname2,"wb"))==NULL)
AfxMessageBox("Error! Code Value Out of Range. Cannot Compress.\n");
/*读取源文件*/
file.Read(lpImageBuf,iwidth*iheight);
file.Close();
/*对源文件数据进行算术编码*/
AC_Code.AC_code(lpImageBuf,iwidth,iheight);
AfxMessageBox("算术编码结束");
}
/*****************************************************************
算术解码程序
******************************************************************/
void CHICDoc::OnArithmeticdcoding()
{
// TODO: Add your command handler code here
/*定义存放解码后数据的指针数组*/
BYTE *pData;
pData = (BYTE*)new char[iwidth * iheight];
CARITHCoding AC_Code;
/*定义需要进行解码的文件路径*/
CString strPathname1="E:\\out.sa";
/*定义解码后文件路径*/
CString strPathname2="E:\\lena.spiht";
AC_Code.fp_in=fopen(strPathname1,"rb");
AC_Code.fp_out=fopen(strPathname2,"wb");
/*算术解码*/
pData=AC_Code.AC_decode(iwidth,iheight);
AfxMessageBox("算术解码结束");
}
/*****************************************************************
图像读取程序,该程序用到CDib类
******************************************************************/
void CHICDoc::OnImageopen()
{
// TODO: Add your command handler code here
CFileDialog fileopenbox(TRUE,NULL,"*.bmp",OFN_HIDEREADONLY,"files(*.bmp)|*.bmp|",NULL);
fileopenbox.m_ofn.lpstrTitle="小波变换";
if(fileopenbox.DoModal()!=IDOK) return;
CString strPathname=fileopenbox.GetPathName();
if(IsBmp(strPathname))
{
lpSrc.Read(strPathname);
}
else
{
AfxMessageBox("不是bmp文件!");
}
int i,j;
CSize m_size;
m_size.cx = lpSrc.Width();
m_size.cy = lpSrc.Height();
iwidth=m_size.cx;
iheight=m_size.cy;
data1=new int[iwidth * iheight];
data2=new double[iwidth * iheight];
for( i = 0; i <iheight; i++ )
for( j = 0; j < iwidth; j++ )
{
data1[i*iwidth+j]=(unsigned char)lpSrc.GetXY8(j,i);
data2[i*iwidth+j]=(unsigned char)lpSrc.GetXY8(j,i);
}
UpdateAllViews(FALSE);
return ;
}
BOOL CHICDoc::IsBmp(LPCTSTR lpszPathName)
{
CFile file;
if( !file.Open( lpszPathName, CFile::modeRead ) )
return 0;
UINT nCount;
BITMAPFILEHEADER bmfh;
nCount = file.Read((LPVOID) &bmfh, sizeof(BITMAPFILEHEADER));
if(nCount != sizeof(BITMAPFILEHEADER))
return FALSE;
if(bmfh.bfType != 0x4d42)
return FALSE;
file.Close( );
return TRUE;
}
/*****************************************************************
Spiht编码程序,只能处理8位灰度图像
******************************************************************/
void CHICDoc::OnSpihtcoder()
{
// TODO: Add your command handler code here
int i,j,*data;
float bpp;
CSPIHTCoder SPIHTCoder;
data=new int[iheight*iwidth];
/*产生对话框*/
CParameter parameter;
parameter.m_level = 0;
parameter.m_bitrate=0;
if (parameter.DoModal()!=IDOK)
return;
/*设置小波分解的层数*/
level=parameter.m_level;
/*每个象素的比特数,通过该参数控制压缩后文件大小*/
bpp=parameter.m_bitrate;
//删除对话框
delete parameter;
/*97提升小波变换*/
LiftDwt.Dwt2D(data2, iheight,iwidth,level);
/*将小波分解后的系数取整,类似量化步骤*/
for(i=0;i<iheight;i++)
for(j=0;j<iwidth;j++)
data[i*iwidth+j]=int(data2[i*iwidth+j]);
/*spiht编码*/
SPIHTCoder.Encode(data,iwidth,iheight,bpp,level);
/*算术编码*/
//OnArithmeticcoding();
AfxMessageBox("Spiht编码结束,压缩后的文件保存在E盘的根目录下");
delete []data2;
delete []data;
UpdateAllViews(NULL);
SetModifiedFlag();
}
/*****************************************************************
Spiht解码程序
******************************************************************/
void CHICDoc::OnSpihtdcoder()
{
// TODO: Add your command handler code here
int m,n;
float MSE, PSNR;
CString str;
double *image;
CSPIHTCoder SPIHTCoder;
lpDst1=lpSrc;
image=new double[iwidth*iheight];
/*算术解码*/
//OnArithmeticdcoding();
/*spiht解码*/
SPIHTCoder.Decode();
/*从压缩文件的文件头中获得图像的宽度和高度*/
iheight=SPIHTCoder.header.height;
iwidth=SPIHTCoder.header.width;
/*获取spiht解码后的数据*/
for(m=0;m<iheight;m++)
for(n=0;n<iwidth;n++)
image[m*iwidth+n]=SPIHTCoder.MR->m[m][n];
/*97提升小波反变换*/
LiftDwt.IDwt2D(image, iheight,iwidth,level);
/*限幅操作*/
for(m=0;m<iheight;m++)
for(n=0;n<iwidth;n++)
{
if(image[m*iwidth+n]<0)
image[m*iwidth+n]=0;
if(image[m*iwidth+n]>255)
image[m*iwidth+n]=255;
}
/*设置图像以便显示*/
for(m=0;m<iheight;m++)
for(n=0;n<iwidth;n++)
{
lpDst1.SetXY8(n,m,int(image[m*iwidth+n]));
}
/*计算解码后图像的PSNR*/
MSE=0;
for(m=0;m<iheight;m++)
for(n=0;n<iwidth;n++)
MSE=MSE+(image[m*iwidth+n]-data1[m*iwidth+n])*(image[m*iwidth+n]-data1[m*iwidth+n]);
MSE=MSE/(iwidth*iheight);
PSNR=10*log10(255*255/MSE);
str.Format("PSNR为%f",PSNR);
AfxMessageBox(str);
delete []image;
UpdateAllViews(NULL);
SetModifiedFlag();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -