|
|
//-------------------------------------------------------------------------
//
// 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; }
|