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

📄 hicdoc.cpp

📁 图像无损压缩 TI常用例程 希望能对大家有所帮助
💻 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 + -