|
|
/*++
Copyright (C) 2000 Microsoft Corporation
Module Name:
gdipconv.cpp
Abstract:
Helper functions for using GDI+ to convert image formats
Author:
DavePar
Revision History:
--*/
#include "pch.h"
/**************************************************************************\
* wiauGetDrvItemContext \**************************************************************************/
HRESULT wiauGetDrvItemContext(BYTE *pWiasContext, VOID **ppItemCtx, IWiaDrvItem **ppDrvItem) { HRESULT hr = S_OK;
//
// Locals
//
IWiaDrvItem *pWiaDrvItem = NULL;
REQUIRE_ARGS(!pWiasContext || !ppItemCtx, hr, "wiauGetDrvItemContext"); *ppItemCtx = NULL; if (ppDrvItem) *ppDrvItem = NULL;
hr = wiasGetDrvItem(pWiasContext, &pWiaDrvItem); REQUIRE_SUCCESS(hr, "wiauGetDrvItemContext", "wiasGetDrvItem failed");
hr = pWiaDrvItem->GetDeviceSpecContext((BYTE **) ppItemCtx); REQUIRE_SUCCESS(hr, "wiauGetDrvItemContext", "GetDeviceSpecContext failed"); if (!*ppItemCtx) { wiauDbgError("wiauGetDrvItemContext", "Item context is null"); hr = E_FAIL; goto Cleanup; }
if (ppDrvItem) { *ppDrvItem = pWiaDrvItem; }
Cleanup: return hr; }
/**************************************************************************\
* wiauSetImageItemSize \**************************************************************************/
HRESULT wiauSetImageItemSize(BYTE *pWiasContext, LONG lWidth, LONG lHeight, LONG lDepth, LONG lSize, PWSTR pwszExt) { HRESULT hr = S_OK;
LONG lNewSize = 0; LONG lWidthInBytes = 0; GUID guidFormatID = GUID_NULL; BSTR bstrExt = NULL;
LONG lNumProperties = 2; PROPVARIANT pv[3]; PROPSPEC ps[3] = {{PRSPEC_PROPID, WIA_IPA_ITEM_SIZE}, {PRSPEC_PROPID, WIA_IPA_BYTES_PER_LINE}, {PRSPEC_PROPID, WIA_IPA_FILENAME_EXTENSION}};
//
// Read the current format GUID
//
hr = wiasReadPropGuid(pWiasContext, WIA_IPA_FORMAT, &guidFormatID, NULL, TRUE); REQUIRE_SUCCESS(hr, "wiauSetImageItemSize", "wiasReadPropGuid failed");
if (IsEqualCLSID(guidFormatID, WiaImgFmt_BMP) || IsEqualCLSID(guidFormatID, WiaImgFmt_MEMORYBMP)) { lNewSize = sizeof(BITMAPINFOHEADER);
//
// if this is a file, add file header to size
//
if (IsEqualCLSID(guidFormatID, WiaImgFmt_BMP)) { lNewSize += sizeof(BITMAPFILEHEADER); }
//
// Calculate number of bytes per line, width must be
// aligned to 4 byte boundary.
//
lWidthInBytes = ((lWidth * lDepth + 31) & ~31) / 8;
//
// Calculate image size
//
lNewSize += lWidthInBytes * lHeight;
//
// Set the extension property
//
if (pwszExt) { bstrExt = SysAllocString(L"BMP"); REQUIRE_ALLOC(bstrExt, hr, "wiauSetImageItemSize"); } } else { lNewSize = lSize; lWidthInBytes = 0; //
// Set the extension property
//
if (pwszExt) { bstrExt = SysAllocString(pwszExt); REQUIRE_ALLOC(bstrExt, hr, "wiauSetImageItemSize"); } }
//
// Initialize propvar's. Then write the values. Don't need to call
// PropVariantClear when done, since no memory was allocated.
//
if (bstrExt) lNumProperties++;
for (int i = 0; i < lNumProperties; i++) { PropVariantInit(&pv[i]); }
pv[0].vt = VT_I4; pv[0].lVal = lNewSize; pv[1].vt = VT_I4; pv[1].lVal = lWidthInBytes; pv[2].vt = VT_BSTR; pv[2].bstrVal = bstrExt;
//
// Write WIA_IPA_ITEM_SIZE and WIA_IPA_BYTES_PER_LINE property values
//
hr = wiasWriteMultiple(pWiasContext, lNumProperties, ps, pv); REQUIRE_SUCCESS(hr, "wiauSetImageItemSize", "wiasWriteMultiple failed");
Cleanup: if (bstrExt) SysFreeString(bstrExt);
return hr; }
/**************************************************************************\
* wiauPropsInPropSpec \**************************************************************************/
BOOL wiauPropsInPropSpec(LONG NumPropSpecs, const PROPSPEC *pPropSpecs, int NumProps, PROPID *pProps) { for (int count = 0; count < NumProps; count++) if (wiauPropInPropSpec(NumPropSpecs, pPropSpecs, pProps[count])) return TRUE;
return FALSE; }
/**************************************************************************\
* wiauPropInPropSpec \**************************************************************************/
BOOL wiauPropInPropSpec(LONG NumPropSpecs, const PROPSPEC *pPropSpecs, PROPID PropId, int *pIdx) { for (int count = 0; count < NumPropSpecs; count++) if (pPropSpecs[count].propid == PropId) { if (pIdx) *pIdx = count; return TRUE; }
return FALSE; }
/**************************************************************************\
* wiauGetValidFormats \**************************************************************************/
HRESULT wiauGetValidFormats(IWiaMiniDrv *pDrv, BYTE *pWiasContext, LONG TymedValue, int *pNumFormats, GUID **ppFormatArray) { HRESULT hr = S_OK;
LONG NumFi = 0; WIA_FORMAT_INFO *pFiArray = NULL; LONG lErrVal = 0; GUID *pFA = NULL;
REQUIRE_ARGS(!ppFormatArray || !pNumFormats, hr, "wiauGetValidFormats");
*ppFormatArray = NULL; *pNumFormats = 0;
hr = pDrv->drvGetWiaFormatInfo(pWiasContext, 0, &NumFi, &pFiArray, &lErrVal); REQUIRE_SUCCESS(hr, "wiauGetValidFormats", "drvGetWiaFormatInfo failed");
//
// This will allocate more spots than necessary, but pNumFormats will be set correctly
//
pFA = new GUID[NumFi]; REQUIRE_ALLOC(pFA, hr, "wiauGetValidFormats");
for (int count = 0; count < NumFi; count++) { if (pFiArray[count].lTymed == TymedValue) { pFA[*pNumFormats] = pFiArray[count].guidFormatID; (*pNumFormats)++; } }
*ppFormatArray = pFA;
Cleanup: return hr; }
/**************************************************************************\
* wiauGetResourceString \**************************************************************************/ HRESULT wiauGetResourceString(HINSTANCE hInst, LONG lResourceID, BSTR *pbstrStr) { DBG_FN("GetResourceString"); HRESULT hr = S_OK;
//
// Locals
//
INT iLen = 0; TCHAR tszTempStr[MAX_PATH] = TEXT(""); WCHAR wszTempStr[MAX_PATH] = L"";
REQUIRE_ARGS(!pbstrStr, hr, "GetResourceString"); *pbstrStr = NULL;
//
// Get the string from the resource
//
iLen = LoadString(hInst, lResourceID, tszTempStr, MAX_PATH); REQUIRE_FILEIO(iLen, hr, "GetResourceString", "LoadString failed");
hr = wiauStrT2W(tszTempStr, wszTempStr, sizeof(wszTempStr)); REQUIRE_SUCCESS(hr, "GetResourceString", "wiauStrT2W failed");
//
// Caller must free this allocated BSTR
//
*pbstrStr = SysAllocString(wszTempStr); REQUIRE_ALLOC(*pbstrStr, hr, "GetResourceString");
Cleanup: return hr; }
/**************************************************************************\
* wiauRegOpenDataW \**************************************************************************/ HRESULT wiauRegOpenDataW(HKEY hkeyAncestor, HKEY *phkeyDeviceData) { DBG_FN("wiauRegOpenDataW");
HRESULT hr = S_OK; //
// Locals
//
LONG lReturn = 0;
REQUIRE_ARGS(!hkeyAncestor || !phkeyDeviceData, hr, "wiauRegOpenDataW");
lReturn = ::RegOpenKeyExW(hkeyAncestor, L"DeviceData", 0, KEY_READ, phkeyDeviceData); REQUIRE_WIN32(lReturn, hr, "wiauRegOpenDataW", "RegOpenKeyExW failed");
Cleanup: return hr; }
/**************************************************************************\
* wiauRegOpenDataA \**************************************************************************/ HRESULT wiauRegOpenDataA(HKEY hkeyAncestor, HKEY *phkeyDeviceData) { DBG_FN("wiauRegOpenDataA");
HRESULT hr = S_OK; //
// Locals
//
LONG lReturn = 0;
REQUIRE_ARGS(!hkeyAncestor || !phkeyDeviceData, hr, "wiauRegOpenDataA");
lReturn = ::RegOpenKeyExA(hkeyAncestor, "DeviceData", 0, KEY_READ, phkeyDeviceData); REQUIRE_WIN32(lReturn, hr, "wiauRegOpenDataA", "RegOpenKeyExA failed");
Cleanup: return hr; }
/**************************************************************************\
* wiauRegGetStrW \**************************************************************************/ HRESULT wiauRegGetStrW(HKEY hkKey, PCWSTR pwszValueName, PWSTR pwszValue, DWORD *pdwLength) { DBG_FN("wiauRegGetStrW");
HRESULT hr = S_OK; //
// Locals
//
LONG lReturn = 0; DWORD dwType = 0;
REQUIRE_ARGS(!hkKey || !pwszValueName || !pwszValue || !pdwLength, hr, "wiauRegGetStrW");
lReturn = ::RegQueryValueExW(hkKey, pwszValueName, NULL, &dwType, (BYTE *) pwszValue, pdwLength); REQUIRE_WIN32(lReturn, hr, "wiauRegGetStrW", "RegQueryValueExW failed");
if ((dwType != REG_SZ) && (dwType != REG_EXPAND_SZ) && (dwType != REG_MULTI_SZ)) {
wiauDbgError("wiauRegGetStrW", "ReqQueryValueEx returned wrong type for key, %d", dwType); hr = E_FAIL; goto Cleanup; }
Cleanup: return hr; }
/**************************************************************************\
* wiauRegGetStrA \**************************************************************************/ HRESULT wiauRegGetStrA(HKEY hkKey, PCSTR pszValueName, PSTR pszValue, DWORD *pdwLength) { DBG_FN("wiauRegGetStrA");
HRESULT hr = S_OK; //
// Locals
//
LONG lReturn = 0; DWORD dwType = 0;
REQUIRE_ARGS(!hkKey || !pszValueName || !pszValue || !pdwLength, hr, "wiauRegGetStrA");
lReturn = ::RegQueryValueExA(hkKey, pszValueName, NULL, &dwType, (BYTE *) pszValue, pdwLength); REQUIRE_WIN32(lReturn, hr, "wiauRegGetStrA", "RegQueryValueExA failed");
if ((dwType != REG_SZ) && (dwType != REG_EXPAND_SZ) && (dwType != REG_MULTI_SZ)) {
wiauDbgError("wiauRegGetStrA", "ReqQueryValueEx returned wrong type for key, %d", dwType); hr = E_FAIL; goto Cleanup; }
Cleanup: return hr; }
/**************************************************************************\
* wiauRegGetDwordW \**************************************************************************/ HRESULT wiauRegGetDwordW(HKEY hkKey, PCTSTR pwszValueName, DWORD *pdwValue) { DBG_FN("wiauRegGetDwordW");
HRESULT hr = S_OK; //
// Locals
//
LONG lReturn = 0; DWORD dwType = 0; DWORD dwLength = sizeof(*pdwValue);
REQUIRE_ARGS(!hkKey || !pwszValueName || !pdwValue, hr, "wiauRegGetDwordW");
lReturn = ::RegQueryValueExW(hkKey, pwszValueName, NULL, &dwType, (BYTE *) pdwValue, &dwLength); REQUIRE_WIN32(lReturn, hr, "wiauRegGetDwordW", "RegQueryValueExW failed");
if (dwType != REG_DWORD) {
wiauDbgError("wiauRegGetDwordW", "ReqQueryValueEx returned wrong type for key, %d", dwType); hr = E_FAIL; goto Cleanup; }
Cleanup: return hr; }
/**************************************************************************\
* wiauRegGetDwordA \**************************************************************************/ HRESULT wiauRegGetDwordA(HKEY hkKey, PCSTR pszValueName, DWORD *pdwValue) { DBG_FN("wiauRegGetDwordA");
HRESULT hr = S_OK; //
// Locals
//
LONG lReturn = 0; DWORD dwType = 0; DWORD dwLength = sizeof(*pdwValue);
REQUIRE_ARGS(!hkKey || !pszValueName || !pdwValue, hr, "wiauRegGetDword");
lReturn = ::RegQueryValueExA(hkKey, pszValueName, NULL, &dwType, (BYTE *) pdwValue, &dwLength); REQUIRE_WIN32(lReturn, hr, "wiauRegGetDwordA", "RegQueryValueExA failed");
if (dwType != REG_DWORD) {
wiauDbgError("wiauRegGetDwordA", "ReqQueryValueExA returned wrong type for key, %d", dwType); hr = E_FAIL; goto Cleanup; }
Cleanup: return hr; }
/**************************************************************************\
* wiauStrW2C \**************************************************************************/
HRESULT wiauStrW2C(WCHAR *pwszSrc, CHAR *pszDst, INT iSize) { HRESULT hr = S_OK; INT iWritten = 0;
REQUIRE_ARGS(!pwszSrc || !pszDst || iSize < 1, hr, "wiauStrW2C");
iWritten = WideCharToMultiByte(CP_ACP, 0, pwszSrc, -1, pszDst, iSize, NULL, NULL); REQUIRE_FILEIO(iWritten != 0, hr, "wiauStrW2C", "WideCharToMultiByte failed");
Cleanup: return hr; }
/**************************************************************************\
* wiauStrC2W \**************************************************************************/
HRESULT wiauStrC2W(CHAR *pszSrc, WCHAR *pwszDst, INT iSize) { HRESULT hr = S_OK; INT iWritten = 0;
REQUIRE_ARGS(!pszSrc || !pwszDst || iSize < 1, hr, "wiauStrC2W");
iWritten = MultiByteToWideChar(CP_ACP, 0, pszSrc, -1, pwszDst, iSize / sizeof(*pwszDst)); REQUIRE_FILEIO(iWritten != 0, hr, "wiauStrC2W", "MultiByteToWideChar failed");
Cleanup: return hr; }
/**************************************************************************\
* wiauStrW2W \**************************************************************************/
HRESULT wiauStrW2W(WCHAR *pwszSrc, WCHAR *pwszDst, INT iSize) { HRESULT hr = S_OK;
REQUIRE_ARGS(!pwszSrc || !pwszDst || iSize < 1, hr, "wiauStrW2W");
if ((lstrlenW(pwszSrc) + 1) > (iSize / (INT) sizeof(*pwszDst))) { hr = ERROR_INSUFFICIENT_BUFFER; goto Cleanup; }
lstrcpyW(pwszDst, pwszSrc);
Cleanup: return hr; }
/**************************************************************************\
* wiauStrC2C \**************************************************************************/
HRESULT wiauStrC2C(CHAR *pszSrc, CHAR *pszDst, INT iSize) { HRESULT hr = S_OK;
REQUIRE_ARGS(!pszSrc || !pszDst || iSize < 1, hr, "wiauStrC2C");
if ((lstrlenA(pszSrc) + 1) > iSize) { hr = ERROR_INSUFFICIENT_BUFFER; goto Cleanup; }
lstrcpyA(pszDst, pszSrc);
Cleanup: return hr; }
|