windows-nt/Source/XPSP1/NT/printscan/wia/drivers/camera/testcam/camxfer.cpp
2020-09-26 16:20:57 +08:00

1196 lines
29 KiB
C++

/*******************************************************************************
*
* (C) COPYRIGHT MICROSOFT CORP., 1998
*
* TITLE: memcam.cpp
*
* VERSION: 2.0
*
* AUTHOR: Mark Enstrom [marke]
* Indy Zhu [indyz]
*
* DATE: 2/4/1998
* 5/18/1998
*
* DESCRIPTION:
* Implementation of an ImageIn test camera device object.
*
*******************************************************************************/
#include <stdio.h>
#include <objbase.h>
#include <tchar.h>
#include <sti.h>
extern HINSTANCE g_hInst; // Global hInstance
#include "testusd.h"
VOID
VerticalFlip(
PBYTE pImageTop,
LONG iHeight,
LONG iWidthInBytes);
/**************************************************************************\
* CamLoadPicture
*
* load a bmp from disk and copy it to application
*
* Arguments:
*
* pCameraImage - pointer to data structure with image info
* pDataTransCtx - pointer to minidriver transfer context
*
* Return Value:
*
* status
*
* History:
*
* 2/10/1998 Mark Enstrom [marke]
*
\**************************************************************************/
HRESULT
TestUsdDevice::CamLoadPicture(
MEMCAM_IMAGE_CONTEXT *pMCamContext,
PMINIDRV_TRANSFER_CONTEXT pDataTransCtx,
PLONG plCamErrVal)
{
LONG lScanLineWidth;
HRESULT hr = S_OK;
LONG cbNeeded;
IWiaMiniDrvCallBack *pIProgressCB;
WIAS_TRACE((g_hInst,"CamLoadPicture"));
//
// verify some params
//
if (! pMCamContext) {
return (E_INVALIDARG);
}
if (pDataTransCtx->guidFormatID != WiaImgFmt_BMP && pDataTransCtx->guidFormatID != WiaAudFmt_WAV) {
return (E_NOTIMPL);
}
pIProgressCB = pDataTransCtx->pIWiaMiniDrvCallBack;
//
// Simulate the download of data from the camera
//
if (pIProgressCB) {
hr = pIProgressCB->MiniDrvCallback(
IT_MSG_STATUS,
IT_STATUS_TRANSFER_FROM_DEVICE,
(LONG)0, // Percentage Complete,
0,
0,
pDataTransCtx,
0);
if (hr != S_OK) {
return (hr); // Client want to cancel the transfer or error
}
}
HANDLE hFile = CreateFile(
pMCamContext->pszCameraImagePath,
GENERIC_WRITE | GENERIC_READ ,
FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL
);
if (hFile == INVALID_HANDLE_VALUE) {
hr = HRESULT_FROM_WIN32(::GetLastError());
return (hr);
}
if (pIProgressCB) {
hr = pIProgressCB->MiniDrvCallback(
IT_MSG_STATUS,
IT_STATUS_TRANSFER_FROM_DEVICE,
(LONG)25, // Percentage Complete,
0,
0,
pDataTransCtx,
0);
}
if (hr != S_OK) {
CloseHandle(hFile);
return (hr);
}
HANDLE hMap = CreateFileMapping(
hFile,
NULL,
PAGE_READWRITE,
0,
0,
NULL);
if (hMap == NULL) {
hr = HRESULT_FROM_WIN32(::GetLastError());
} else {
if (pIProgressCB) {
hr = pIProgressCB->MiniDrvCallback(
IT_MSG_STATUS,
IT_STATUS_TRANSFER_FROM_DEVICE,
(LONG)50, // Percentage Complete,
0,
0,
pDataTransCtx,
0);
}
}
if (hr != S_OK) {
CloseHandle(hFile);
return (hr);
}
PBYTE pFile = (PBYTE)MapViewOfFileEx(
hMap,
FILE_MAP_READ | FILE_MAP_WRITE,
0,
0,
0,
NULL);
if (pFile == NULL) {
hr = HRESULT_FROM_WIN32(::GetLastError());
} else {
if (pIProgressCB) {
hr = pIProgressCB->MiniDrvCallback(
IT_MSG_STATUS,
IT_STATUS_TRANSFER_FROM_DEVICE,
(LONG)100, // Percentage Complete,
0,
0,
pDataTransCtx,
0);
}
}
if (hr != S_OK) {
CloseHandle(hFile);
CloseHandle(hMap);
return(hr);
}
if (pDataTransCtx->guidFormatID == WiaImgFmt_BMP)
{
//
// File contains BITMAPFILEHEADER + BITMAPINFO structure.
//
// DIB Data is located bfOffBits after start of file
//
PBITMAPFILEHEADER pbmFile = (PBITMAPFILEHEADER)pFile;
PBITMAPINFO pbmi = (PBITMAPINFO)(pFile +
sizeof(BITMAPFILEHEADER));
//
// validate bitmap
//
if (pbmFile->bfType != 'MB') {
//
// file is not a bitmap
//
UnmapViewOfFile(pFile);
CloseHandle(hMap);
CloseHandle(hFile);
return(E_FAIL);
}
//
// write image size
//
// make sure to align scanline to ULONG boundary
//
// calculate byte width
//
lScanLineWidth = pbmi->bmiHeader.biWidth * pbmi->bmiHeader.biBitCount;
//
// round up to nearenst DWORD
//
lScanLineWidth = (lScanLineWidth + 31) >> 3;
lScanLineWidth &= 0xfffffffc;
cbNeeded = lScanLineWidth * pbmi->bmiHeader.biHeight;
if (cbNeeded > ((LONG)pDataTransCtx->lItemSize - (LONG)pDataTransCtx->cbOffset)) {
hr = HRESULT_FROM_WIN32(ERROR_BUFFER_OVERFLOW);
} else {
//
// copy only the bitmap bits (no headers)
//
memcpy(
pDataTransCtx->pTransferBuffer + pDataTransCtx->cbOffset,
pFile + pbmFile->bfOffBits,
cbNeeded);
}
}
else
{
memcpy (pDataTransCtx->pTransferBuffer,
pFile,
pDataTransCtx->lItemSize);
}
UnmapViewOfFile(pFile);
CloseHandle(hMap);
CloseHandle(hFile);
return(S_OK);
}
/**************************************************************************\
* CamLoadPictureCB
*
* return data by filling the data buffer and calling back to the client
*
* Arguments:
*
* pCameraImage - image item
* pTransCtx - mini driver transfer contect
*
* Return Value:
*
* status
*
* History:
*
* 1/10/1999 Mark Enstrom [marke]
*
\**************************************************************************/
HRESULT TestUsdDevice::CamLoadPictureCB(
MEMCAM_IMAGE_CONTEXT *pMCamContext,
MINIDRV_TRANSFER_CONTEXT *pTransCtx,
PLONG plCamErrVal)
{
LONG lScanLineWidth;
HRESULT hr = E_FAIL;
WIAS_TRACE((g_hInst,"CamLoadPictureCB"));
//
// verify parameters
//
if (!pMCamContext) {
return (E_INVALIDARG);
}
if (pTransCtx == NULL) {
return (E_INVALIDARG);
}
if ((pTransCtx->guidFormatID != WiaImgFmt_BMP) &&
(pTransCtx->guidFormatID != WiaImgFmt_MEMORYBMP)) {
return (E_NOTIMPL);
}
//
// try to open disk file
//
HANDLE hFile = CreateFile(
pMCamContext->pszCameraImagePath,
GENERIC_WRITE | GENERIC_READ ,
FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL
);
if (hFile == INVALID_HANDLE_VALUE) {
hr = HRESULT_FROM_WIN32(::GetLastError());
return(hr);
}
HANDLE hMap = CreateFileMapping(
hFile,
NULL,
PAGE_READWRITE,
0,
0,
NULL);
if (hMap == NULL) {
CloseHandle(hFile);
hr = HRESULT_FROM_WIN32(::GetLastError());
return(hr);
}
PBYTE pFile = (PBYTE)MapViewOfFileEx(
hMap,
FILE_MAP_READ | FILE_MAP_WRITE,
0,
0,
0,
NULL);
if (pFile == NULL) {
CloseHandle(hFile);
CloseHandle(hMap);
hr = HRESULT_FROM_WIN32(::GetLastError());
return(hr);
}
//
// File contains BITMAPFILEHEADER + BITMAPINFO structure.
//
// DIB Data is located bfOffBits after start of file
//
PBITMAPFILEHEADER pbmFile = (PBITMAPFILEHEADER)pFile;
PBITMAPINFO pbmi = (PBITMAPINFO)(pFile +
sizeof(BITMAPFILEHEADER));
//
// validate bitmap
//
if (pbmFile->bfType != 'MB') {
//
// file is not a bitmap
//
UnmapViewOfFile(pFile);
CloseHandle(hMap);
CloseHandle(hFile);
return(E_FAIL);
}
//
// get image size
//
// make sure to align scanline to ULONG boundary
//
// calculate byte width
//
lScanLineWidth = pbmi->bmiHeader.biWidth * pbmi->bmiHeader.biBitCount;
//
// round up to nearenst DWORD
//
lScanLineWidth = (lScanLineWidth + 31) >> 3;
lScanLineWidth &= 0xfffffffc;
LONG lBytesRemaining = lScanLineWidth * pbmi->bmiHeader.biHeight;
//
// Flip the image vertically if WiaImgFmt_MEMORYBMP is requested
//
if (pTransCtx->guidFormatID == WiaImgFmt_MEMORYBMP) {
VerticalFlip(
(PBYTE)pFile + pbmFile->bfOffBits,
pbmi->bmiHeader.biHeight,
lScanLineWidth);
}
//
// callback loop
//
PBYTE pSrc = (PBYTE)pFile + pbmFile->bfOffBits;
LONG lTransferSize;
LONG lPercentComplete;
do {
PBYTE pDst = pTransCtx->pTransferBuffer;
//
// transfer up to entire buffer size
//
lTransferSize = lBytesRemaining;
if (lBytesRemaining > pTransCtx->lBufferSize) {
lTransferSize = pTransCtx->lBufferSize;
}
//
// copy data
//
memcpy(pDst, pSrc, lTransferSize);
lPercentComplete = 100 * (pTransCtx->cbOffset + lTransferSize);
lPercentComplete /= pTransCtx->lItemSize;
//
// make callback
//
hr = pTransCtx->pIWiaMiniDrvCallBack->MiniDrvCallback(
IT_MSG_DATA,
IT_STATUS_TRANSFER_TO_CLIENT,
lPercentComplete,
pTransCtx->cbOffset,
lTransferSize,
pTransCtx,
0);
//
// inc pointers (redundant pointers here)
//
pSrc += lTransferSize;
pTransCtx->cbOffset += lTransferSize;
lBytesRemaining -= lTransferSize;
if (hr != S_OK) {
break;
}
} while (lBytesRemaining > 0);
//
// Flip the image back if WiaImgFmt_MEMORYBMP is requested
//
if (pTransCtx->guidFormatID == WiaImgFmt_MEMORYBMP) {
VerticalFlip(
(PBYTE)pFile + pbmFile->bfOffBits,
pbmi->bmiHeader.biHeight,
lScanLineWidth);
}
//
// Garbage collection
//
UnmapViewOfFile(pFile);
CloseHandle(hMap);
CloseHandle(hFile);
return(hr);
}
/**************************************************************************\
* CamGetPictureInfo
*
* Load file, get information from image
*
* Arguments:
*
* pCameraImage - image item
* pPictInfo - fill out ino about image
* ppBITMAPINFO - alloc and fill out BITMAPINFO
* pBITMAPINFOSize - size
*
* Return Value:
*
* status
*
* History:
*
* 1/17/1999 Mark Enstrom [marke]
*
\**************************************************************************/
HRESULT
TestUsdDevice::CamGetPictureInfo(
MEMCAM_IMAGE_CONTEXT *pMCamContext,
PCAMERA_PICTURE_INFO pPictInfo,
PBYTE *ppBITMAPINFO,
LONG *pBITMAPINFOSize)
{
HRESULT hr = S_OK;
FILETIME ftCreate;
SYSTEMTIME stCreate;
WIAS_TRACE((g_hInst,"CamGetPictureInfo"));
//
// Try to open disk file
//
HANDLE hFile = CreateFile(
pMCamContext->pszCameraImagePath,
GENERIC_WRITE | GENERIC_READ,
FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL
);
if (hFile == INVALID_HANDLE_VALUE) {
hr = HRESULT_FROM_WIN32(::GetLastError());
return(hr);
}
//
// Grab the creation time for this image
//
if (GetFileTime( hFile, &ftCreate, NULL, NULL)) {
FileTimeToSystemTime( &ftCreate, &stCreate );
} else {
//
// To return something, use the system time
//
GetLocalTime( &stCreate );
}
HANDLE hMap = CreateFileMapping(
hFile,
NULL,
PAGE_READWRITE,
0,
0,
NULL
);
if (hMap == NULL) {
CloseHandle(hFile);
hr = HRESULT_FROM_WIN32(::GetLastError());
return(hr);
}
PBYTE pFile = (PBYTE)MapViewOfFileEx(
hMap,
FILE_MAP_READ | FILE_MAP_WRITE,
0,
0,
0,
NULL);
if (pFile == NULL) {
CloseHandle(hFile);
CloseHandle(hMap);
hr = HRESULT_FROM_WIN32(::GetLastError());
return(hr);
}
//
// File contains BITMAPFILEHEADER + BITMAPINFO structure.
//
// DIB Data is located bfOffBits after start of file
//
PBITMAPFILEHEADER pbmFile = (PBITMAPFILEHEADER)pFile;
PBITMAPINFOHEADER pbmiHeader =
(PBITMAPINFOHEADER)(pFile +
sizeof(BITMAPFILEHEADER));
PBYTE pDIBFile = pFile + pbmFile->bfOffBits;
//
// validate bitmap.
//
if (pbmFile->bfType != 'MB') {
//
// file is not a bitmap
//
UnmapViewOfFile(pFile);
CloseHandle(hFile);
CloseHandle(hMap);
return(E_FAIL);
}
//
// fill out image information
//
pPictInfo->PictNumber = 0; // ??? Should support picture handle ???
pPictInfo->ThumbWidth = 80;
pPictInfo->ThumbHeight = 60;
pPictInfo->PictWidth = pbmiHeader->biWidth;
pPictInfo->PictHeight = pbmiHeader->biHeight;
pPictInfo->PictCompSize = 0;
pPictInfo->PictFormat = 0;
pPictInfo->PictBitsPerPixel = pbmiHeader->biBitCount;
{
LONG lScanLineWidth = (pbmiHeader->biWidth *
pbmiHeader->biBitCount);
//
// round up to nearenst DWORD
//
lScanLineWidth = (lScanLineWidth + 31) >> 3;
//
// remove extra bytes
//
lScanLineWidth &= 0xfffffffc;
pPictInfo->PictBytesPerRow = lScanLineWidth;
}
//
// is there a color table
//
LONG ColorMapSize = 0;
LONG bmiSize;
if (pbmiHeader->biBitCount == 1) {
ColorMapSize = 2;
} else if (pbmiHeader->biBitCount == 4) {
ColorMapSize = 16;
} else if (pbmiHeader->biBitCount == 8) {
ColorMapSize = 256;
}
//
// Changed by Indy on 5/18/98 to BITMAPINFOHEADER
//
bmiSize = sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * ColorMapSize;
*ppBITMAPINFO = (PBYTE)ALLOC(bmiSize);
if (*ppBITMAPINFO != NULL) {
memcpy(*ppBITMAPINFO, pbmiHeader, bmiSize);
*pBITMAPINFOSize = bmiSize;
} else {
UnmapViewOfFile(pFile);
CloseHandle(hFile);
CloseHandle(hMap);
return(E_OUTOFMEMORY);
}
//
// Set the time for the image
//
memcpy(&pPictInfo->TimeStamp, &stCreate, sizeof(pPictInfo->TimeStamp));
//
// close up the file
//
UnmapViewOfFile(pFile);
CloseHandle(hMap);
CloseHandle(hFile);
return(hr);
}
/**************************************************************************\
* CamLoadThumbnail
*
* Load the thumbnail of the specified picture
*
* Arguments:
*
* pCameraImage - image item
* pThumbnail - buffer for thumbnail
* pThumbSize - size of thumbnail
*
* Return Value:
*
* status
*
* History:
*
* 2/9/1998 Mark Enstrom [marke]
* 6/9/1998 Indy Zhu [indyz]
*
\**************************************************************************/
HRESULT
TestUsdDevice::CamLoadThumbnail(
MEMCAM_IMAGE_CONTEXT *pMCamContext ,
PBYTE *pThumbnail,
LONG *pThumbSize
)
{
TCHAR pszThumbName[MAX_PATH];
HRESULT hr;
BOOL bCacheThumb = TRUE;
BOOL bThumbExists = TRUE;
PBYTE pTmbPixels;
HBITMAP hbmThumb = NULL;
PBYTE pThumb = NULL;
HANDLE hTmbFile = INVALID_HANDLE_VALUE;
HANDLE hTmbMap = NULL;
PBYTE pTmbFile = NULL;
HANDLE hFile = INVALID_HANDLE_VALUE;
HANDLE hMap = NULL;
PBYTE pFile = NULL;
BITMAPINFO bmiDIB;
HDC hdc = NULL;
HDC hdcm1 = NULL;
WIAS_TRACE((g_hInst,"CamLoadThumbnail"));
//
// Initialize the return values
//
*pThumbnail = NULL;
*pThumbSize = 0;
//
// Fill in the size of the tumbnail pixel buffer
//
bmiDIB.bmiHeader.biSizeImage = 80*60*3;
//
// Build thumbnail filename Image.bmp.tmb
//
_tcscpy(pszThumbName, pMCamContext->pszCameraImagePath);
_tcscat(pszThumbName, TEXT(".tmb"));
__try {
hTmbFile = CreateFile(
pszThumbName,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL
);
//
// See if cached thumbnail already exists
//
if (hTmbFile == INVALID_HANDLE_VALUE) {
//
// Try to create a new one
//
hTmbFile = CreateFile(
pszThumbName,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_WRITE,
NULL,
CREATE_NEW,
FILE_ATTRIBUTE_NORMAL,
NULL
);
//
// Thumbnail need to be created
//
bThumbExists = FALSE;
}
//
// thumbnail file exists
//
if (hTmbFile != INVALID_HANDLE_VALUE) {
hTmbMap = CreateFileMapping(
hTmbFile,
NULL,
PAGE_READWRITE,
0,
80 * 60 * 3,
NULL);
if (hTmbMap != NULL) {
pTmbFile = (PBYTE)MapViewOfFileEx(
hTmbMap,
FILE_MAP_READ | FILE_MAP_WRITE,
0,
0,
0,
NULL);
if (pTmbFile) {
if (bThumbExists) {
//
// Alloca memory for thumbnail pixels
//
pTmbPixels = (PBYTE)ALLOC(bmiDIB.bmiHeader.biSizeImage);
if (! pTmbPixels) {
return(E_OUTOFMEMORY);
}
//
// Pull the thumbnail from the cached file
//
memcpy(pTmbPixels, pTmbFile,
bmiDIB.bmiHeader.biSizeImage);
//
// All the handles will be closed in __finally block
//
*pThumbnail = pTmbPixels;
*pThumbSize = bmiDIB.bmiHeader.biSizeImage;
return(S_OK);
}
} else {
bCacheThumb = FALSE;
}
} else {
bCacheThumb = FALSE;
}
} else {
//
// Can't cache thumbnail
//
bCacheThumb = FALSE;
}
//
// Try to create a thumbnail from the full-size image
// and cache it if the thumbnail cache file is created
//
hFile = CreateFile(
pMCamContext->pszCameraImagePath,
GENERIC_WRITE | GENERIC_READ,
FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL
);
if (hFile == INVALID_HANDLE_VALUE) {
hr = HRESULT_FROM_WIN32(::GetLastError());
return(hr);
}
hMap = CreateFileMapping(
hFile,
NULL,
PAGE_READWRITE,
0,
0,
NULL
);
if (hMap == NULL) {
hr = HRESULT_FROM_WIN32(::GetLastError());
return(hr);
}
pFile = (PBYTE)MapViewOfFileEx(
hMap,
FILE_MAP_READ | FILE_MAP_WRITE,
0,
0,
0,
NULL
);
if (pFile == NULL) {
hr = HRESULT_FROM_WIN32(::GetLastError());
return(hr);
}
PBITMAPFILEHEADER pbmFile = (PBITMAPFILEHEADER)pFile;
PBITMAPINFO pbmi = (PBITMAPINFO)(pFile +
sizeof(BITMAPFILEHEADER));
PBYTE pPixels = pFile + pbmFile->bfOffBits;
//
// Generate the thumbnail from the full-size image
//
hdc = GetDC(NULL);
hdcm1 = CreateCompatibleDC(hdc);
SetStretchBltMode(hdcm1, COLORONCOLOR);
//
// Create a BITMAP for rendering the thumbnail
//
bmiDIB.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmiDIB.bmiHeader.biBitCount = 24;
bmiDIB.bmiHeader.biWidth = 80;
bmiDIB.bmiHeader.biHeight = 60;
bmiDIB.bmiHeader.biPlanes = 1;
bmiDIB.bmiHeader.biCompression = BI_RGB;
bmiDIB.bmiHeader.biXPelsPerMeter = 100;
bmiDIB.bmiHeader.biYPelsPerMeter = 100;
bmiDIB.bmiHeader.biClrUsed = 0;
bmiDIB.bmiHeader.biClrImportant = 0;
hbmThumb = CreateDIBSection(hdc, &bmiDIB, DIB_RGB_COLORS,
(VOID **)&pThumb, NULL, 0);
if (! hbmThumb) {
hr = HRESULT_FROM_WIN32(::GetLastError());
return hr;
}
HBITMAP hbmDef = (HBITMAP)SelectObject(hdcm1, hbmThumb);
//
// Init DIB
//
memset(pThumb, 0, bmiDIB.bmiHeader.biSizeImage);
//
// create 80x60 thumbnail while preserving image
// aspect ratio
//
LONG lThumbWidth;
LONG lThumbHeight;
double fImageWidth = (double)pbmi->bmiHeader.biWidth;
double fImageHeight = (double)pbmi->bmiHeader.biHeight;
double fAspect = fImageWidth / fImageHeight;
double fDefAspect = 80.0 / 60.0;
if (fAspect > fDefAspect) {
lThumbWidth = 80;
lThumbHeight = (LONG)(80.0 / fAspect);
} else {
lThumbHeight = 60;
lThumbWidth = (LONG)(60.0 * fAspect);
}
int i = StretchDIBits(
hdcm1,
0,
0,
lThumbWidth,
lThumbHeight,
0,
0,
pbmi->bmiHeader.biWidth,
pbmi->bmiHeader.biHeight,
pPixels,
pbmi,
DIB_RGB_COLORS,
SRCCOPY
);
SelectObject(hdcm1, hbmDef);
//
// Cache ?
//
if (bCacheThumb) {
memcpy(pTmbFile, pThumb, bmiDIB.bmiHeader.biSizeImage);
}
//
// Alloca memory for thumbnail pixels
//
pTmbPixels = (PBYTE)ALLOC(bmiDIB.bmiHeader.biSizeImage);
if (! pTmbPixels) {
return(E_OUTOFMEMORY);
}
//
// Write out data
//
memcpy(pTmbPixels, pThumb, bmiDIB.bmiHeader.biSizeImage);
*pThumbnail = pTmbPixels;
*pThumbSize = bmiDIB.bmiHeader.biSizeImage;
return(S_OK);
} // End of __try { ... } block
__finally {
if (pTmbFile) {
UnmapViewOfFile(pTmbFile);
}
if (hTmbMap) {
CloseHandle(hTmbMap);
}
if (hTmbFile != INVALID_HANDLE_VALUE) {
CloseHandle(hTmbFile);
}
if (pFile) {
UnmapViewOfFile(pFile);
}
if (hMap) {
CloseHandle(hMap);
}
if (hFile != INVALID_HANDLE_VALUE) {
CloseHandle(hFile);
}
if (hbmThumb) {
DeleteObject(hbmThumb);
}
if (hdcm1) {
DeleteDC(hdcm1);
}
if (hdc) {
ReleaseDC(NULL, hdc);
}
}
return(E_FAIL);
}
/**************************************************************************\
* CamDeletePicture
*
*
* Arguments:
*
*
*
* Return Value:
*
*
*
* History:
*
* 6/3/1998 Mark Enstrom [marke]
*
\**************************************************************************/
HRESULT
CamDeletePicture(
MEMCAM_IMAGE_CONTEXT *pMCamContext)
{
return(E_NOTIMPL);
}
/**************************************************************************\
* CamTakePicture
*
*
* Arguments:
*
*
*
* Return Value:
*
*
*
* History:
*
* 6/3/1998 Mark Enstrom [marke]
*
\**************************************************************************/
HRESULT
CamTakePicture(
MEMCAM_IMAGE_CONTEXT *pMCamContext ,
ULONG *pHandle)
{
return (E_NOTIMPL);
}
/**************************************************************************\
* VertivalFlip
*
*
*
* Arguments:
*
*
*
* Return Value:
*
* Status
*
* History:
*
* 11/18/1998 Original Version
*
\**************************************************************************/
VOID
VerticalFlip(
PBYTE pImageTop,
LONG iHeight,
LONG iWidthInBytes)
{
//
// try to allocat a temp scan line buffer
//
PBYTE pBuffer = (PBYTE)LocalAlloc(LPTR,iWidthInBytes);
if (pBuffer != NULL) {
LONG index;
PBYTE pImageBottom;
pImageBottom = pImageTop + (iHeight-1) * iWidthInBytes;
for (index = 0;index < (iHeight/2);index++) {
memcpy(pBuffer,pImageTop,iWidthInBytes);
memcpy(pImageTop,pImageBottom,iWidthInBytes);
memcpy(pImageBottom,pBuffer,iWidthInBytes);
pImageTop += iWidthInBytes;
pImageBottom -= iWidthInBytes;
}
LocalFree(pBuffer);
}
}