📄 wiadevice.h
字号:
/*****************************************************************************
*
* WiaDevice.h
*
* Copyright (c) 2003 Microsoft Corporation. All Rights Reserved.
*
* DESCRIPTION:
*
* This class simulates a "real" device from which we can acquire image data and upload
* image data. It uses GDI+ internally to create the image.
*
*******************************************************************************/
#pragma once
using namespace Gdiplus;
extern HINSTANCE g_hInst;
class WiaDevice
{
public:
WiaDevice() :
m_dwTotalBytesToRead(0),
m_dwTotalBytesRead(0),
m_dwLinesRead(0),
m_pBitmap(NULL),
m_pBitmapData(NULL),
m_pBitmapBits(NULL),
m_ulHeaderSize(NULL),
m_ulBytesPerLineBMP(0),
m_ulBytesPerLineRAW(0)
{
memset(&m_bmfh, 0, sizeof(m_bmfh));
memset(&m_bmih, 0, sizeof(m_bmih));
};
virtual ~WiaDevice()
{
UninitializeForDownload();
};
HRESULT InitializeForDownload(
__in BYTE *pWiasContext,
__in HINSTANCE hInstance,
UINT uiBitmapResourceID,
const GUID &guidFormatID)
{
HRESULT hr = E_INVALIDARG;
memset(&m_RawHeader, 0, sizeof(m_RawHeader));
if((pWiasContext)&&(hInstance))
{
m_pBitmap = new Bitmap(hInstance,MAKEINTRESOURCE(uiBitmapResourceID));
if(m_pBitmap)
{
m_pBitmapData = new BitmapData;
if(m_pBitmapData)
{
hr = LockSelectionAreaOnBitmap(pWiasContext, m_pBitmap, m_pBitmapData, &m_bmih, &m_pBitmapBits);
if(SUCCEEDED(hr))
{
if(IsEqualGUID(guidFormatID, WiaImgFmt_RAW))
{
//
// Raw format (no color palette is used, just the header):
//
m_ulHeaderSize = sizeof(WIA_RAW_HEADER);
}
else
{
//
// Device Independent Bitmap (DIB):
//
m_ulHeaderSize = sizeof(m_bmfh) + sizeof(m_bmih);
}
//
// Initialize the remaining BITMAPINFOHEADER fields (use for both BMP and RAW transfers):
//
m_bmfh.bfType = ((WORD) ('M' << 8) | 'B');
m_bmfh.bfOffBits = sizeof(m_bmfh) + sizeof(m_bmih); //m_ulHeaderSize;
m_bmfh.bfSize = m_bmfh.bfOffBits + m_bmih.biSizeImage;
//
// We assume the sample source data is 24-bit RGB only:
//
m_ulBytesPerLineBMP = m_bmih.biWidth * 3;
//
// The WIA raw format requires image lines to be DWORD aligned,
// in this case however the DIB data that we are using as the
// source is already DWORD aligned:
//
// m_ulBytesPerLineRAW = (m_ulBytesPerLineBMP + 3) & ~3;
//
m_ulBytesPerLineRAW = m_ulBytesPerLineBMP;
//
// m_dwTotalBytesToRead is used to measure the total number of bytes to read from the source DIB
// (in a real case for RAW this may be different than the actual number of bytes to be transferred,
// however in this particular case the two match because we accept in this sample only DIBs at input
// - with the exception of the DIB file header, see below..)
//
if(IsEqualGUID(guidFormatID, WiaImgFmt_RAW))
{
//
// For Raw this is just the size of the DIB data (no file header)
//
m_dwTotalBytesToRead = m_bmih.biSizeImage;
//
// The number of bytes in the raw data is described in this case by the number of bytes
// to be read from the DIB source (the data comes already DWORD aligned so the two numbers
// match in this particular case):
//
m_RawHeader.RawDataSize = m_dwTotalBytesToRead;
m_RawHeader.BytesPerLine = m_ulBytesPerLineRAW;
}
else
{
//
// For bitmap transfers the DIB file header is transferred too..
//
m_dwTotalBytesToRead = m_bmfh.bfSize;
m_RawHeader.RawDataSize = 0;
}
m_dwTotalBytesRead = 0;
m_dwLinesRead = 0;
}
}
else
{
hr = E_OUTOFMEMORY;
WIAS_ERROR((g_hInst, "Failed to allocate memory for GDI+ bitmap data object, hr = 0x%lx",hr));
}
}
else
{
hr = E_OUTOFMEMORY;
WIAS_ERROR((g_hInst, "Failed to allocate memory for GDI+ bitmap object, hr = 0x%lx",hr));
}
}
else
{
WIAS_ERROR((g_hInst, "Invalid parameters were passed"));
}
return hr;
}
void UninitializeForDownload()
{
if (m_pBitmap && m_pBitmapData)
{
UnlockSelectionAreaOnBitmap(m_pBitmap, m_pBitmapData);
}
m_pBitmapBits = NULL;
SAFE_DELETE(m_pBitmapData);
SAFE_DELETE(m_pBitmap);
}
BOOL InitializedForDownload()
{
return (BOOL)(m_pBitmap && m_pBitmapData);
}
BitmapData* GetBitmapData()
{
return m_pBitmapData;
}
HRESULT GetNextBand(__out_bcount_part(ulBufferSize, *pulBytesRead) BYTE *pBuffer,
ULONG ulBufferSize,
__out ULONG *pulBytesRead,
__out LONG *plPercentComplete,
const GUID &guidFormatID)
{
HRESULT hr = S_OK;
if (pBuffer && pulBytesRead && plPercentComplete && (ulBufferSize > m_ulHeaderSize))
{
//
// iScanline contains the number of bytes to copy from each scanline
//
// Note: this logic works well considering that we are using only
// 24-bit RGB color sample images. For a real solution different
// pixel formats and bit depths may have to be considered.
//
INT iScanline = ((m_pBitmapData->Width * 3) + 3) & ~3;
*pulBytesRead = 0;
*plPercentComplete = 0;
if(m_dwTotalBytesRead < m_dwTotalBytesToRead)
{
//
// Check whether we should send the bitmap header or the data.
// The header is always sent first, unless this is a Raw transfer
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -