www.pudn.com > FatRec001.rar > Dib.cpp


// Dib.cpp: implementation of the CDib class. 
// 
////////////////////////////////////////////////////////////////////// 
 
#include "StdAfx.h" 
#include "Dib.h" 
 
#ifdef _DEBUG 
#undef THIS_FILE 
static char THIS_FILE[]=__FILE__; 
#define new DEBUG_NEW 
#endif 
 
////////////////////////////////////////////////////////////////////// 
// Construction/Destruction 
////////////////////////////////////////////////////////////////////// 
 
CDib::CDib() 
{ 
	m_hDrawDib=NULL; 
	m_pDib=NULL; 
} 
 
CDib::~CDib() 
{ 
	Close(); 
} 
/******************************************************************************   
    *   画图   
  ******************************************************************************/   
 
void CDib::Draw(CDC *pDC,int nWidth, int nHeight) 
{ 
	if(m_pDib!=NULL) 
	{ 
	ASSERT(IsValid()); 
	DrawDibRealize(m_hDrawDib,pDC->GetSafeHdc(),TRUE); 
	DrawDibDraw(m_hDrawDib,pDC->GetSafeHdc(), 
				0,  //desktop left 
				0,  //desktop top 
				nWidth, 
				nHeight, 
				(BITMAPINFOHEADER *)m_pDib, 
				(LPVOID) GetBits(), 
				0,  //source left 
				0,  //source top 
				((BITMAPINFOHEADER *)m_pDib)->biWidth, 
				((BITMAPINFOHEADER *)m_pDib)->biHeight, 
				DDF_BACKGROUNDPAL); 
	} 
} 
  
  /******************************************************************************   
    *   获得图像大小   
  ******************************************************************************/   
 
CSize CDib::GetSize() 
{ 
	return CSize(((BITMAPINFOHEADER *)m_pDib)->biWidth,      //位图的宽 (以象素为单位) 
				 ((BITMAPINFOHEADER *)m_pDib)->biHeight);	 ////位图的高 (以象素为单位) 
} 
/******************************************************************************   
    *   获得图像宽度   
  ******************************************************************************/   
 
LONG CDib::GetWidth() 
{ 
	return ((BITMAPINFOHEADER *)m_pDib)->biWidth;            //位图的宽 (以象素为单位) 
} 
/******************************************************************************   
    *   获得图像高度   
  ******************************************************************************/   
 
LONG CDib::GetHeight() 
{ 
	return	((BITMAPINFOHEADER *)m_pDib)->biHeight;          ////位图的高 (以象素为单位) 
} 
/******************************************************************************   
    *   关闭图像   
  ******************************************************************************/   
 
void CDib::Close() 
{ 
	if(m_hDrawDib!=NULL)        //如果句柄不为空 
	{ 
		DrawDibClose(m_hDrawDib); 
		m_hDrawDib=NULL; 
	} 
 
	if(m_pDib!=NULL)         //如果指针不为空 
	{ 
		delete m_pDib; 
		m_pDib=NULL; 
	} 
} 
  /******************************************************************************   
    *   打开图像   
  ******************************************************************************/   
 
BOOL CDib::Open(const char * pzFileName) 
{ 
//	BITMAPFILEHEADER bmpFileHeader; 
	CFile file; 
	int nBmpFileHeaderSize; 
 
	Close(); 
 
	//drawdibopen initialize the diradib library and  
	//returns a handle for all drawdib operations 
	if(!(m_hDrawDib=DrawDibOpen())) 
		goto exit; 
 
 	//open and read the DIB file header   打开并读取位图信息 
	nBmpFileHeaderSize=sizeof(BITMAPFILEHEADER);          //获取头文件结构体的大小 
 
	if(!file.Open(pzFileName,CFile::modeRead | CFile::typeBinary))      //如果不是以只度模式和二进制模式打开  
		goto exit; 
 
	if(file.Read((void *)&bmpFileHeader,nBmpFileHeaderSize)!=(UINT)nBmpFileHeaderSize)        //如果读到的头文件中大小与获取的不一致 
		goto failure; 
 
	//validate the DIB file header by checking the first 
	//two characters for the signature "BM"         验证位图信息 
	if(bmpFileHeader.bfType!=*((WORD *)"BM")) 
		goto failure; 
 
	//allocate a big chuck of global memory to store the DIB   申请内存  
	 
	m_pDib=(BYTE *)new char [bmpFileHeader.bfSize-nBmpFileHeaderSize];   
	//包含位图的文件的的大小(以字节为单位)-文件头的大小 
 
	//allocate memory fail        内存申请失败 
	if(!m_pDib) 
		goto failure; 
 
	//read the dib into the buffer at a time using ReadHuge         读取位图数据 
	file.ReadHuge(m_pDib,bmpFileHeader.bfSize-nBmpFileHeaderSize);        //将数据从文件读入寄存器 
 
	if(((BITMAPINFOHEADER *)m_pDib)->biSizeImage==0)      //如果创建的时候没有放入 则强制放入 
	{ 
		//the application that create this bitmap didn't fill 
		//in the biSizeImage field. Let's fill it 
		//in even though the DrawDib * functions don't need it. 
		BITMAPINFOHEADER *pDib=(BITMAPINFOHEADER *)m_pDib; 
 
		//scan lines must be DWord aligned, hence the strange bit stuff 
		pDib->biSizeImage=((((pDib->biWidth*pDib->biBitCount)+31)&~31)>>3)*pDib->biHeight;       //指定位图大小(以字节为单位) 
	} 
 
	m_pDibBits=GetBits();     //保存位图数据 
 
	file.Close(); 
	return TRUE; 
 
failure: 
	file.Close(); 
exit: 
	Close(); 
	return FALSE; 
} 
/******************************************************************************   
    *   保存位图图像   
  ******************************************************************************/   
 
BOOL CDib::Save(const char * pzFileName) 
{ 
//	BITMAPFILEHEADER bmpFileHeader; 
	CFile file; 
	int nBmpFileHeaderSize; 
 
 	//open and read the DIB file header 
	nBmpFileHeaderSize=sizeof(BITMAPFILEHEADER); 
 
	if(!file.Open(pzFileName,CFile::modeCreate | CFile::modeWrite | CFile::typeBinary)) 
		goto exit; 
 
	file.Write(&bmpFileHeader,nBmpFileHeaderSize);  
 
	//allocate memory fail   内存申请失败 
	if(!m_pDib) 
		goto failure; 
 
	//read the dib into the buffer at a time using ReadHuge 
	file.WriteHuge(m_pDib,bmpFileHeader.bfSize-nBmpFileHeaderSize); 
 
	file.Close(); 
	return TRUE; 
 
failure: 
	file.Close(); 
exit: 
	return FALSE; 
} 
/******************************************************************************   
    *   获得位图的完全大小  
  ******************************************************************************/   
 
BYTE * CDib::GetBits() 
{ 
	//the size of the color map is determined by the number 
	//of RGBQUAD structures present. 
	//it also depends on the bit_depth of the Dib 
	DWORD dwNumColors,dwColorTableSize; 
	BITMAPINFOHEADER *lpDib=(BITMAPINFOHEADER *)m_pDib; 
 
	WORD wBitCount=lpDib->biBitCount;          //表示颜色时所用到的字节数 
 
	if(lpDib->biSize>=36)              //结构指定的字节数 
		dwNumColors=lpDib->biClrUsed;      //颜色数 
	else 
		dwNumColors=0; 
 
	if(dwNumColors==0) 
	{ 
		if(wBitCount!=24) 
			dwNumColors=1L<biSize+dwColorTableSize;      //位图文件除头的大小+位图的信息头+调色板大小 
} 
/******************************************************************************   
    *   位图数据大小   
  ******************************************************************************/   
 
int CDib::GetBiBitCount() 
{ 
	if(m_pDib!=NULL) 
		return ((BITMAPINFOHEADER *)m_pDib)->biBitCount;          //指定表示颜色时要用到的位数 
	return 0; 
}