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

📄 hicdoc.cpp

📁 视频图像的压缩编码。用Vc编写的
💻 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 + -