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);
}
}
}