📄 hicdoc.cpp
字号:
// HICDoc.cpp : implementation of the CHICDoc class
//
#include "stdafx.h"
#include "HIC.h"
#include "HICDoc.h"
#include "SPIHTCoder.h"
#include "JPEG_LS.h"
#include "math.h"
#include "IntDwt53.h"
#include "ARITHCoding.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_IMAGEOPEN, OnImageopen)
ON_COMMAND(ID_SPIHTCODING, OnSpihtcoding)
ON_COMMAND(ID_DPCMCODING, OnDpcmcoding)
ON_COMMAND(ID_JPEGLSCODING, OnJpeglscoding)
//}}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::OnImageopen()
{
// TODO: Add your command handler code here
int i,j;
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文件!");
}
/*存放图像数据*/
iwidth=lpSrc.Width();
iheight=lpSrc.Height();
/*存放图像数据*/
data1=new int[iwidth * iheight];
data2=new double[iwidth * iheight];
original=new int[iwidth*iheight];
for( i = 0; i <iheight; i++ )
for( j = 0; j < iwidth; j++ )
{
data1[i*iwidth+j]=lpSrc.GetXY8(j,i);
data2[i*iwidth+j]=lpSrc.GetXY8(j,i);
original[i*iwidth+j]=lpSrc.GetXY8(j,i);
}
UpdateAllViews(FALSE);
}
void CHICDoc::OnSpihtcoding()
{
// TODO: Add your command handler code here
int i,j,*data;
float bytecounts2;
data=new int[iheight*iwidth];
CSPIHTCoder SPIHTCoder;
CString str;
lpDst1=lpSrc;
/*设置小波分解的层数*/
level=4;
//开始计时
start = clock();
/*5/3提升小波变换*/
// IntDwt53.Dwt2D(data1, iheight,iwidth,level);
SPTransform.Dwt2D(data1, iheight,iwidth,level);
/*spiht编码*/
SPIHTCoder.Losslessencode(data1,iwidth,iheight);
threshold2=SPIHTCoder.threshold;
bytecounts2=SPIHTCoder.counts;
/*计算压缩比*/
CR1=float((iwidth*iheight)/bytecounts2);
/*spiht解码*/
SPIHTCoder.Losslessdecoder(iwidth,iheight,threshold2);
//计时结束
finish = clock();
//计算编码时间
duration1 = (double)(finish - start)/CLOCKS_PER_SEC;
/*获取spiht解码后的数据*/
for(i=0;i<iheight;i++)
for(j=0;j<iwidth;j++)
data[i*iwidth+j]=SPIHTCoder.MR->m[i][j];
/*5/3提升小波反变换*/
// IntDwt53.IDwt2D(data1, iheight,iwidth,level);
SPTransform.IDwt2D(data1, iheight,iwidth,level);
for(i=0;i<iheight;i++)
for(j=0;j<iwidth;j++)
{
lpDst1.SetXY8(j,i,int(data1[i*iwidth+j]));
}
MSE=0;
for(i=0;i<iheight;i++)
for(j=0;j<iwidth;j++)
MSE=MSE+(data1[i*iwidth+j]-original[i*iwidth+j])*(data1[i*iwidth+j]-original[i*iwidth+j]);
/*刷新*/
UpdateAllViews(NULL);
SetModifiedFlag();
/*清除内存*/
delete []data;
delete []data1;
delete []data2;
}
void CHICDoc::OnDpcmcoding()
{
// TODO: Add your command handler code here
int i,j,temp1,temp2;
int *nDpcm,*pData;
BYTE *Deimage;
CARITHCoding AC;
nDpcm=new int[iwidth*iheight]; /*存放预测误差*/
pData=new int[iwidth*iheight];
/*存放算术解码后的数据*/
Deimage=new BYTE[iwidth*iheight]; /*存放DPCM解码后的数据*/
lpDst2=lpSrc;
/*编码部分*/
/*首先编码第0行,若是图像(0,0)处像素,则不进行预测*/
nDpcm[0]=data1[0];
/*若不是(0,0)处的像素,则利用其上一个像素对其进行预测*/
for(j=1;j<iwidth;j++)
{
nDpcm[j]=data1[j]-data1[j-1];
}
/*编码第1行到第iheight-1行*/
/*若是第1列,则利用其上一个像素对其进行预测*/
for(i=1;i<iheight;i++)
{
nDpcm[i*iwidth]=data1[i*iwidth]-data1[(i-1)*iwidth];
}
/*若非第0列*/
for(i=1;i<iheight;i++)
for(j=1;j<iwidth;j++)
{
temp1=floor((data1[(i-1)*iwidth+j]-data1[(i-1)*iwidth+j-1])*0.5+data1[i*iwidth+j-1]);
if(temp1<0)
temp1=0;
if(temp1>255)
temp1=255;
nDpcm[i*iwidth+j]=data1[i*iwidth+j]-temp1;
}
/*算术编码*/
OnArithmeticencode(nDpcm, iwidth, iheight);
/*计算压缩比*/
CR2=float((iwidth*iheight)/ACByte);
/*解码部分,首先进行算术解码*/
pData=OnArithmeticdcoding(iwidth, iheight);
MSE=0;
for(i=0;i<iheight;i++)
for(j=0;j<iwidth;j++)
{
MSE=MSE+(float)(pData[i*iwidth+j]-nDpcm[i*iwidth+j]);
if(MSE!=0)
break;
}
/*首先解码(0,0)处像素*/
Deimage[0]=pData[0];
/*解码第0行非(0,0)处的像素*/
for(j=1;j<iwidth;j++)
{
Deimage[j]=pData[j]+Deimage[j-1];
}
/*解码第0行到第iheight-1行*/
/*若是第0列*/
for(i=1;i<iheight;i++)
{
Deimage[i*iwidth]=pData[i*iwidth]+Deimage[(i-1)*iwidth];
}
/*若非第0行第0列*/
for(i=1;i<iheight;i++)
for(j=1;j<iwidth;j++)
{
temp2=floor((Deimage[(i-1)*iwidth+j]-Deimage[(i-1)*iwidth+j-1])*0.5+Deimage[i*iwidth+j-1]);
if(temp2<0)
temp2=0;
if(temp2>255)
temp2=255;
Deimage[i*iwidth+j]=pData[i*iwidth+j]+temp2;
}
for(i=0;i<iheight;i++)
for(j=0;j<iwidth;j++)
{
lpDst2.SetXY8(j,i,int(Deimage[i*iwidth+j]));
}
MSE=0;
for(i=0;i<iheight;i++)
for(j=0;j<iwidth;j++)
MSE=MSE+(float)(Deimage[i*iwidth+j]-original[i*iwidth+j])*(Deimage[i*iwidth+j]-original[i*iwidth+j]);
MSE=MSE/(iwidth*iheight);
/*刷新*/
UpdateAllViews(NULL);
SetModifiedFlag();
/*清除内存*/
delete []data1;
delete []data2;
delete []nDpcm;
delete []Deimage;
}
void CHICDoc::OnJpeglscoding()
{
// TODO: Add your command handler code here
int i,j,*data;
float bytecounts;
data=new int[iheight*iwidth];
JPEG_LS JPEGLS;
lpDst4=lpSrc;
//开始计时
start = clock();
/*JPEG-LS编码*/
bytecounts=JPEGLS.JPEG_LSEncoding(data1,iwidth,iheight);
/*计算压缩比*/
CR4=float((iwidth*iheight)/bytecounts);
/*JPEG-LS解码*/
data=JPEGLS.JPEG_LSDecoding(iwidth,iheight);
//计时结束
finish = clock();
//计算编码时间
duration1 = (double)(finish - start)/CLOCKS_PER_SEC;
for(i=0;i<iheight;i++)
for(j=0;j<iwidth;j++)
{
lpDst4.SetXY8(j,i,int(data[i*iwidth+j]));
}
MSE=0;
for(i=0;i<iheight;i++)
for(j=0;j<iwidth;j++)
MSE=MSE+(float)(data[i*iwidth+j]-original[i*iwidth+j])*(data[i*iwidth+j]-original[i*iwidth+j]);
MSE=MSE/(iwidth*iheight);
/*刷新*/
UpdateAllViews(NULL);
SetModifiedFlag();
/*清除内存*/
delete []data;
delete []data1;
}
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;
}
void CHICDoc::OnArithmeticencode(int *image, int width, int height)
{
CFile file;
CARITHCoding AC_Code;
/*算术编码后的输出文件路径*/
CString strPathname="E:\\lena.ac";
if((AC_Code.fp_out=fopen(strPathname,"wb"))==NULL)
AfxMessageBox("Error! Code Value Out of Range. Cannot Compress.\n");
/*对源文件数据进行算术编码*/
AC_Code.AC_code(image,width,height);
ACByte=AC_Code.bytenum;
}
int * CHICDoc::OnArithmeticdcoding(int width, int height)
{
/*定义存放解码后数据的指针数组*/
int *lptempbuf;
lptempbuf =new int[width * height];
CARITHCoding AC_Code;
/*定义需要进行解码的文件路径*/
CString strPathname="E:\\lena.ac";
AC_Code.fp_in=fopen(strPathname,"rb");
/*算术解码*/
lptempbuf=AC_Code.AC_decode(width,height);
return lptempbuf;
}
long CHICDoc::OnACencode(int *image, int width, int height)
{
long acbyte;
CFile file;
CARITHCoding AC_Code;
/*算术编码后的输出文件路径*/
CString strPathname="E:\\lena.ac";
if((AC_Code.fp_out=fopen(strPathname,"wb"))==NULL)
AfxMessageBox("Error! Code Value Out of Range. Cannot Compress.\n");
/*对源文件数据进行算术编码*/
AC_Code.AC_code(image,width,height);
acbyte=AC_Code.bytenum;
return acbyte;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -