windows-nt/Source/XPSP1/NT/printscan/ui/uicommon/memdib.h
2020-09-26 16:20:57 +08:00

349 lines
9.6 KiB
C++

/*******************************************************************************
*
* (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 <windows.h>
#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<BITMAPINFO*>( 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<BYTE*>(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<nLineCount;i++)
{
if (nStartLine + 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<nLineCount;i++)
{
if (nStartLine + 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