1008 lines
22 KiB
C++
1008 lines
22 KiB
C++
//+---------------------------------------------------------------------------
|
|
//
|
|
// Microsoft Windows
|
|
// Copyright (C) Microsoft Corporation, 1992 - 1993.
|
|
//
|
|
// File: bmpfile.cxx
|
|
//
|
|
// Contents: CBitmapFile implementation
|
|
//
|
|
// Classes:
|
|
//
|
|
// Functions:
|
|
//
|
|
// History: 4-23-94 KirtD Created
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
#include "headers.hxx"
|
|
#pragma hdrstop
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: CBitmapFile::CBitmapFile
|
|
//
|
|
// Synopsis: Constructor
|
|
//
|
|
// Arguments: (none)
|
|
//
|
|
// Returns: nothing
|
|
//
|
|
// History: 4-23-94 KirtD Created
|
|
//
|
|
// Notes:
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
CBitmapFile::CBitmapFile ()
|
|
{
|
|
//
|
|
// Initialize private members
|
|
//
|
|
|
|
//
|
|
// The name
|
|
//
|
|
|
|
_pszBitmapFile[0] = '\0';
|
|
_cBitmapFile = 0;
|
|
|
|
//
|
|
// The bitmap information
|
|
//
|
|
|
|
_cbi = 0;
|
|
_pbi = NULL;
|
|
|
|
//
|
|
// The bits
|
|
//
|
|
|
|
_cbData = 0;
|
|
_pbData = NULL;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: CBitmapFile::~CBitmapFile
|
|
//
|
|
// Synopsis: Destructor
|
|
//
|
|
// Arguments: (none)
|
|
//
|
|
// Returns: nothing
|
|
//
|
|
// History: 4-23-94 KirtD Created
|
|
//
|
|
// Notes:
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
CBitmapFile::~CBitmapFile ()
|
|
{
|
|
//
|
|
// Delete any possibly allocated things
|
|
//
|
|
|
|
delete _pbi;
|
|
delete _pbData;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: CBitmapFile::LoadBitmapFile
|
|
//
|
|
// Synopsis: loads a bitmap file
|
|
//
|
|
// Arguments: [pszFile] -- the file
|
|
//
|
|
// Returns: HRESULT
|
|
//
|
|
// History: 4-23-94 KirtD Created
|
|
//
|
|
// Notes:
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
HRESULT
|
|
CBitmapFile::LoadBitmapFile (LPSTR pszFile)
|
|
{
|
|
HRESULT hr = ResultFromScode(S_OK);
|
|
HANDLE hFile = INVALID_HANDLE_VALUE;
|
|
HANDLE hMap = INVALID_HANDLE_VALUE;
|
|
DWORD dwFileSizeLow = 0;
|
|
DWORD dwFileSizeHigh = 0;
|
|
LPBYTE pbuffer = NULL;
|
|
|
|
//
|
|
// First open the file
|
|
//
|
|
|
|
hFile = CreateFileA(pszFile,
|
|
GENERIC_READ,
|
|
FILE_SHARE_READ,
|
|
NULL,
|
|
OPEN_EXISTING,
|
|
FILE_ATTRIBUTE_NORMAL,
|
|
NULL);
|
|
|
|
if (hFile == INVALID_HANDLE_VALUE)
|
|
{
|
|
hr = HRESULT_FROM_WIN32(GetLastError());
|
|
}
|
|
|
|
//
|
|
// Get the size of the file
|
|
//
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
dwFileSizeLow = GetFileSize(hFile, &dwFileSizeHigh);
|
|
if ((dwFileSizeLow == 0xFFFFFFFF) && (GetLastError() != NO_ERROR))
|
|
{
|
|
hr = HRESULT_FROM_WIN32(GetLastError());
|
|
}
|
|
else if (dwFileSizeHigh != 0)
|
|
{
|
|
//
|
|
// Bitmap files can't be greater than 4G
|
|
//
|
|
|
|
hr = ResultFromScode(E_FAIL);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Create a file mapping object on the file
|
|
//
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hMap = CreateFileMapping(hFile,
|
|
NULL,
|
|
PAGE_READONLY,
|
|
0,
|
|
dwFileSizeLow,
|
|
NULL);
|
|
|
|
if (hMap == INVALID_HANDLE_VALUE)
|
|
{
|
|
hr = HRESULT_FROM_WIN32(GetLastError());
|
|
}
|
|
}
|
|
|
|
//
|
|
// Now map a view of the file into our address space
|
|
//
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
pbuffer = (LPBYTE)MapViewOfFile(hMap, FILE_MAP_READ, 0, 0, 0);
|
|
if (pbuffer == NULL)
|
|
{
|
|
hr = HRESULT_FROM_WIN32(GetLastError());
|
|
}
|
|
}
|
|
|
|
//
|
|
// Get the bitmap data from the buffer
|
|
//
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = _GetBitmapDataFromBuffer(pbuffer, (ULONG)dwFileSizeLow);
|
|
}
|
|
|
|
//
|
|
// Record the file name
|
|
//
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
ULONG cFile;
|
|
|
|
//
|
|
// Get the length of the file name
|
|
//
|
|
|
|
cFile = strlen(pszFile);
|
|
|
|
//
|
|
// Check to see that our buffer is big enough and then copy
|
|
// it. NOTE that I can use sizeof here since the buffer is
|
|
// in characters which are 1 byte.
|
|
//
|
|
|
|
if (cFile < sizeof(_pszBitmapFile))
|
|
{
|
|
strcpy(_pszBitmapFile, pszFile);
|
|
_cBitmapFile = cFile;
|
|
}
|
|
else
|
|
{
|
|
hr = ResultFromScode(E_FAIL);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Cleanup
|
|
//
|
|
|
|
if (hMap != INVALID_HANDLE_VALUE)
|
|
{
|
|
CloseHandle(hMap);
|
|
}
|
|
|
|
if (hFile != INVALID_HANDLE_VALUE)
|
|
{
|
|
CloseHandle(hFile);
|
|
}
|
|
|
|
return(hr);
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: CBitmapFile::GetBitmapFileName
|
|
//
|
|
// Synopsis: gets the file name used to set the bitmap
|
|
//
|
|
// Arguments: [pszFile] -- the file
|
|
// [cChar] -- the length of the buffer in characters
|
|
//
|
|
// Returns: HRESULT
|
|
//
|
|
// History: 4-23-94 KirtD Created
|
|
//
|
|
// Notes:
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
HRESULT
|
|
CBitmapFile::GetBitmapFileName (LPSTR pszFile, ULONG cChar) const
|
|
{
|
|
//
|
|
// Check the length of the receiving buffer, making sure the buffer size
|
|
// includes the null terminator
|
|
//
|
|
|
|
if (cChar <= _cBitmapFile)
|
|
{
|
|
return(ResultFromScode(E_INVALIDARG));
|
|
}
|
|
|
|
//
|
|
// Copy the string
|
|
//
|
|
|
|
strcpy(pszFile, _pszBitmapFile);
|
|
|
|
return(ResultFromScode(S_OK));
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: CBitmapFile::GetBitmapFileNameLength
|
|
//
|
|
// Synopsis: returns _cBitmapFile
|
|
//
|
|
// Arguments: (none)
|
|
//
|
|
// Returns: ULONG
|
|
//
|
|
// History: 4-23-94 KirtD Created
|
|
//
|
|
// Notes:
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
ULONG
|
|
CBitmapFile::GetBitmapFileNameLength () const
|
|
{
|
|
return(_cBitmapFile);
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: CBitmapFile::GetDIBHeight
|
|
//
|
|
// Synopsis: gets the height in pixels of the DIB
|
|
//
|
|
// Arguments: (none)
|
|
//
|
|
// Returns: LONG
|
|
//
|
|
// History: 4-23-94 KirtD Created
|
|
//
|
|
// Notes:
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
LONG
|
|
CBitmapFile::GetDIBHeight () const
|
|
{
|
|
if (_pbi)
|
|
{
|
|
return(_pbi->bmiHeader.biHeight);
|
|
}
|
|
else
|
|
{
|
|
return(0);
|
|
}
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: CBitmapFile::GetDIBWidth
|
|
//
|
|
// Synopsis: gets the width in pixels of the DIB
|
|
//
|
|
// Arguments: (none)
|
|
//
|
|
// Returns: LONG
|
|
//
|
|
// History: 4-23-94 KirtD Created
|
|
//
|
|
// Notes:
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
LONG
|
|
CBitmapFile::GetDIBWidth () const
|
|
{
|
|
if (_pbi)
|
|
{
|
|
return(_pbi->bmiHeader.biWidth);
|
|
}
|
|
else
|
|
{
|
|
return(0);
|
|
}
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: CBitmapFile::GetLogicalPalette
|
|
//
|
|
// Synopsis: gets the logical palette from the DIB
|
|
//
|
|
// Arguments: [pplogpal] -- logical palette goes here
|
|
//
|
|
// Returns: HRESULT
|
|
//
|
|
// History: 4-23-94 KirtD Created
|
|
//
|
|
// Notes:
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
HRESULT
|
|
CBitmapFile::GetLogicalPalette (LPLOGPALETTE *pplogpal) const
|
|
{
|
|
HRESULT hr = ResultFromScode(S_OK);
|
|
LOGPALETTE *plogpal = NULL;
|
|
WORD cPalEntry;
|
|
LPMALLOC pMalloc = NULL;
|
|
|
|
//
|
|
// First check to see if we have been initialized with a bitmap
|
|
//
|
|
|
|
if (_pbi == NULL)
|
|
{
|
|
return(ResultFromScode(E_FAIL));
|
|
}
|
|
|
|
//
|
|
// Check to see if this bit count allows a palette
|
|
//
|
|
|
|
if (HasPaletteData() == FALSE)
|
|
{
|
|
return(ResultFromScode(E_FAIL));
|
|
}
|
|
|
|
//
|
|
// NOTE: We are about to get the number of palette entries we
|
|
// need to allocate, we do NOT use biClrUsed since we
|
|
// know that if this field was set the bitmap would
|
|
// not have been loaded, see BUGBUG in
|
|
// _GetBitmapDataFromBuffer notes section. This is
|
|
// probably a good candidate for an assert.
|
|
//
|
|
|
|
//
|
|
// Get the palette entries
|
|
//
|
|
|
|
cPalEntry = (WORD) (1 << _pbi->bmiHeader.biBitCount);
|
|
|
|
//
|
|
// Allocate a LOGPALETTE
|
|
//
|
|
|
|
hr = CoGetMalloc(MEMCTX_TASK, &pMalloc);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
plogpal = (LOGPALETTE *)pMalloc->Alloc(sizeof(LOGPALETTE)+
|
|
((cPalEntry-1)*
|
|
sizeof(PALETTEENTRY)));
|
|
|
|
if (plogpal == NULL)
|
|
{
|
|
hr = ResultFromScode(E_OUTOFMEMORY);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Copy the palette information
|
|
//
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
ULONG cCount;
|
|
|
|
plogpal->palVersion = 0x300;
|
|
plogpal->palNumEntries = cPalEntry;
|
|
|
|
for (cCount = 0; cCount < cPalEntry; cCount++)
|
|
{
|
|
plogpal->palPalEntry[cCount].peRed = _pbi->bmiColors[cCount].rgbRed;
|
|
plogpal->palPalEntry[cCount].peGreen = _pbi->bmiColors[cCount].rgbGreen;
|
|
plogpal->palPalEntry[cCount].peBlue = _pbi->bmiColors[cCount].rgbBlue;
|
|
plogpal->palPalEntry[cCount].peFlags = PC_NOCOLLAPSE;
|
|
}
|
|
|
|
*pplogpal = plogpal;
|
|
}
|
|
|
|
//
|
|
// Cleanup
|
|
//
|
|
|
|
if (pMalloc)
|
|
{
|
|
pMalloc->Release();
|
|
}
|
|
|
|
return(hr);
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: CBitmapFile::CreateDIBInHGlobal
|
|
//
|
|
// Synopsis: creates a DIB i.e. info and data in a GlobalAlloc'd buffer
|
|
//
|
|
// Arguments: [phGlobal] -- handle goes here
|
|
//
|
|
// Returns: HRESULT
|
|
//
|
|
// History: 5-06-94 KirtD Created
|
|
//
|
|
// Notes:
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
HRESULT
|
|
CBitmapFile::CreateDIBInHGlobal (HGLOBAL *phGlobal) const
|
|
{
|
|
HRESULT hr = ResultFromScode(S_OK);
|
|
ULONG cb = 0;
|
|
LPBYTE pb = NULL;
|
|
HGLOBAL hGlobal = NULL;
|
|
ULONG cbPalEntry = 0;
|
|
|
|
//
|
|
// Check to see if we are initialized
|
|
//
|
|
|
|
if (_pbi == NULL)
|
|
{
|
|
return(ResultFromScode(E_FAIL));
|
|
}
|
|
|
|
//
|
|
// The size to allocate for the data must be calculated
|
|
// from the following ...
|
|
//
|
|
|
|
//
|
|
// The size of the bitmap info plus the size of the data
|
|
//
|
|
|
|
cb = _cbi + _cbData;
|
|
|
|
//
|
|
// Allocate
|
|
//
|
|
|
|
hGlobal = GlobalAlloc(GHND, cb);
|
|
if (hGlobal == NULL)
|
|
{
|
|
hr = HRESULT_FROM_WIN32(GetLastError());
|
|
}
|
|
|
|
//
|
|
// Lock the handle
|
|
//
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
pb = (LPBYTE)GlobalLock(hGlobal);
|
|
if (pb == NULL)
|
|
{
|
|
hr = HRESULT_FROM_WIN32(GetLastError());
|
|
}
|
|
}
|
|
|
|
//
|
|
// Copy the information
|
|
//
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
//
|
|
// First the bitmap info
|
|
//
|
|
|
|
memcpy(pb, _pbi, _cbi);
|
|
|
|
//
|
|
// Move pointer but if there is no palette compensate
|
|
// for the extra RGBQUAD
|
|
//
|
|
|
|
if (_pbi->bmiHeader.biBitCount == BMP_24_BITSPERPIXEL)
|
|
{
|
|
pb += (_cbi - sizeof(RGBQUAD));
|
|
}
|
|
else
|
|
{
|
|
pb += _cbi;
|
|
}
|
|
|
|
//
|
|
// Now the bits
|
|
//
|
|
|
|
memcpy(pb, _pbData, _cbData);
|
|
}
|
|
|
|
//
|
|
// Cleanup
|
|
//
|
|
|
|
//
|
|
// If we locked the handle, unlock it
|
|
//
|
|
|
|
if (pb)
|
|
{
|
|
GlobalUnlock(hGlobal);
|
|
}
|
|
|
|
//
|
|
// If we succeeded, set the out parameter, if we failed and
|
|
// we had allocated the hGlobal, free it
|
|
//
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
*phGlobal = hGlobal;
|
|
}
|
|
else if (hGlobal)
|
|
{
|
|
GlobalFree(hGlobal);
|
|
}
|
|
|
|
return(hr);
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: CBitmapFile::HasPaletteData
|
|
//
|
|
// Synopsis: returns whether or not the dib has palette data
|
|
//
|
|
// Arguments: (none)
|
|
//
|
|
// Returns: BOOL
|
|
//
|
|
// History: 5-16-94 kirtd Created
|
|
//
|
|
// Notes:
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
BOOL
|
|
CBitmapFile::HasPaletteData () const
|
|
{
|
|
//
|
|
// If we are not initialized return FALSE
|
|
//
|
|
|
|
if (_pbi == NULL)
|
|
{
|
|
return(FALSE);
|
|
}
|
|
|
|
//
|
|
// If we are a 24, 16 or 32 bpp DIB then we do not have
|
|
// palette data
|
|
//
|
|
// BUGBUG: The case where biClrUsed is set is not dealt
|
|
// with
|
|
//
|
|
|
|
if ((_pbi->bmiHeader.biBitCount == BMP_24_BITSPERPIXEL) ||
|
|
(_pbi->bmiHeader.biBitCount == BMP_16_BITSPERPIXEL) ||
|
|
(_pbi->bmiHeader.biBitCount == BMP_32_BITSPERPIXEL))
|
|
{
|
|
return(FALSE);
|
|
}
|
|
|
|
//
|
|
// Otherwise we do have palette data
|
|
//
|
|
|
|
return(TRUE);
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: CBitmapFile::GetDIBBits
|
|
//
|
|
// Synopsis: gets the bits
|
|
//
|
|
// Arguments: (none)
|
|
//
|
|
// Returns: LPBYTE
|
|
//
|
|
// History: 5-02-94 KirtD Created
|
|
//
|
|
// Notes:
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
LPBYTE
|
|
CBitmapFile::GetDIBBits ()
|
|
{
|
|
return(_pbData);
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: CBitmapFile::GetBitmapInfo
|
|
//
|
|
// Synopsis: gets the bitmap info pointer
|
|
//
|
|
// Arguments: (none)
|
|
//
|
|
// Returns: LPBITMAPINFO
|
|
//
|
|
// History: 5-14-94 kirtd Created
|
|
//
|
|
// Notes:
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
LPBITMAPINFO
|
|
CBitmapFile::GetBitmapInfo ()
|
|
{
|
|
return(_pbi);
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: CBitmapFile::_GetBitmapDataFromBuffer
|
|
//
|
|
// Synopsis: gets the bitmap data from the given buffer
|
|
//
|
|
// Arguments: [pbuffer] -- the buffer
|
|
// [cb] -- the buffer size
|
|
//
|
|
// Returns: HRESULT
|
|
//
|
|
// History: 4-23-94 KirtD Created
|
|
//
|
|
// Notes: BUGBUG: If biClrUsed is set the bitmap is not loaded
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
HRESULT
|
|
CBitmapFile::_GetBitmapDataFromBuffer (LPBYTE pbuffer, ULONG cb)
|
|
{
|
|
HRESULT hr = ResultFromScode(S_OK);
|
|
BITMAPFILEHEADER bmfh;
|
|
BITMAPCOREHEADER *pbch;
|
|
BITMAPINFOHEADER bih;
|
|
LPBYTE pbStart;
|
|
ULONG cbi = 0;
|
|
ULONG cbData;
|
|
LPBITMAPINFO pbi = NULL;
|
|
LPBYTE pbData = NULL;
|
|
DWORD dwSizeOfHeader;
|
|
|
|
//
|
|
// Record the starting position
|
|
//
|
|
|
|
pbStart = pbuffer;
|
|
|
|
//
|
|
// First validate the buffer for size
|
|
//
|
|
|
|
if (cb < sizeof(BITMAPFILEHEADER))
|
|
{
|
|
return(ResultFromScode(E_FAIL));
|
|
}
|
|
|
|
//
|
|
// Now get the bitmap file header
|
|
//
|
|
|
|
memcpy(&bmfh, pbuffer, sizeof(BITMAPFILEHEADER));
|
|
|
|
//
|
|
// Validate the information
|
|
//
|
|
|
|
hr = _ValidateBitmapFileHeader (&bmfh, cb);
|
|
|
|
//
|
|
// Get the next 4 bytes which will represent the size of the
|
|
// next structure and allow us to determine the type
|
|
//
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
pbuffer += sizeof(BITMAPFILEHEADER);
|
|
memcpy(&dwSizeOfHeader, pbuffer, sizeof(DWORD));
|
|
|
|
if (dwSizeOfHeader == sizeof(BITMAPCOREHEADER))
|
|
{
|
|
pbch = (BITMAPCOREHEADER *)pbuffer;
|
|
memset(&bih, 0, sizeof(BITMAPINFOHEADER));
|
|
|
|
bih.biSize = sizeof(BITMAPINFOHEADER);
|
|
bih.biWidth = pbch->bcWidth;
|
|
bih.biHeight = pbch->bcHeight;
|
|
bih.biPlanes = pbch->bcPlanes;
|
|
bih.biBitCount = pbch->bcBitCount;
|
|
|
|
pbuffer += sizeof(BITMAPCOREHEADER);
|
|
}
|
|
else if (dwSizeOfHeader == sizeof(BITMAPINFOHEADER))
|
|
{
|
|
memcpy(&bih, pbuffer, sizeof(BITMAPINFOHEADER));
|
|
|
|
pbuffer += sizeof(BITMAPINFOHEADER);
|
|
}
|
|
else
|
|
{
|
|
hr = ResultFromScode(E_FAIL);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Check if biClrUsed is set since we do not handle that
|
|
// case at this time
|
|
//
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
if (bih.biClrUsed != 0)
|
|
{
|
|
hr = ResultFromScode(E_FAIL);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Now we need to calculate the size of the BITMAPINFO we need
|
|
// to allocate including any palette information
|
|
//
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
//
|
|
// First the size of the header
|
|
//
|
|
|
|
cbi = sizeof(BITMAPINFOHEADER);
|
|
|
|
//
|
|
// Now the palette
|
|
//
|
|
|
|
if (bih.biBitCount == BMP_24_BITSPERPIXEL)
|
|
{
|
|
//
|
|
// Just add on the 1 RGBQUAD for the structure but
|
|
// there is no palette
|
|
//
|
|
|
|
cbi += sizeof(RGBQUAD);
|
|
}
|
|
else if ((bih.biBitCount == BMP_16_BITSPERPIXEL) ||
|
|
(bih.biBitCount == BMP_32_BITSPERPIXEL))
|
|
{
|
|
//
|
|
// Add on the 3 DWORD masks which are used to
|
|
// get the colors out of the data
|
|
//
|
|
|
|
cbi += (3 * sizeof(DWORD));
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Anything else we just use the bit count to calculate
|
|
// the number of entries
|
|
//
|
|
|
|
cbi += ((1 << bih.biBitCount) * sizeof(RGBQUAD));
|
|
}
|
|
|
|
//
|
|
// Now allocate the BITMAPINFO
|
|
//
|
|
|
|
pbi = (LPBITMAPINFO) new BYTE [cbi];
|
|
if (pbi == NULL)
|
|
{
|
|
hr = ResultFromScode(E_OUTOFMEMORY);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Fill in the BITMAPINFO data structure and get the bits
|
|
//
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
//
|
|
// First copy the header data
|
|
//
|
|
|
|
memcpy(&(pbi->bmiHeader), &bih, sizeof(BITMAPINFOHEADER));
|
|
|
|
//
|
|
// Now the palette data
|
|
//
|
|
|
|
if (bih.biBitCount == BMP_24_BITSPERPIXEL)
|
|
{
|
|
//
|
|
// No palette data to copy
|
|
//
|
|
}
|
|
else if ((bih.biBitCount == BMP_16_BITSPERPIXEL) ||
|
|
(bih.biBitCount == BMP_32_BITSPERPIXEL))
|
|
{
|
|
//
|
|
// Copy the 3 DWORD masks
|
|
//
|
|
|
|
memcpy(&(pbi->bmiColors), pbuffer, 3*sizeof(DWORD));
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// If we were a BITMAPCOREHEADER type then we have our
|
|
// palette data in the form of RGBTRIPLEs so we must
|
|
// explicitly copy each. Otherwise we can just memcpy
|
|
// the RGBQUADs
|
|
//
|
|
|
|
if (dwSizeOfHeader == sizeof(BITMAPCOREHEADER))
|
|
{
|
|
ULONG cPalEntry = (1 << bih.biBitCount);
|
|
ULONG cCount;
|
|
RGBTRIPLE *argbt = (RGBTRIPLE *)pbuffer;
|
|
|
|
for (cCount = 0; cCount < cPalEntry; cCount++)
|
|
{
|
|
pbi->bmiColors[cCount].rgbRed =
|
|
argbt[cCount].rgbtRed;
|
|
pbi->bmiColors[cCount].rgbGreen =
|
|
argbt[cCount].rgbtGreen;
|
|
pbi->bmiColors[cCount].rgbBlue =
|
|
argbt[cCount].rgbtBlue;
|
|
|
|
pbi->bmiColors[cCount].rgbReserved = 0;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ULONG cbPalette = (1 << bih.biBitCount) * sizeof(RGBQUAD);
|
|
|
|
memcpy(&(pbi->bmiColors), pbuffer, cbPalette);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Now find out where the bits are
|
|
//
|
|
|
|
pbuffer = pbStart + bmfh.bfOffBits;
|
|
|
|
//
|
|
// Get the size to copy
|
|
//
|
|
|
|
cbData = cb - bmfh.bfOffBits;
|
|
|
|
//
|
|
// Allocate the buffer to hold the bits
|
|
//
|
|
|
|
pbData = new BYTE [cbData];
|
|
if (pbData == NULL)
|
|
{
|
|
hr = ResultFromScode(E_OUTOFMEMORY);
|
|
}
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
memcpy(pbData, pbuffer, cbData);
|
|
}
|
|
}
|
|
|
|
//
|
|
// If everything succeeded record the data
|
|
//
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
//
|
|
// Record the info
|
|
//
|
|
|
|
delete _pbi;
|
|
_cbi = cbi;
|
|
_pbi = pbi;
|
|
|
|
//
|
|
// Record the data
|
|
//
|
|
|
|
delete _pbData;
|
|
_cbData = cbData;
|
|
_pbData = pbData;
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Cleanup
|
|
//
|
|
|
|
delete pbi;
|
|
delete pbData;
|
|
}
|
|
|
|
return(hr);
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: CBitmapFile::_ValidateBitmapFileHeader
|
|
//
|
|
// Synopsis: validates a bitmap file header
|
|
//
|
|
// Arguments: [pbmfh] -- bitmap file header
|
|
// [cbFile] -- bitmap file size
|
|
//
|
|
// Returns: HRESULT
|
|
//
|
|
// History: 4-23-94 KirtD Created
|
|
//
|
|
// Notes:
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
HRESULT
|
|
CBitmapFile::_ValidateBitmapFileHeader (BITMAPFILEHEADER *pbmfh, ULONG cbFile)
|
|
{
|
|
//
|
|
// Check for the following,
|
|
//
|
|
// 1. The bfType member contains 'BM'
|
|
// 2. The bfOffset member is NOT greater than the size of the file
|
|
//
|
|
|
|
if ((pbmfh->bfType == 0x4d42) && (pbmfh->bfOffBits <= cbFile))
|
|
{
|
|
return(ResultFromScode(S_OK));
|
|
}
|
|
|
|
return(ResultFromScode(E_FAIL));
|
|
}
|