www.pudn.com > opengl_pick_sample.rar > dibsect.cpp


#include "stdafx.h" 
#include "dibsect.h" 
 
 
void DIBSection::InitObject(void) 
{ 
	m_hbmp = NULL ; 
	m_pBits = NULL ; 
	m_pdc = NULL ; 
	m_total_width = 0; 
	m_bitcount = 0; 
	m_size.cx = m_size.cy = m_total_width = 0; 
} 
 
DIBSection::DIBSection() 
{ 
	InitObject(); 
} 
 
DIBSection::DIBSection(const DIBSection& dib) 
{ 
	InitObject(); 
	Copy(dib); 
} 
 
DIBSection::~DIBSection() 
{ 
	Close(); 
} 
 
void DIBSection::Copy(const DIBSection& dib) 
{ 
	Close(); 
	if (dib.IsCreated()) 
	{ 
		int w = dib.Width(); 
		int h = dib.Height(); 
		int bitcount = dib.GetBitCount(); 
 
		Create(w,h,bitcount); 
 
		if (IsCreated()) 
		{ 
			memcpy(m_pBits,dib.GetConstBits(),(h * m_total_width * bitcount / 8)); 
		} 
	} 
} 
 
DIBSection& DIBSection::operator = (const DIBSection& dib) 
{ 
	Copy(dib); 
	return *this; 
} 
 
void DIBSection::Close(void) 
{ 
	if (m_hbmOld) 
	{ 
		::SelectObject(m_pdc->GetSafeHdc(), m_hbmOld); 
	} 
 
	if (m_hbmp) DeleteObject(m_hbmp); 
 
	if (m_pdc) delete m_pdc; 
 
	InitObject(); 
} 
 
void DIBSection::Create(int cx, int cy, int nbits)  
{ 
	ASSERT(cx > 0); 
	ASSERT(cy > 0); 
 
	ASSERT((nbits == 8) || (nbits == 16) || 
	   (nbits == 24) || (nbits == 32))	; 
 
	Close(); 
 
	 // Save size for drawing later. 
	m_size.cx = cx ; 
	m_size.cy = cy ; 
 
	 // Initialize the bitmapinfo header 
	int size = sizeof(BITMAPINFOHEADER) ; 
	memset(&m_bih, 0, size); 
 
	 // Populate bitmapinfo header 
	m_bih.biSize = size; 
	m_bih.biWidth = ((((int) cx * 8) + 31) & ~31) >> 3; 
	m_bih.biHeight = cy; 
	m_bih.biPlanes = 1; 
	m_bih.biBitCount = nbits; 
	m_bih.biCompression = BI_RGB; 
	m_total_width = m_bih.biWidth; 
	m_bitcount = nbits; 
 
	  // Create a new DC. 
	m_pdc = new CDC ; 
	m_pdc->CreateCompatibleDC(NULL); 
 
	  // Create the DIB section. 
	m_hbmp = CreateDIBSection( m_pdc->GetSafeHdc(), 
							(BITMAPINFO*)&m_bih, 
							DIB_PAL_COLORS, 
							&m_pBits, 
							NULL, 
							0); 
 
	ASSERT(m_hbmp); 
	ASSERT(m_pBits); 
 
	  // Select the bitmap into the buffer 
	if (m_hbmp) 
	{ 
		m_hbmOld = (HBITMAP)::SelectObject(m_pdc->GetSafeHdc(), 
										   m_hbmp); 
	}  
} 
 
void DIBSection::Draw(CDC* pdcDest, int x, int y)  
{ 
	pdcDest->BitBlt( 0, 0, 
					 m_size.cx, m_size.cy, 
					 m_pdc, 
					 x, y, 
					 SRCCOPY); 
 
} 
void DIBSection::SetPixel(UINT32 x, UINT32 y, COLORREF cr) 
{ 
	if ((x < Width()) && (y < Height())) 
	{ 
		unsigned char * bits = (unsigned char *)GetBits(); 
		UINT32 offset = x * GetBitCount()/8 + (Height() - y - 1)*GetTotalWidth()*GetBitCount()/8; 
		bits[offset++] = GetBValue(cr); 
		bits[offset++] = GetGValue(cr); 
		bits[offset] = GetRValue(cr); 
	} 
} 
 
void DIBSection::GetPixel(UINT32 x, UINT32 y, COLORREF& cr) 
{ 
	if ((x < Width()) && (y < Height())) 
	{ 
		unsigned char * src = (unsigned char *)GetBits(); 
		unsigned char * dst = (unsigned char *)&cr; 
		UINT32 offset = x * GetBitCount()/8 + (Height() - y - 1)*GetTotalWidth()*GetBitCount()/8; 
		dst[3] = 0; 
		dst[2] = src[offset++]; 
		dst[1] = src[offset++]; 
		dst[0] = src[offset]; 
	} 
} 
 
void DIBSection::ResizeImage(DIBSection& dst_dib, int w, int h) 
{ 
	if ((w > 0) && (h > 0)) 
	{ 
		dst_dib.Create(w,h,GetBitCount()); 
 
		if (dst_dib.IsCreated()) 
		{ 
			UINT32 width = dst_dib.Width(); 
			UINT32 height = dst_dib.Height(); 
			UINT32 src_width = Width(); 
			UINT32 src_height = Height(); 
 
			if ((dst_dib.IsCreated() && (width > 0) && (height > 0)) && 
				(IsCreated() && (src_width > 0) && (src_height > 0))) 
			{ 
				double horizontal_scale = (double)src_width/(double)dst_dib.Width(); 
				double vertical_scale = (double)src_height/(double)dst_dib.Height(); 
 
				unsigned char * src_ptr = (unsigned char *)GetBits(); 
				unsigned char * dst_ptr = (unsigned char *)dst_dib.GetBits(); 
 
				UINT32 src_bytecount = GetBitCount()/8; 
				UINT32 src_dibwidth = GetTotalWidth(); 
 
				UINT32 dst_bytecount = dst_dib.GetBitCount()/8; 
				UINT32 dst_dibwidth = dst_dib.GetTotalWidth(); 
				UINT32 dst_bitcount = dst_dib.GetBitCount(); 
 
				UINT32 src_row, src_col; 
				UINT32 src_index, dst_index; 
 
				for (UINT32 row=0;row= src_height) src_row = src_height - 1; 
 
					for (UINT32 col=0;col= src_width) src_col = src_width-1; 
						src_index = src_row * src_dibwidth * src_bytecount + src_col*src_bytecount; 
						dst_index = row*dst_dibwidth*dst_bytecount+col*dst_bytecount; 
						memcpy(&dst_ptr[dst_index], 
							&src_ptr[src_index], 
							dst_bytecount); 
					} 
				} 
			} 
		} 
	} 
} 
 
void DIBSection::PatBlt(DWORD pattern) 
{ 
	if (IsCreated()) 
	{ 
		if ((Width() > 0) && (Height() > 0)) 
		{ 
			m_pdc->PatBlt(0,0,Width(),Height(),pattern); 
		} 
	} 
}