DIBCLS.CPP

//=--------------------------------------------------------------------------= 
// DibCls.Cpp
//=--------------------------------------------------------------------------=
// Copyright 1995 - 1998 Microsoft Corporation. All Rights Reserved.
//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//=--------------------------------------------------------------------------=
//
// contains the CDibFile and CDibSection classes.
//
#include "IPServer.H"

#include "DibCls.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)
{
BITMAPFILEHEADERbmfh;

HRESULThr = 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)
{
HRESULThr= 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 = (HBITMAP) ::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;
HRESULT hr;

do
{
hr = strm->Read(m_current, m_imageSize, &dwRead);

if (SUCCEEDED(hr) || hr == E_PENDING)
m_current += dwRead;
}
while (!(hr == E_PENDING || hr == S_FALSE) && SUCCEEDED(hr));

return (hr);
}


HRESULT CDibSection::Setup(HDC hdc)
{
m_memDC = ::CreateCompatibleDC(hdc);

return( m_memDC ? NOERROR : E_FAIL );
}


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

HRESULTCDibSection::GetSize(SIZEL &sz)
{
sz.cx = m_w;
sz.cy = m_h;

return(S_OK);
}