📄 wiadevice.h
字号:
// (when the raw header is individually sent before calling GetNextBand)
//
if((m_dwTotalBytesRead == 0) && (!IsEqualGUID(guidFormatID, WiaImgFmt_RAW)))
{
// Read the header.
memcpy(pBuffer,&m_bmfh, sizeof(m_bmfh));
memcpy(pBuffer + sizeof(m_bmfh),&m_bmih, sizeof(m_bmih));
*pulBytesRead = m_ulHeaderSize;
hr = S_OK;
}
else
{
//
// For WIA raw transfers we do not have much to do in this case other than
// just copy the DIB data which already had DWORD line alignment, in the
// current line order the DIB provides (bottom to top usually) considering
// the raw header describes the current order (the WIA raw format supports
// both possible configurations). So we'll use the same code for both
// formats, WiaImgFmt_BMP and WiaImgFmt_RAW.
//
// Read a data band
// First calculate number of bytes in whole scan lines.
DWORD dwNumLineBytesInBuffer = (ulBufferSize - (ulBufferSize % iScanline));
DWORD dwNumBytesLeftToRead = (m_dwTotalBytesToRead - m_dwTotalBytesRead);
// Set how many bytes we are going to read. This is either the maxiumun
// nunmber of scan lines that will fit into the buffer, or it's the number
// of bytes left in the last chunk.
if(dwNumBytesLeftToRead < dwNumLineBytesInBuffer)
{
dwNumLineBytesInBuffer = dwNumBytesLeftToRead;
}
// Position buffer pointer to correct data location for this band. We are copying
// in reverse scanline order so that the bitmap becomes topdown (it is currently
// upside-down in the source buffer).
BYTE *pBits = m_pBitmapBits + (m_pBitmapData->Height * m_pBitmapData->Stride);
pBits -= (m_pBitmapData->Stride * (1 + m_dwLinesRead));
DWORD dwDestOffset = 0;
for (BYTE *pCurLine = pBits; dwDestOffset < dwNumLineBytesInBuffer; pCurLine -= m_pBitmapData->Stride, m_dwLinesRead++)
{
memcpy(pBuffer + dwDestOffset, pCurLine, iScanline);
dwDestOffset += iScanline;
}
*pulBytesRead = dwNumLineBytesInBuffer;
hr = S_OK;
}
m_dwTotalBytesRead += *pulBytesRead;
if(IsEqualGUID(guidFormatID, WiaImgFmt_RAW))
{
*plPercentComplete = (LONG)((((float)(m_RawHeader.HeaderSize + m_dwTotalBytesRead) /
(float)(m_RawHeader.RawDataSize + m_RawHeader.HeaderSize + m_RawHeader.PaletteSize))) * 100.0f);
}
else
{
*plPercentComplete = (LONG)((((float)m_dwTotalBytesRead/(float)m_dwTotalBytesToRead)) * 100.0f);
}
}
else
{
// We have no more data
hr = WIA_STATUS_END_OF_MEDIA;
}
}
else
{
WIAS_ERROR((g_hInst, "Invalid parameters"));
hr = E_INVALIDARG;
}
return hr;
}
HRESULT Upload(__in BSTR bstrItemName,
ULONG ulTotalBytes,
__in IStream *pSourceStream,
__callback IWiaMiniDrvTransferCallback *pTransferCallback,
__inout WiaTransferParams *pParams,
const CBasicStringWide &cswStoragePath)
{
// TBD: don't write to C:\TEMP\DATATRANSFERTEST, use actual storage item.
HRESULT hr = S_OK;
IStream *pDestination = NULL;
CBasicStringWide cswFileName = cswStoragePath;
cswFileName += L"\\";
cswFileName += bstrItemName;
// create stream on a file in the temporary directory (filename is bstrItemName)
hr = SHCreateStreamOnFile(cswFileName.String(),STGM_WRITE|STGM_CREATE,&pDestination);
if(SUCCEEDED(hr))
{
// loop while reading data is availble from source stream
BYTE *pBuffer = (BYTE*)CoTaskMemAlloc(DEFAULT_BUFFER_SIZE);
if(pBuffer)
{
ULONG ulNumBytesRead = 0;
ULONG ulNumBytesWritten = 0;
ULONG ulTotalBytesWritten = 0;
//
// Seek to the beginning of the stream before reading:
//
LARGE_INTEGER li = {0};
hr = pSourceStream->Seek(li, STREAM_SEEK_SET, NULL);
if (FAILED(hr))
{
WIAS_ERROR((g_hInst, "Could not seek to stream start before during upload, hr = 0x%lx", hr));
}
while (SUCCEEDED(hr) && SUCCEEDED(pSourceStream->Read(pBuffer,DEFAULT_BUFFER_SIZE,&ulNumBytesRead)) && ulNumBytesRead)
{
// write the chunk
hr = pDestination->Write(pBuffer,ulNumBytesRead,&ulNumBytesWritten);
if(FAILED(hr))
{
WIAS_ERROR((g_hInst, "Failed to write upload data to destination stream, hr = 0x%lx",hr));
break;
}
ulTotalBytesWritten += ulNumBytesWritten;
LONG lPercentComplete = -1;
if(ulTotalBytes > 0)
{
lPercentComplete = (LONG)((((float)ulTotalBytesWritten/(float)ulTotalBytes)) * 100.0f);
}
// make callback
pParams->lMessage = WIA_TRANSFER_MSG_STATUS;
pParams->lPercentComplete = lPercentComplete;
pParams->ulTransferredBytes = ulTotalBytesWritten;
hr = pTransferCallback->SendMessage(0,pParams);
if(SUCCEEDED(hr))
{
if(S_FALSE == hr)
{
WIAS_TRACE((g_hInst,"Application cancelled upload"));
break;
}
else if (S_OK != hr)
{
WIAS_ERROR((g_hInst, "SendMessage returned unknown Success value, hr = 0x%lx",hr));
hr = E_UNEXPECTED;
break;
}
}
else
{
WIAS_ERROR((g_hInst, "Failed to send status message to application. Upload aborted, hr = 0x%lx",hr));
break;
}
}
if(ulTotalBytesWritten == 0)
{
hr = E_FAIL;
WIAS_ERROR((g_hInst, "No data was written during upload, hr = 0x%lx",hr));
}
CoTaskMemFree(pBuffer);
pBuffer = NULL;
}
else
{
hr = E_OUTOFMEMORY;
WIAS_ERROR((g_hInst, "Failed to allocate buffer for upload, hr = 0x%lx",hr));
}
// TBD: decide on exact behavior for notifying clients.
pDestination->Release();
pDestination = NULL;
}
else
{
WIAS_ERROR((g_hInst, "Failed to create destination stream on file %ws, hr = 0x%lx",cswFileName.String(),hr));
}
return hr;
}
public:
DWORD m_dwTotalBytesToRead;
WIA_RAW_HEADER m_RawHeader;
private:
ULONG m_ulHeaderSize;
BITMAPFILEHEADER m_bmfh;
BITMAPINFOHEADER m_bmih;
DWORD m_dwTotalBytesRead;
DWORD m_dwLinesRead;
ULONG m_ulBytesPerLineBMP;
ULONG m_ulBytesPerLineRAW;
Bitmap *m_pBitmap;
BitmapData *m_pBitmapData;
BYTE *m_pBitmapBits;
};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -