www.pudn.com > ImgFFT.zip > CDib.cpp


//CDib.cpp:implement the operations of proccessing DIB 
#include "stdafx.h" 
#include "Pro2.h" 
  
#include "Pro2Doc.h" 
#include "Pro2View.h" 
#include "CDib.h" 
 
#ifdef _DEBUG 
#define new DEBUG_NEW 
#undef THIS_FILE 
static char THIS_FILE[] = __FILE__; 
#endif 
 
IMPLEMENT_SERIAL(CDib,CObject,0) 
 
///////////////////////////////////////////////////////////////////////// 
CDib::CDib() 
{ 
	m_hFile=NULL; 
	m_hBitmap=NULL; 
	m_hPalette=NULL; 
	m_nBmihAlloc=m_nImageAlloc=noAlloc; 
	Empty(); 
} 
 
CDib::CDib(CSize size,int nBitCount) 
{ 
	m_hFile=NULL; 
	m_hBitmap=NULL; 
	m_hPalette=NULL; 
	m_nBmihAlloc=m_nImageAlloc=noAlloc; 
	Empty(); 
 
	ComputePaletteSize(nBitCount); 
 
	m_lpBMIH=(LPBITMAPINFOHEADER)new  
				char[sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*m_nColorTableEntries]; 
	 
	m_nBmihAlloc=crtAlloc; 
	m_lpBMIH->biSize=sizeof(BITMAPINFOHEADER); 
	m_lpBMIH->biWidth=size.cx; 
	m_lpBMIH->biHeight=size.cy; 
	m_lpBMIH->biPlanes=1; 
	m_lpBMIH->biBitCount=nBitCount; 
	m_lpBMIH->biCompression=BI_RGB; 
	m_lpBMIH->biSizeImage=0; 
	m_lpBMIH->biXPelsPerMeter=0; 
	m_lpBMIH->biYPelsPerMeter=0; 
	m_lpBMIH->biClrUsed=m_nColorTableEntries; 
	m_lpBMIH->biClrImportant=m_nColorTableEntries; 
 
	ComputeMetrics(); 
 
	memset(m_lpvColorTable,0,sizeof(RGBQUAD)*m_nColorTableEntries); 
 
	m_lpImage=NULL; 
} 
 
CDib::~CDib() 
{ 
	Empty(); 
} 
 
//////////////////////////////////////////////////////////////////////////// 
//put data of a file in or out 
BOOL CDib::Read(CFile *pFile) 
{ 
	Empty(); 
 
	int nCount,nSize; 
	BITMAPFILEHEADER bmfh; 
	char ko[100]; 
 
	try 
	{ 
		nCount=pFile->Read((LPVOID)&bmfh,sizeof(BITMAPFILEHEADER)); 
		if(nCount!=sizeof(BITMAPFILEHEADER)) 
		{ 
			throw new CException; 
		} 
 
		if(bmfh.bfType!=0x4d42) 
		{ 
			throw new CException; 
		} 
 
		nSize=bmfh.bfOffBits-sizeof(BITMAPFILEHEADER); 
		m_lpBMIH=(LPBITMAPINFOHEADER)new char[nSize]; 
		m_nBmihAlloc=m_nImageAlloc=crtAlloc; 
 
		nCount=pFile->Read(m_lpBMIH,nSize); 
 
		ComputeMetrics(); 
 
		ComputePaletteSize(m_lpBMIH->biBitCount); 
	 
		MakePalette(); 
 
		m_lpImage=(LPBYTE)new char[m_dwSizeImage]; 
		nCount=pFile->Read(m_lpImage,m_dwSizeImage); 
 
		for(int i=0;i<100;i++) 
		{ 
			ko[i]=*(m_lpImage+i+220000); 
		} 
 
 
	} 
 
	catch(CException *pe) 
	{ 
		AfxMessageBox("Read Error!"); 
		pe->Delete(); 
		return FALSE; 
	} 
 
	return TRUE; 
} 
 
BOOL CDib::ReadSection(CFile *pFile,CDC* pDC)//=NULL 
{ 
	Empty(); 
 
	int nCount,nSize; 
	BITMAPFILEHEADER bmfh; 
 
	try 
	{ 
		nCount=pFile->Read((LPVOID)&bmfh,sizeof(BITMAPFILEHEADER)); 
		if(nCount!=sizeof(BITMAPFILEHEADER)) 
		{ 
			throw new CException; 
		} 
 
		if(bmfh.bfType!=0x4d42) 
		{ 
			throw new CException; 
		} 
 
		nSize=bmfh.bfOffBits-sizeof(BITMAPINFOHEADER); 
		m_lpBMIH=(LPBITMAPINFOHEADER)new char[nSize]; 
		m_nBmihAlloc=crtAlloc; 
		m_nImageAlloc=noAlloc; 
 
		nCount=pFile->Read(m_lpBMIH,nSize); 
 
		if(m_lpBMIH->biCompression!=BI_RGB) 
		{ 
			throw new CException; 
		} 
 
		ComputeMetrics(); 
 
		ComputePaletteSize(m_lpBMIH->biBitCount); 
 
		MakePalette(); 
 
		//here is the differences from Read(). 
		UsePalette(pDC); 
 
		//here is the differences from Read(). 
		m_hBitmap=::CreateDIBSection(pDC->GetSafeHdc(),(LPBITMAPINFO)m_lpBMIH, 
										DIB_RGB_COLORS,(LPVOID*)&m_lpImage,NULL,0); 
		ASSERT(m_lpImage!=NULL); 
			 
		nCount=pFile->Read(m_lpImage,m_dwSizeImage); 
	} 
 
	catch(CException *pe) 
	{ 
		AfxMessageBox("ReadSection Error!"); 
		pe->Delete(); 
		return FALSE; 
	} 
 
	return FALSE; 
} 
 
BOOL CDib::Write(CFile* pFile) 
{ 
	BITMAPFILEHEADER bmfh; 
 
	bmfh.bfType=0x4d42; 
 
	int nSizeHdr=sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*m_nColorTableEntries; 
 
	bmfh.bfSize=sizeof(BITMAPFILEHEADER)+nSizeHdr+m_dwSizeImage; 
	bmfh.bfReserved1=bmfh.bfReserved2=0; 
	bmfh.bfOffBits=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*m_nColorTableEntries; 
 
	try 
	{ 
		pFile->Write((LPVOID)&bmfh,sizeof(BITMAPFILEHEADER)); 
		pFile->Write((LPVOID)m_lpBMIH,nSizeHdr); 
		pFile->Write((LPVOID)m_lpImage,m_dwSizeImage); 
	} 
 
	catch(CException *pe) 
	{ 
		AfxMessageBox("Write Error!"); 
		pe->Delete(); 
		return FALSE;	 
	} 
 
	return TRUE; 
} 
 
void CDib::Serialize(CArchive& ar) 
{ 
	DWORD dwPos; 
 
	dwPos=ar.GetFile()->GetPosition(); 
	TRACE("CDib::Serialize--pos=%d\n",dwPos); 
 
	ar.Flush(); 
 
	dwPos=ar.GetFile()->GetPosition(); 
	TRACE("CDib::Serialize--pos=%d\n",dwPos); 
 
	if(ar.IsStoring()) 
	{ 
		Write(ar.GetFile()); 
	} 
 
	else 
	{ 
		Read(ar.GetFile()); 
	} 
} 
 
////////////////////////////////////////////////////////////////////////// 
//show up a picture in DIB form. 
BOOL CDib::Draw(CDC* pDC,CPoint origin,CSize size) 
{ 
	if(m_lpBMIH==NULL) return FALSE; 
 
	if(m_hPalette!=NULL) 
	{ 
		::SelectPalette(pDC->GetSafeHdc(),m_hPalette,TRUE); 
	} 
	 
	pDC->SetStretchBltMode(COLORONCOLOR); 
 
	::StretchDIBits(pDC->GetSafeHdc(),origin.x,origin.y,size.cx,size.cy, 
					0,0,m_lpBMIH->biWidth,m_lpBMIH->biHeight,m_lpImage, 
					(LPBITMAPINFO)m_lpBMIH,DIB_RGB_COLORS,SRCCOPY); 
 
	return TRUE; 
} 
 
/////////////////////////////////////////////////////////////////////////// 
//operate a palette 
BOOL CDib::MakePalette() 
{ 
	if(m_nColorTableEntries==0) return FALSE; 
 
	if(m_hPalette!=NULL) ::DeleteObject(m_hPalette); 
	TRACE("CDib::MakePalette--m_nColorTableEntries=%d\n",m_nColorTableEntries); 
 
	LPLOGPALETTE pLogPal=(LPLOGPALETTE)new char[sizeof(DWORD)+m_nColorTableEntries*sizeof(PALETTEENTRY)]; 
 
	pLogPal->palVersion=0x300; 
	pLogPal->palNumEntries=m_nColorTableEntries; 
 
	LPRGBQUAD pDibQuad=(LPRGBQUAD)m_lpvColorTable; 
	for(int i=0;ipalPalEntry[i].peRed=pDibQuad->rgbRed; 
		pLogPal->palPalEntry[i].peGreen=pDibQuad->rgbGreen; 
		pLogPal->palPalEntry[i].peBlue=pDibQuad->rgbBlue; 
		pLogPal->palPalEntry[i].peFlags=0; 
	} 
 
	m_hPalette=::CreatePalette(pLogPal); 
 
	delete[] pLogPal; 
	return TRUE; 
} 
 
BOOL CDib::SetSystemPalette(CDC* pDC) 
{ 
	if(m_nColorTableEntries==0) return FALSE; 
 
	m_hPalette=::CreateHalftonePalette(pDC->GetSafeHdc()); 
 
	return TRUE; 
} 
 
UINT CDib::UsePalette(CDC* pDC,BOOL bBackGround) 
{ 
	if(m_hPalette==NULL) return 0; 
 
	HDC hdc=pDC->GetSafeHdc(); 
 
	::SelectPalette(hdc,m_hPalette,bBackGround); 
 
	return ::RealizePalette(hdc); 
} 
 
///////////////////////////////////////////////////////////////////////////// 
//release located memory and check whether being empty 
void CDib::Empty() 
{ 
	DetachMapFile(); 
 
	if(m_nBmihAlloc==crtAlloc) 
	{ 
		delete[] m_lpBMIH; 
	} 
	 
	else 
	{ 
		if(m_nBmihAlloc==heapAlloc) 
		{ 
			::GlobalUnlock(m_hGlobal); 
			::GlobalFree(m_hGlobal); 
		} 
	} 
 
	if(m_nImageAlloc==crtAlloc) delete[] m_lpImage; 
 
	if(m_hPalette!=NULL) ::DeleteObject(m_hPalette); 
 
	if(m_hBitmap!=NULL) ::DeleteObject(m_hBitmap); 
 
	m_nBmihAlloc=m_nImageAlloc=noAlloc; 
 
	m_hGlobal=NULL; 
	m_lpBMIH=NULL; 
	m_lpImage=NULL; 
	m_lpvColorTable=NULL; 
	m_nColorTableEntries=0; 
	m_dwSizeImage=0; 
	m_lpvFile=NULL; 
	m_hMap=NULL; 
	m_hFile=NULL; 
	m_hBitmap=NULL; 
	m_hPalette=NULL; 
} 
 
BOOL CDib::IsEmpty() 
{ 
	if(m_lpBMIH==NULL&&m_lpImage==NULL) 
		return TRUE; 
	else 
		return FALSE; 
} 
 
//////////////////////////////////////////////////////////////////////////// 
//operate internal memory 
void CDib::DetachMapFile() 
{ 
	if(m_hFile==NULL) return; 
 
	::UnmapViewOfFile(m_lpvFile); 
 
	::CloseHandle(m_hMap); 
	::CloseHandle(m_hFile); 
	m_hFile=NULL; 
} 
 
//////////////////////////////////////////////////////////////////////////// 
//compute numbers 
void CDib::ComputeMetrics() 
{ 
	m_lpvColorTable=m_lpBMIH+sizeof(BITMAPFILEHEADER); 
 
	if(m_lpBMIH->biSizeImage==0) 
	{ 
		DWORD dwBytes=(DWORD)m_lpBMIH->biWidth*m_lpBMIH->biBitCount/32; 
 
		if((DWORD)m_lpBMIH->biWidth*m_lpBMIH->biBitCount%32) 
			dwBytes++; 
 
		dwBytes*=4; 
		 
		m_lpBMIH->biSizeImage=dwBytes*m_lpBMIH->biHeight; 
	} 
	 
	m_dwSizeImage=m_lpBMIH->biSizeImage; 
 
} 
 
void CDib::ComputePaletteSize(int nBitCount) 
{ 
	if(nBitCount) 
	{ 
		switch(nBitCount) 
		{ 
		case 1: 
			m_nColorTableEntries=2; 
			break; 
		case 4: 
			m_nColorTableEntries=16; 
			break; 
		case 8: 
			m_nColorTableEntries=256; 
			break; 
		case 16: 
		case 24: 
		case 32: 
			m_nColorTableEntries=0; 
			break; 
		default: 
			break; 
		} 
	} 
} 
 
//////////////////////////////////////////////////////////////////////////// 
//get attributes of a DIB picture 
CSize CDib::GetDibSaveDim() 
{ 
	CSize sizeSaveDim; 
	int k=(m_lpBMIH->biWidth*m_lpBMIH->biBitCount+31)/32*4; 
	sizeSaveDim.cx=(m_lpBMIH->biWidth*m_lpBMIH->biBitCount+31)/32*4; 
	sizeSaveDim.cy=m_lpBMIH->biHeight; 
	return sizeSaveDim; 
} 
 
CSize CDib::GetDimension() 
{ 
	if(m_lpBMIH==NULL) return CSize(0,0); 
	return CSize((int)m_lpBMIH->biWidth,m_lpBMIH->biHeight); 
} 
 
LONG CDib::GetPixelOffset(int x,int y) 
{ 
	CSize sizeSaveDim; 
	sizeSaveDim=GetDibSaveDim(); 
	LONG lOffset=(LONG)(sizeSaveDim.cy-y-1)*sizeSaveDim.cx+x*m_lpBMIH->biBitCount/8; 
 
	return lOffset; 
} 
 
RGBQUAD CDib::GetPixel(int x,int y) 
{ 
	RGBQUAD cColor; 
	switch(m_lpBMIH->biBitCount) 
	{ 
	case 1: 
		if(1<<(7-x%8)&*(LPBYTE)(m_lpImage+GetPixelOffset(x,y))) 
		{ 
			cColor.rgbBlue=255; 
			cColor.rgbGreen=255; 
			cColor.rgbRed=255; 
			cColor.rgbReserved=0; 
		} 
 
		else 
		{ 
			cColor.rgbBlue=0; 
			cColor.rgbGreen=0; 
			cColor.rgbRed=0; 
			cColor.rgbReserved=0; 
		} 
 
		break; 
 
	case 4: 
		{//{} is necessary here. 
		int nIndex=(*(LPBYTE)(m_lpImage+GetPixelOffset(x,y))&(x%2?0x0f:0xf0)) 
			>>(x%2?0:4); 
 
		LPRGBQUAD pDibQuad=(LPRGBQUAD)(m_lpvColorTable)+nIndex; 
		cColor.rgbBlue=pDibQuad->rgbBlue; 
		cColor.rgbGreen=pDibQuad->rgbGreen; 
		cColor.rgbRed=pDibQuad->rgbRed; 
		cColor.rgbReserved=0; 
		} 
 
		break; 
 
	case 8: 
		{ 
		int nIndex=*(BYTE*)(m_lpImage+GetPixelOffset(x,y)); 
 
		LPRGBQUAD pDibQuad=(LPRGBQUAD)(m_lpvColorTable)+nIndex; 
		cColor.rgbBlue=pDibQuad->rgbBlue; 
		cColor.rgbGreen=pDibQuad->rgbGreen; 
		cColor.rgbRed=pDibQuad->rgbRed; 
		cColor.rgbReserved=0; 
		} 
 
		break; 
 
	default: 
		int nIndex=*(BYTE*)(m_lpImage+GetPixelOffset(x,y)); 
 
		cColor.rgbBlue=m_lpImage[nIndex]; 
		cColor.rgbGreen=m_lpImage[nIndex+1]; 
		cColor.rgbRed=m_lpImage[nIndex+2]; 
		cColor.rgbReserved=0; 
 
		break; 
 
	} 
 
	return cColor; 
} 
 
/* 
int CDib::GetSizeImage(){return m_dwSizeImage;} 
 
int CDib::GetSizeHeader() 
	{return sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*m_nColorTableEntries;} 
*/ 
 
WORD CDib::PaletteSize() 
{ 
	WORD NumColors; 
	LPBITMAPINFOHEADER lpbi=m_lpBMIH; 
 
	NumColors=(m_lpBMIH->biClrUsed==0&&m_lpBMIH->biBitCount<=8)? 
		(int)(1<biBitCount):(int)m_lpBMIH->biClrUsed;//int is equal to WORD 
	//in the structure, *?*:*, () is needed outside the second and the last *. 
 
//the way of the definition of color is not the same with BITMAPINFOHEADER. 
	if(lpbi->biSize==sizeof(BITMAPCOREHEADER)) 
		return NumColors*sizeof(RGBTRIPLE); 
	else 
		return NumColors*sizeof(RGBQUAD); 
 
}