/******************************************************************************* * * (C) COPYRIGHT MICROSOFT CORPORATION, 1998 * * TITLE: MEMDIB.H * * VERSION: 1.0 * * AUTHOR: ShaunIv * * DATE: 7/14/1998 * * DESCRIPTION: This class allows you to construct a bitmap from raw bitmap data. * IMPORTANT: All source data is assumed to be TOP-DOWN!!!!!! * *******************************************************************************/ #ifndef __MEMDIB_H_INCLUDED #define __MEMDIB_H_INCLUDED #include #include "miscutil.h" #include "wiadebug.h" class CMemoryDib { private: PBYTE m_pBitmapBits; HBITMAP m_hBitmap; UINT m_nHeaderLength; private: // No implementation int operator=( const CMemoryDib & ); CMemoryDib( const CMemoryDib & ); public: CMemoryDib(void) : m_hBitmap(NULL), m_pBitmapBits(NULL), m_nHeaderLength(0) { } virtual ~CMemoryDib(void) { Destroy(); } void Destroy(void) { if (m_hBitmap) { DeleteObject(m_hBitmap); m_hBitmap = NULL; } m_nHeaderLength = 0; m_pBitmapBits = NULL; } bool IsValid(void) const { bool bResult = (m_hBitmap && m_pBitmapBits && m_nHeaderLength); return bResult; } PBYTE GetBitmapBits(void) { if (!IsValid()) { return NULL; } return (m_pBitmapBits); } bool GetDibSection( DIBSECTION &ds ) { if (IsValid() && GetObject( m_hBitmap, sizeof(DIBSECTION), &ds )) { return true; } return false; } LONG GetBitsPerPixel(void) { if (!IsValid()) { return 0; } DIBSECTION ds; if (GetDibSection(ds)) { return ds.dsBmih.biBitCount; } return 0; } LONG GetWidthInPixels(void) { if (!IsValid()) { return 0; } DIBSECTION ds; if (GetDibSection(ds)) { return ds.dsBmih.biWidth; } return 0; } LONG GetPackedWidthInBytes(void) { if (!IsValid()) { return 0; } return (GetWidthInPixels() * GetBitsPerPixel()) / 8; } LONG GetUnpackedWidthInBytes(void) { if (!IsValid()) { return 0; } return (WiaUiUtil::Align(GetWidthInPixels() * GetBitsPerPixel(), sizeof(DWORD)*8)/8); } LONG GetHeight(void) { if (!IsValid()) { return 0; } DIBSECTION ds; if (GetDibSection(ds)) { return ds.dsBmih.biHeight; } return 0; } UINT GetHeaderLength(void) const { if (!IsValid()) { return 0; } return m_nHeaderLength; } LONG GetUnpackedBitmapDataSize(void) { if (!IsValid()) { return 0; } return (GetUnpackedWidthInBytes() * GetHeight()); } LONG GetPackedBitmapDataSize(void) { if (!IsValid()) { return 0; } return (GetPackedWidthInBytes() * GetHeight()); } HBITMAP Bitmap(void) { if (!IsValid()) { return NULL; } return m_hBitmap; } HBITMAP DetachBitmap(void) { HBITMAP hBitmap = m_hBitmap; m_hBitmap = NULL; m_pBitmapBits = NULL; return hBitmap; } static void DumpBitmap( PBITMAPINFO pBitmapInfo ) { WIA_TRACE((TEXT("pBitmapInfo: %08X"), pBitmapInfo )); WIA_TRACE((TEXT("biSize: %d\nbiWidth: %d\nbiHeight: %d\nbiPlanes: %d\nbiBitCount: %d\nbiCompression: %d\nbiSizeImage: %d\nbiXPelsPerMeter: %d\nbiYPelsPerMeter: %d\nbiClrUsed: %d\nbiClrImportant: %d"), pBitmapInfo->bmiHeader.biSize, pBitmapInfo->bmiHeader.biWidth, pBitmapInfo->bmiHeader.biHeight, pBitmapInfo->bmiHeader.biPlanes, pBitmapInfo->bmiHeader.biBitCount, pBitmapInfo->bmiHeader.biCompression, pBitmapInfo->bmiHeader.biSizeImage, pBitmapInfo->bmiHeader.biXPelsPerMeter, pBitmapInfo->bmiHeader.biYPelsPerMeter, pBitmapInfo->bmiHeader.biClrUsed, pBitmapInfo->bmiHeader.biClrImportant)); } bool Initialize( PBITMAPINFO pBitmapInfo ) { // // Clear everything // Destroy(); if (pBitmapInfo) { // // What kind of bitmap is this? // DumpBitmap(pBitmapInfo); // // Get the header size. We'll need it later // m_nHeaderLength = WiaUiUtil::GetBmiSize(pBitmapInfo); if (m_nHeaderLength) { // // Allocate a new BITMAPINFOHEADER + palette // BITMAPINFO *pNewBitmapInfo = reinterpret_cast( new BYTE[m_nHeaderLength] ); if (pNewBitmapInfo) { // // Copy the header and palette // CopyMemory( pNewBitmapInfo, pBitmapInfo, m_nHeaderLength ); // // Make sure we have a positive height // pNewBitmapInfo->bmiHeader.biHeight = WiaUiUtil::Absolute( pNewBitmapInfo->bmiHeader.biHeight ); // // If this is one of those "unknown length" bitmaps, normalize it to be 8.5 x 11 // if (!pNewBitmapInfo->bmiHeader.biHeight) { pNewBitmapInfo->bmiHeader.biHeight = WiaUiUtil::MulDivNoRound(pNewBitmapInfo->bmiHeader.biWidth,1100,850); } m_hBitmap = CreateDIBSection( NULL, pNewBitmapInfo, DIB_RGB_COLORS, (void**)&m_pBitmapBits, 0, 0 ); if (m_hBitmap) { // // Initialize it to white. We hope. It will depend on the palette. // FillMemory( m_pBitmapBits, GetUnpackedBitmapDataSize(), 0xFF ); } else { WIA_PRINTHRESULT((HRESULT_FROM_WIN32(GetLastError()),TEXT("CreateDIBSection FAILED"))); } // // Free up our temporary header // delete[] reinterpret_cast(pNewBitmapInfo); } else { WIA_ERROR((TEXT("pNewBitmapInfo is NULL"))); } } else { WIA_ERROR((TEXT("m_nHeaderLength was 0"))); } // // Make sure there are no turds left over // if (!IsValid()) { WIA_ERROR((TEXT("IsValid() was FALSE"))); Destroy(); } } else { WIA_ERROR((TEXT("pBitmapInfo is NULL"))); } return IsValid(); } bool SetPackedData( PBYTE pData, int nStartLine, int nLineCount ) { if (!IsValid()) { return false; } nStartLine = WiaUiUtil::Absolute(nStartLine); nLineCount = WiaUiUtil::Absolute(nLineCount); for (int i=0;i= 0 && nStartLine + i < GetHeight()) { PBYTE pDest = GetBitmapBits() + (GetHeight()-nStartLine-i-1) * GetUnpackedWidthInBytes(); CopyMemory( pDest, pData + GetPackedWidthInBytes() * i, GetPackedWidthInBytes() ); } else { WIA_ERROR((TEXT("CMemoryDib::SetPackedData: Ignoring out-of-range data: nStartLine: %d, nLineCount: %d"), nStartLine, nLineCount )); } } return true; } bool ScrollDataUp( int nScrollCount ) { if (!IsValid()) { return false; } if (nScrollCount > GetHeight()) { nScrollCount = GetHeight(); } PBYTE pSourceLine = GetBitmapBits() + (GetHeight() - nScrollCount - 1) * GetUnpackedWidthInBytes(); PBYTE pTargetLine = GetBitmapBits() + (GetHeight() - 1) * GetUnpackedWidthInBytes(); for (int i=0;i < GetHeight() - nScrollCount;i++) { CopyMemory(pTargetLine,pSourceLine,GetUnpackedWidthInBytes()); pSourceLine -= GetUnpackedWidthInBytes(); pTargetLine -= GetUnpackedWidthInBytes(); } return true; } bool SetUnpackedData( PBYTE pData, int nStartLine, int nLineCount ) { if (!IsValid()) { return false; } nStartLine = WiaUiUtil::Absolute(nStartLine); nLineCount = WiaUiUtil::Absolute(nLineCount); for (int i=0;i= 0 && nStartLine + i < GetHeight()) { PBYTE pDest = GetBitmapBits() + (GetHeight()-nStartLine-i-1) * GetUnpackedWidthInBytes(); CopyMemory( pDest, pData + GetUnpackedWidthInBytes() * i, GetUnpackedWidthInBytes() ); } else { WIA_ERROR((TEXT("CMemoryDib::SetPackedData: Ignoring out-of-range data: nStartLine: %d, nLineCount: %d"), nStartLine, nLineCount )); } } return true; } }; #endif // __MEMDIB_H_INCLUDED