// 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

BOOL
CDIB::Create( int width, int height )
{
	Destroy();

	ZeroMemory( &m_info, sizeof( BITMAPINFO ) );

	m_info.bmiHeader.biSize = sizeof( BITMAPINFOHEADER );
	m_info.bmiHeader.biWidth = width;
	m_info.bmiHeader.biHeight = -height;
	m_info.bmiHeader.biPlanes = 1;
	m_info.bmiHeader.biBitCount = 32; 
	m_info.bmiHeader.biCompression = BI_RGB;
	m_info.bmiHeader.biSizeImage = width * height * 4;
    
	m_bitmap = CreateDIBSection( NULL, &m_info, DIB_RGB_COLORS, (void **)&m_bits, NULL, NULL ); 

	if( m_bitmap ) {
		m_size = CSize( width, height );
		return TRUE;
	} else {
		m_size = CSize( 0, 0 );
		return FALSE;
	}
}

BOOL
CDIB::Create( CDC *pDC, UINT uBitmapID )
{
	// Creates from a bitmap
	CDC			bufferDC;
    CBitmap		bufferBitmap;
	CBitmap*	oldBitmap;
	BITMAP		bmpData;

	if( !bufferBitmap.LoadBitmap( uBitmapID ) )
		return FALSE;   // Can't load resource bitmap

	if( !bufferBitmap.GetBitmap( &bmpData ) )
		return FALSE;   // Can't get bitmap info
	if( !Create( bmpData.bmWidth, bmpData.bmHeight ) )
		return FALSE;   // Can't create DIB buffer

	bufferDC.CreateCompatibleDC( pDC );
	oldBitmap = bufferDC.SelectObject( &bufferBitmap );
	GetDIBits( bufferDC.m_hDC, HBITMAP(bufferBitmap), 0, m_size.cy, m_bits, &(m_info), DIB_RGB_COLORS ); 
	bufferDC.SelectObject( oldBitmap );
	bufferBitmap.DeleteObject();

	return TRUE;
}

void
CDIB::Destroy ()
{
	if( m_bitmap )
		DeleteObject( m_bitmap );
	m_bitmap = NULL;
	m_size = CSize ( 0, 0 );
}


void
CDIB::GetFromDC( CDC *pDC, int x, int y, int w, int h )
{
	// If DibSize Wrong Re-Create Dib
	if( (m_size.cx != w) || (m_size.cy != h) )
		Create ( w, h );
    
	CDC			bufferDC;
	CBitmap		bufferBitmap;
	CBitmap*	oldBitmap;

	bufferDC.CreateCompatibleDC( pDC );
	bufferBitmap.CreateCompatibleBitmap( pDC, w, h );
	oldBitmap = bufferDC.SelectObject( &bufferBitmap );
	bufferDC.FillSolidRect( 0, 0, w, h, 0 );
	bufferDC.BitBlt( 0, 0, w, h, pDC, x, y, SRCCOPY );
	bufferDC.SelectObject( oldBitmap );
	GetDIBits( pDC->m_hDC, HBITMAP(bufferBitmap), 0, h, m_bits, &(m_info), DIB_RGB_COLORS ); 
}


BOOL 
CDIB::operator==( const CDIB &dib ) const
{
	if( m_size != dib.m_size )
		return FALSE;
	if( (NULL == m_bits) || (NULL == dib.m_bits) )
		return FALSE;
	if( 0 != memcmp( &m_info, &dib.m_info, sizeof( BITMAPINFO ) ) )
		return FALSE;
	if( 0 != memcmp( m_bits, dib.m_bits, m_info.bmiHeader.biSizeImage ) )
		return FALSE;
	return TRUE;
}

CDIB &
CDIB::operator=( const CDIB &dib )
{
	CopyFrom( &dib );
	return *this;
}

