www.pudn.com > 图像处理源代码.rar > Task5.cpp


// Task5.cpp : implementation file 
// 
 
#include "stdafx.h" 
#include "tuxiang.h" 
#include "image.h" 
#include "imgview.h" 
#include "Task5.h" 
#include  
 
#ifdef _DEBUG 
#define new DEBUG_NEW 
#undef THIS_FILE 
static char THIS_FILE[] = __FILE__; 
#endif 
 
#define INDEXNUM	256 
 
CODETABLEITEM codetab[INDEXNUM]; 
 
//遍历HUFFMAN树,生成各索引值的HUFFMAN码 
// node指向当前结点,codelen为当前的码长, codeval为当前的编码 
void list(TWOTREE *node,int codelen,int codeval) 
{ 
	if(node->lChild ==NULL && node->rChild ==NULL) 
	{ 
		codetab[node->indexvalue].codelen = codelen; 
		codetab[node->indexvalue].codeval = codeval; 
	} 
	else 
	{ 
		list(node->lChild,codelen+1,codeval*2+1); 
		list(node->rChild,codelen+1,codeval*2); 
	} 
} 
 
void listfree(TWOTREE* node) 
{ 
	if(node->lChild !=NULL) 
		listfree(node->lChild); 
	if(node->rChild !=NULL) 
		listfree(node->rChild); 
} 
 
int compare( const void *arg1, const void *arg2 ) 
{ 
   /* Compare all of both strings: */ 
	HISTOARRAY *val1,*val2; 
	val1=( HISTOARRAY* ) arg1; 
	val2=( HISTOARRAY* ) arg2; 
   return (val2->count - val1->count ); 
} 
 
///////////////////////////////////////////////////////////////////////////// 
// CTask5 property page 
 
IMPLEMENT_DYNCREATE(CTask5, CPropertyPage) 
 
CTask5::CTask5() : CPropertyPage(CTask5::IDD) 
{ 
	//{{AFX_DATA_INIT(CTask5) 
		// NOTE: the ClassWizard will add member initialization here 
	//}}AFX_DATA_INIT 
} 
 
CTask5::~CTask5() 
{ 
} 
 
void CTask5::DoDataExchange(CDataExchange* pDX) 
{ 
	CPropertyPage::DoDataExchange(pDX); 
	//{{AFX_DATA_MAP(CTask5) 
		// NOTE: the ClassWizard will add DDX and DDV calls here 
	//}}AFX_DATA_MAP 
} 
 
 
BEGIN_MESSAGE_MAP(CTask5, CPropertyPage) 
	//{{AFX_MSG_MAP(CTask5) 
	ON_BN_CLICKED(IDOPEN, OnOpen) 
	ON_BN_CLICKED(IDCLEAR, OnClear) 
	//}}AFX_MSG_MAP 
END_MESSAGE_MAP() 
 
///////////////////////////////////////////////////////////////////////////// 
// CTask5 message handlers 
 
extern MYIMAGE* pImage; 
extern CImgView *m_ImgView; 
 
void CTask5::OnOpen()  
{ 
	if(m_ImgView!=NULL) m_ImgView->ShowWindow (SW_HIDE); 
	if(pImage!=NULL) 
		delete pImage; 
 
	static char BASED_CODE szFilter[] = "图象文件 (*.bmp)|*.bmp"; 
	CString sFileName; 
 
	//显示一个Open File Dialog 
	CFileDialog	opendlg(TRUE,NULL,NULL,OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,szFilter,NULL); 
	int choice=opendlg.DoModal(); 
	if(choice!=IDOK) 
		return; 
 
	//读取文件名 
	sFileName=opendlg.GetPathName(); 
	if(opendlg.GetFileExt()=="bmp") 
		pImage=ReadBmp(sFileName,this->m_hWnd); 
	if(m_ImgView==NULL) m_ImgView=new CImgView(pImage,this); 
	m_ImgView->ShowWindow (SW_SHOWNORMAL); 
	m_ImgView->DisplayImage(); 
 
	HISTOARRAY histoarray[INDEXNUM]; 
 
	for(int x=0;xHeight * pImage->Width ;x++) 
		histoarray[pImage->ImgData[x]].count++; 
/*	histoarray[0].count=40; 
	histoarray[1].count=8; 
	histoarray[2].count=8; 
	histoarray[3].count=20; 
	histoarray[4].count=12; 
	histoarray[5].count=8; 
	histoarray[6].count=4; 
	histoarray[7].count=0;*/ 
 
	for(x=0;xlChild=NULL; 
		tt[x]->rChild=NULL; 
		tt[x]->Parent=NULL; 
		tt[x]->indexvalue=histoarray[x].indexvalue; 
		tt[x]->count=histoarray[x].count; 
	} 
 
	for(x=1;xrChild = tt[INDEXNUM-x];	//概率最小的为右子结点 
		tt[INDEXNUM-x]->Parent=newnode; 
		newnode->lChild = tt[INDEXNUM-x-1];	//概率次小的为左子结点 
		tt[INDEXNUM-x-1]->Parent=newnode; 
 
		//父结点的概率为两个子结点的概率之和 
		newnode->count = newnode->lChild ->count + newnode->rChild ->count ; 
 
		//将父结点按概率顺序插入到序列中,始终保持序列的概率按顺序排列, 
		//丢弃原最小的两个结点 
		int times=0; 
		int end=INDEXNUM-x-2; 
		while(end-times>=0 && newnode->count > tt[end-times]->count ) 
		{ 
			tt[end-times+1]=tt[end-times]; 
			times++; 
		} 
		tt[end-times+1]=newnode; 
	} 
 
	TWOTREE *root=tt[0];	//根结点 
	 
	list(root,0,0); 
 
	listfree(root); 
	 
//	下面的代码用于计算平均码长、熵以及显示代码表 
	FILE *result=fopen("result.txt","w"); 
	long int totalbit=0; 
	double h=0.0; 
	for(x=0;xHeight * pImage->Width); 
		h += p*log10(p)/log10(2.0); 
		totalbit += codetab[x].codelen * codetab[x].count ; 
		fprintf(result,"index:%4d count: %8d codelen: %2d codeval %6X \n", 
			x,codetab[x].count, codetab[x].codelen,codetab[x].codeval); 
	} 
 
	double averlen=(double)totalbit/(pImage->Height * pImage->Width); 
	fprintf(result,"\nAverage code length: %f\n",averlen); 
	fprintf(result,"Entropy = %f\n",fabs(h)); 
	fclose(result); 
} 
 
void CTask5::OnClear()  
{ 
	if(m_ImgView!=NULL) 
	{ 
		m_ImgView->EndDialog(IDOK); 
		m_ImgView=NULL; 
	} 
	if(pImage!=NULL) 
	{ 
		delete pImage; 
		pImage=NULL; 
	}	 
}