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