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

650 lines
16 KiB
C++

//-------------------------------------------------------------------------
//
// Copyright (c) 1999 Microsoft Corporation.
//
// camopen.cpp
//
// Abstract:
//
// Enumerate disk images to emulate camera
//
// Author:
//
// Edward Reus 27/Jul/99
// modeled after code by Mark Enstrom
//
//-------------------------------------------------------------------------
#include <windows.h>
#include <stdio.h>
#include <objbase.h>
#include <tchar.h>
#include "sti.h"
#include "ircamera.h"
#include <irthread.h>
extern HINSTANCE g_hInst; // Global hInstance
#define __GLOBALPROPVARS__
#include "resource.h"
#include "defprop.h"
//-------------------------------------------------------------------------
// IrUsdDevice::CamOpenCamera()
//
// Initialize the IrTran-P camera driver.
//
// This is a helper called by IrUsdDevice::Initialize().
//
// Arguments:
//
// pGenericStatus - camera status
//
// Return Value:
//
// HRESULT - S_OK
//
//-------------------------------------------------------------------------
HRESULT IrUsdDevice::CamOpenCamera( IN OUT CAMERA_STATUS *pCameraStatus )
{
HRESULT hr = S_OK;
SYSTEMTIME SystemTime;
WIAS_TRACE((g_hInst,"IrUsdDevice::CamOpenCamerai()"));
//
// Initialize camera state:
//
memset( pCameraStatus, 0, sizeof(CAMERA_STATUS) );
pCameraStatus->FirmwareVersion = 0x00000001;
pCameraStatus->NumPictTaken = 20;
pCameraStatus->NumPictRemaining = 0;
pCameraStatus->ThumbWidth = 80;
pCameraStatus->ThumbHeight= 60;
pCameraStatus->PictWidth = 300;
pCameraStatus->PictHeight = 300;
GetSystemTime( &(pCameraStatus->CameraTime) );
return hr;
}
//-------------------------------------------------------------------------
// IrUsdDevice::CamBuildImageTree()
//
// Build the tree of camera images by enumerating a disk directory for
// all .JPG files.
//
// Arguments:
//
// pCamStatus - device status
// ppRootFile - return new root of item tree
//
// Return Value:
//
// status
//
//-------------------------------------------------------------------------
HRESULT IrUsdDevice::CamBuildImageTree( OUT CAMERA_STATUS *pCamStatus,
OUT IWiaDrvItem **ppRootFile )
{
HRESULT hr = S_OK;
WIAS_TRACE((g_hInst,"IrUsdDevice::CamBuildImageTree()"));
//
// Create the new image root:
//
BSTR bstrRoot = SysAllocString(L"Root");
if (!bstrRoot)
{
return E_OUTOFMEMORY;
}
//
// Call Wia service library to create new root item:
//
hr = wiasCreateDrvItem( WiaItemTypeFolder | WiaItemTypeRoot | WiaItemTypeDevice,
bstrRoot,
m_bstrRootFullItemName,
(IWiaMiniDrv*)this,
sizeof(IRCAM_IMAGE_CONTEXT),
NULL,
ppRootFile );
SysFreeString(bstrRoot);
if (FAILED(hr))
{
WIAS_ERROR((g_hInst,"ddevBuildDeviceItemTree, CreateDeviceItem failed"));
return hr;
}
//
// Enumerate the root directory:
//
CHAR *pszImageDirectory = GetImageDirectory();
if (!pszImageDirectory)
{
return E_OUTOFMEMORY;
}
#ifdef UNICODE
WCHAR wszPath[MAX_PATH];
mbstowcs( wszPath, pszImageDirectory, strlen(pszImageDirectory) );
hr = EnumDiskImages( *ppRootFile, wszPath );
#else
hr = EnumDiskImages( *ppRootFile, pszImageDirectory );
#endif
// Don't free pszImageDirectory!!
return (hr);
}
//-------------------------------------------------------------------------
// IrUsdDevice::EnumDiskImages()
//
// Walk through camera temp directory looking for JPEG files to pick up.
//
// Arguments:
//
// pRootFile
// pwszDirName
//
// Return Value:
//
// status
//
//-------------------------------------------------------------------------
HRESULT IrUsdDevice::EnumDiskImages( IWiaDrvItem *pRootFile,
TCHAR *pszDirName )
{
HRESULT hr = E_FAIL;
WIN32_FIND_DATA FindData;
TCHAR *pTempName;
WIAS_TRACE((g_hInst,"IrUsdDevice::EnumDiskImages()"));
pTempName = (TCHAR*)ALLOC(MAX_PATH);
if (!pTempName)
{
return E_OUTOFMEMORY;
}
_tcscpy( pTempName, pszDirName);
_tcscat( pTempName, TEXT("\\*.jpg") );
//
// Look for files at the specified directory:
//
HANDLE hFile = FindFirstFile( pTempName, &FindData );
if (hFile != INVALID_HANDLE_VALUE)
{
BOOL bStatus;
do {
//
// Add an image to this folder.
//
// Create file name:
//
_tcscpy(pTempName, pszDirName);
_tcscat(pTempName, TEXT("\\"));
_tcscat(pTempName, FindData.cFileName);
//
// Create a new DrvItem for this image and add it to the
// DrvItem tree.
//
IWiaDrvItem *pNewImage;
hr = CreateItemFromFileName(
WiaItemTypeFile | WiaItemTypeImage,
pTempName,
FindData.cFileName,
&pNewImage);
if (FAILED(hr))
{
break;
}
hr = pNewImage->AddItemToFolder(pRootFile);
pNewImage->Release();
//
// Look for the next image:
//
bStatus = FindNextFile(hFile,&FindData);
} while (bStatus);
FindClose(hFile);
}
//
// Now look for directories,
// add a new PCAMERA_FILE for each sub directory found
//
_tcscpy(pTempName, pszDirName);
_tcscat(pTempName, TEXT("\\*.*"));
hFile = FindFirstFile( pTempName,&FindData );
if (hFile != INVALID_HANDLE_VALUE)
{
BOOL bStatus;
do {
if ( (FindData.cFileName[0] != L'.')
&& (FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
{
//
// Found a subdirectory:
//
_tcscpy(pTempName, pszDirName);
_tcscat(pTempName, TEXT("\\"));
_tcscat(pTempName, FindData.cFileName);
//
// Create a new folder for the sub-directory:
//
IWiaDrvItem *pNewFolder;
hr = CreateItemFromFileName(
WiaItemTypeFolder,
pTempName,
FindData.cFileName,
&pNewFolder);
if (FAILED(hr))
{
continue;
}
hr = pNewFolder->AddItemToFolder(pRootFile);
pNewFolder->Release();
if (hr == S_OK)
{
//
// Enumerate the sub-folder
//
EnumDiskImages(pNewFolder, pTempName);
}
}
bStatus = FindNextFile(hFile,&FindData);
} while (bStatus);
FindClose(hFile);
}
FREE(pTempName);
return S_OK;
}
//-------------------------------------------------------------------------
// IrUsdDevice::CreateItemFromFileName()
//
// Helper funtion used by EnumDiskImages to create dev items and names.
//
// Arguments:
//
// FolderType - type of item to create
// pszPath - complete path name
// pszName - file name
// ppNewFolder - return new item
//
// Return Value:
//
// status
//
//-------------------------------------------------------------------------
HRESULT IrUsdDevice::CreateItemFromFileName( LONG FolderType,
TCHAR *pszPath,
TCHAR *pszName,
IWiaDrvItem **ppNewFolder )
{
HRESULT hr = S_OK;
WCHAR wszFullItemName[MAX_PATH];
WCHAR wszTemp[MAX_PATH];
BSTR bstrItemName;
BSTR bstrFullItemName;
IWiaDrvItem *pNewFolder = 0;
WIAS_TRACE((g_hInst,"IrUsdDevice::CreateItemFromFileName()"));
*ppNewFolder = NULL;
//
// Convert path to wide char
//
CHAR *pszImageDirectory = ::GetImageDirectory();
if (!pszImageDirectory)
{
return E_OUTOFMEMORY;
}
DWORD dwImageDirectoryLen = strlen(pszImageDirectory);
#ifndef UNICODE
MultiByteToWideChar( CP_ACP,
0,
pszPath + dwImageDirectoryLen,
strlen(pszPath) - dwImageDirectoryLen - 4,
wszTemp,
MAX_PATH);
#else
wcscpy(wszTemp, pszPath+dwImageDirectoryLen);
#endif
if (FolderType & ~WiaItemTypeFolder)
{
wszTemp[_tcslen(pszPath) - strlen(pszImageDirectory) - 4] = 0;
}
wcscpy(wszFullItemName, m_bstrRootFullItemName);
wcscat(wszFullItemName, wszTemp);
//
// Convert item name to wide char:
//
#ifndef UNICODE
MultiByteToWideChar( CP_ACP,
0,
pszName,
strlen(pszName)-4,
wszTemp,
MAX_PATH);
#else
wcscpy(wszTemp, pszName);
#endif
if (FolderType & ~WiaItemTypeFolder)
{
wszTemp[_tcslen(pszName)-4] = 0;
}
bstrItemName = SysAllocString(wszTemp);
if (bstrItemName)
{
bstrFullItemName = SysAllocString(wszFullItemName);
if (bstrFullItemName)
{
//
// Call WIA to create new DrvItem
//
IRCAM_IMAGE_CONTEXT *pContext = 0;
hr = wiasCreateDrvItem( FolderType,
bstrItemName,
bstrFullItemName,
(IWiaMiniDrv *)this,
sizeof(IRCAM_IMAGE_CONTEXT),
(BYTE **)&pContext,
&pNewFolder);
if (hr == S_OK)
{
//
// init device specific context (image path)
//
pContext->pszCameraImagePath = _tcsdup(pszPath);
}
else
{
WIAS_ERROR((g_hInst,"ddevBuildDeviceItemTree, wiasCreateDrvItem failed"));
}
SysFreeString(bstrFullItemName);
}
else
{
WIAS_ERROR((g_hInst,"ddevBuildDeviceItemTree, unable to allocate full item name"));
hr = E_OUTOFMEMORY;
}
SysFreeString(bstrItemName);
}
else
{
WIAS_ERROR((g_hInst,"ddevBuildDeviceItemTree, unable to allocate item name"));
hr = E_OUTOFMEMORY;
}
//
// Assign output value and cleanup
//
if (hr == S_OK)
{
*ppNewFolder = pNewFolder;
}
else
{
//
// delete item
//
}
return hr;
}
//-------------------------------------------------------------------------
// SetItemSize()
//
// Helper function to call wias to calc new item size
//
// Arguments:
//
// pWiasContext - item
//
// Return Value:
//
// Status
//
//-------------------------------------------------------------------------
HRESULT SetItemSize( BYTE* pWiasContext )
{
HRESULT hr;
MINIDRV_TRANSFER_CONTEXT drvTranCtx;
memset( &drvTranCtx, 0, sizeof(MINIDRV_TRANSFER_CONTEXT) );
hr = wiasReadPropGuid( pWiasContext,
WIA_IPA_FORMAT,
(GUID*)&drvTranCtx.guidFormatID,
NULL,
false );
if (FAILED(hr))
{
return hr;
}
hr = wiasReadPropLong( pWiasContext,
WIA_IPA_TYMED,
(LONG*)&drvTranCtx.tymed,
NULL,
false );
if (FAILED(hr))
{
return hr;
}
WIAS_TRACE((g_hInst,"SetItemSize(): tymed: %d",drvTranCtx.tymed));
//
// wias works for DIB and TIFF formats.
//
// Driver doesn't support JPEG
//
hr = wiasGetImageInformation(pWiasContext,
WIAS_INIT_CONTEXT,
&drvTranCtx);
if (hr == S_OK)
{
WIAS_TRACE((g_hInst,"SetItemSize(): lItemSize: %d",drvTranCtx.lItemSize));
hr = wiasWritePropLong(pWiasContext, WIA_IPA_ITEM_SIZE, drvTranCtx.lItemSize);
hr = wiasWritePropLong(pWiasContext, WIA_IPA_BYTES_PER_LINE, drvTranCtx.cbWidthInBytes);
}
return hr;
}
//-------------------------------------------------------------------------
// IrUsdDevice::InitImageInformation()
//
// Init image properties
//
// Arguments:
//
//
// Return Value:
//
// Status
//
//-------------------------------------------------------------------------
HRESULT IrUsdDevice::InitImageInformation( BYTE *pWiasContext,
IRCAM_IMAGE_CONTEXT *pContext,
LONG *plDevErrVal)
{
int i;
HRESULT hr = S_OK;
CAMERA_PICTURE_INFO camInfo;
PROPVARIANT propVar;
WIAS_TRACE((g_hInst,"IrUsdDevice::InitImageInformation()"));
//
// GET image info
//
hr = CamGetPictureInfo( pContext,
&camInfo );
if (hr != S_OK)
{
return hr;
}
//
// Use WIA services to write image properties:
//
wiasWritePropLong( pWiasContext,
WIA_IPC_THUMB_WIDTH,
camInfo.ThumbWidth);
wiasWritePropLong( pWiasContext,
WIA_IPC_THUMB_HEIGHT,
camInfo.ThumbHeight );
wiasWritePropLong( pWiasContext,
WIA_IPA_PIXELS_PER_LINE,
camInfo.PictWidth );
wiasWritePropLong( pWiasContext,
WIA_IPA_NUMBER_OF_LINES,
camInfo.PictHeight );
wiasWritePropGuid( pWiasContext,
WIA_IPA_PREFERRED_FORMAT,
WiaImgFmt_JPEG );
wiasWritePropLong( pWiasContext,
WIA_IPA_DEPTH,
camInfo.PictBitsPerPixel );
wiasWritePropBin( pWiasContext,
WIA_IPA_ITEM_TIME,
sizeof(SYSTEMTIME),
(PBYTE)&camInfo.TimeStamp );
wiasWritePropLong( pWiasContext,
WIA_IPA_DATATYPE,
WIA_DATA_COLOR );
wiasWritePropLong( pWiasContext,
WIA_IPA_ITEM_SIZE,
camInfo.PictCompSize );
wiasWritePropLong( pWiasContext,
WIA_IPA_BYTES_PER_LINE,
camInfo.PictBytesPerRow );
//
// Calculate item size
//
// hr = SetItemSize(pWiasContext); BUGBUG
//
// Load a thumbnail of the image:
//
PBYTE pThumb;
LONG lSize;
hr = CamLoadThumbnail(pContext, &pThumb, &lSize);
if (hr == S_OK)
{
//
// write thumb property
//
PROPSPEC propSpec;
PROPVARIANT propVar;
propVar.vt = VT_VECTOR | VT_UI1;
propVar.caub.cElems = lSize;
propVar.caub.pElems = pThumb;
propSpec.ulKind = PRSPEC_PROPID;
propSpec.propid = WIA_IPC_THUMBNAIL;
hr = wiasWriteMultiple(pWiasContext, 1, &propSpec, &propVar);
FREE(pThumb);
}
//
// Use WIA services to set the extended property access and
// valid value information from gWiaPropInfoDefaults.
//
hr = wiasSetItemPropAttribs(pWiasContext,
NUM_CAM_ITEM_PROPS,
gPropSpecDefaults,
gWiaPropInfoDefaults);
return hr;
}