|
|
#include "header.h"
#include "DibCls.H"
#define _HRESULT_TYPEDEF_(_sc) ((HRESULT)_sc)
#include <urlmon.h>
#define WIDTHBYTES(bits) (((bits) + 31) / 32 * 4)
//=--------------------------------------------------------------------------=
// DIB Utitilty Classes
//=--------------------------------------------------------------------------=
// Not wholey generic but getting there...
//
// Notes:
//
CDibFile::CDibFile() { m_headerSize = 0; m_bmi.p = 0; }
CDibFile::~CDibFile() { if( m_bmi.p ) delete m_bmi.p; }
DWORD CDibFile::CalcImageSize() { DWORD & dw = m_bmi.p->bmiHeader.biSizeImage; if( dw == 0) dw = WIDTHBYTES((DWORD)m_bmi.p->bmiHeader.biWidth * m_bmi.p->bmiHeader.biBitCount) * m_bmi.p->bmiHeader.biHeight;
return(dw); }
HRESULT CDibFile::GetInfoHeader( IStream * strm ) { HRESULT hr = S_OK; m_bmi.bytes = new unsigned char[ m_headerSize ];
if( !m_bmi.bytes ) hr = E_OUTOFMEMORY;
if( SUCCEEDED(hr) ) hr = strm->Read(m_bmi.bytes,m_headerSize,0);
if( SUCCEEDED(hr) ) CalcImageSize();
return(hr); }
HRESULT CDibFile::GetFileHeader(IStream * strm) { BITMAPFILEHEADER bmfh;
HRESULT hr = strm->Read(&bmfh,sizeof(bmfh),0); if( SUCCEEDED(hr) && (bmfh.bfType != 0x4d42 )) hr = E_UNEXPECTED;
if( SUCCEEDED(hr) ) m_headerSize = bmfh.bfOffBits - sizeof(bmfh);
return(hr); }
CDibSection::CDibSection() { m_bitsBase = 0; m_current = 0; m_memDC = 0; m_handle = m_oldBitmap = 0; m_w = m_h = 32; // totally arbitrary
}
CDibSection::~CDibSection() { if( m_memDC ) { if( m_oldBitmap ) ::SelectObject( m_memDC, m_oldBitmap );
::DeleteDC(m_memDC); }
if( m_handle ) ::DeleteObject(m_handle);
} HRESULT CDibSection::Create(CDibFile& dibFile) { HRESULT hr = S_OK; BITMAPINFOHEADER * bmih = dibFile; // will convert itself
m_handle = ::CreateDIBSection( m_memDC, // handle to device context
dibFile, // pointer to structure containing bitmap size,
// format, and color data
DIB_RGB_COLORS, // color data type indicator: RGB values or
// palette indices
(void **)&m_bitsBase, // pointer to variable to receive a pointer
// to the bitmap's bit values
0, // optional handle to a file mapping object
0 // offset to the bitmap bit values
// within the file mapping object
);
if( !m_handle ) hr = E_FAIL; if( SUCCEEDED(hr) ) { m_oldBitmap = ::SelectObject( m_memDC, m_handle ); if( !m_oldBitmap ) hr = E_FAIL; }
if( SUCCEEDED(hr) ) { m_current = m_bitsBase;
m_w = bmih->biWidth; m_h = bmih->biHeight; if( m_h < 0 ) m_h *= -1; } return(hr); }
HRESULT CDibSection::ReadFrom( IStream * strm, DWORD amount ) { DWORD dwRead = 0; DWORD dwReadTotal = 0; HRESULT hr;
do { hr = strm->Read(m_current,amount,&dwRead);
if( SUCCEEDED(hr) || hr == E_PENDING ) { m_current += dwRead; dwReadTotal += dwRead; } } while ( (hr == S_OK) && (dwReadTotal <= amount) );
return (hr); }
HRESULT CDibSection::Setup(HDC hdc) { m_memDC = ::CreateCompatibleDC(hdc);
return( m_memDC ? NOERROR : E_FAIL ); }
HRESULT CDibSection::PaintTo(HDC hdc, int x, int y) { BOOL b = BitBlt( hdc, // handle to destination device context
x, // x-coordinate of destination rectangle's upper-left corner
y, // x-coordinate of destination rectangle's upper-left corner
m_w, // width of destination rectangle
m_h, // height of destination rectangle
m_memDC, // handle to source device context
0, // x-coordinate of source rectangle's upper-left corner
0, // y-coordinate of source rectangle's upper-left corner
SRCCOPY // raster operation code
);
return( b ? NOERROR : E_FAIL ); }
HRESULT CDibSection::GetSize(SIZEL &sz) { sz.cx = m_w; sz.cy = m_h;
return(S_OK); }
|