//------------------------------------------------------------------------- // // 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 #include #include #include #include "sti.h" #include "ircamera.h" #include 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; }