📄 imagefilter.cpp
字号:
if (m_pCurrentStream)
{
pWiaTransferParams->ulTransferredBytes = m_pCurrentStream->m_cBytesWritten;
}
//
// Note the percent reflects the amount of scanning the driver reports
// whereas the "BytesWritten" member is the actual number of bytes
// that we have sent to the application stream.
//
if (m_pCurrentStream && (pWiaTransferParams->lMessage == WIA_TRANSFER_MSG_END_OF_STREAM))
{
if (!m_bTransferCancelled)
{
hr = m_pCurrentStream->Flush();
pWiaTransferParams->ulTransferredBytes = m_pCurrentStream->m_cBytesWritten;
}
m_pCurrentStream -> ReleaseStreams();
}
//
// Call this regardless of hr because applications need termination messages
//
HRESULT hrInner = m_pAppWiaTransferCallback->TransferCallback(lFlags, pWiaTransferParams);
//
// Don't overwrite the original error if there was one
//
if (SUCCEEDED(hr))
{
hr = hrInner;
}
if (m_pCurrentStream && (pWiaTransferParams->lMessage == WIA_TRANSFER_MSG_END_OF_STREAM))
{
m_pCurrentStream->Release();
m_pCurrentStream = NULL;
}
//
// To indicate not to write to the stream later
//
if ( S_OK != hr)
{
m_bTransferCancelled = TRUE;
}
}
return hr;
}
/*****************************************************************************
*
* @func STDMETHODIMP | CImageFilter::GetNextStream | Implementation of GetNextStream
*
* @parm LONG | lFlags |
* Flags
*
* @parm BSTR | bstrItemName |
* Name of item
*
* @parm BSTR | bstrFullItemName |
* Full name of item
*
* @parm IStream | ppDestination |
* Upon successful return this will contain the filtering stream
*
* @comm
* GetNextStream creates a filtering stream. Since the item represented by
* bstrFullItemName may be a child item of the item passed into InitializeFilter
* we have to call FindItemByName to retrieve the actual item.
*
* @rvalue S_OK |
* The function succeeded.
* @rvalue E_XXXXXX |
* Failure
*
*****************************************************************************/
STDMETHODIMP
CImageFilter::GetNextStream(
IN LONG lFlags,
IN BSTR bstrItemName,
IN BSTR bstrFullItemName,
__out OUT IStream **ppDestination)
{
HRESULT hr;
IStream *pAppStream = NULL;
IWiaItem2 *pCurrentWiaItem = NULL;
BOOL bStorageItem = FALSE;
BOOL bRawFormat = FALSE;
LONG lBrightness = 0;
LONG lContrast = 0;
LONG lDeskewX = 0;
LONG lDeskewY = 0;
LONG lRotation = PORTRAIT;
LONG lXExtent = 0;
LONG lYExtent = 0;
LONG lBitDepth = 0;
hr = m_pAppWiaTransferCallback ? S_OK : E_UNEXPECTED;
if (m_pCurrentStream)
{
m_pCurrentStream->Release();
m_pCurrentStream = NULL;
}
if (SUCCEEDED(hr))
{
hr = m_pAppWiaTransferCallback->GetNextStream(lFlags, bstrItemName, bstrFullItemName, &pAppStream);
}
//
// Return immediately following cancellations or skips
//
if ((S_FALSE == hr) || (WIA_STATUS_SKIP_ITEM == hr))
{
return hr;
}
if (SUCCEEDED(hr))
{
hr = m_pWiaItem->FindItemByName(0, bstrFullItemName, &pCurrentWiaItem);
}
//
// Here we read all properties from pCurrentWiaItem that we need in order to
// do the the filtering - in this specific case only brightness.
//
if (SUCCEEDED(hr))
{
CWiaItem *pIWiaItemWrapper = NULL;
pIWiaItemWrapper = new CWiaItem();
hr = pIWiaItemWrapper ? S_OK : E_OUTOFMEMORY;
if (SUCCEEDED(hr))
{
hr = pIWiaItemWrapper->SetIWiaItem(pCurrentWiaItem);
}
if (SUCCEEDED(hr))
{
GUID guidItemCategory = {0};
hr = pIWiaItemWrapper->ReadRequiredPropertyGUID(WIA_IPA_ITEM_CATEGORY,&guidItemCategory);
bStorageItem = ((guidItemCategory == WIA_CATEGORY_FINISHED_FILE) || (WIA_CATEGORY_FOLDER == guidItemCategory));
}
if(SUCCEEDED(hr))
{
GUID guidItemFormat = {0};
hr = pIWiaItemWrapper->ReadRequiredPropertyGUID(WIA_IPA_FORMAT, &guidItemFormat);
if(SUCCEEDED(hr))
{
bRawFormat = (BOOL)(IsEqualGUID(guidItemFormat, WiaImgFmt_RAW));
}
}
if ((!bStorageItem) && (!bRawFormat))
{
if (SUCCEEDED(hr))
{
hr = pIWiaItemWrapper->ReadRequiredPropertyLong(WIA_IPS_BRIGHTNESS,&lBrightness);
}
if (SUCCEEDED(hr))
{
hr = pIWiaItemWrapper->ReadRequiredPropertyLong(WIA_IPS_CONTRAST,&lContrast);
}
if (SUCCEEDED(hr))
{
hr = pIWiaItemWrapper->ReadRequiredPropertyLong(WIA_IPS_ROTATION, &lRotation);
}
if (SUCCEEDED(hr))
{
hr = pIWiaItemWrapper->ReadRequiredPropertyLong(WIA_IPS_DESKEW_X, &lDeskewX);
}
if (SUCCEEDED(hr))
{
hr = pIWiaItemWrapper->ReadRequiredPropertyLong(WIA_IPS_DESKEW_Y, &lDeskewY);
}
if (SUCCEEDED(hr))
{
hr = pIWiaItemWrapper->ReadRequiredPropertyLong(WIA_IPS_XEXTENT, &lXExtent);
}
if (SUCCEEDED(hr))
{
hr = pIWiaItemWrapper->ReadRequiredPropertyLong(WIA_IPS_YEXTENT, &lYExtent);
}
if (SUCCEEDED(hr))
{
hr = pIWiaItemWrapper->ReadRequiredPropertyLong(WIA_IPA_DEPTH, &lBitDepth);
}
}
if (pIWiaItemWrapper)
{
delete pIWiaItemWrapper;
}
}
if (SUCCEEDED(hr))
{
if ((!bStorageItem) && (!bRawFormat))
{
//
// We could easily improve the performace by creating a separate filtering stream
// which simply delegates all calls directly to the application's stream in case
// Rotation, DeskewX, DeskewY, Brightness and Contrast are all set to 0.
//
m_pCurrentStream = new CMyFilterStream();
if (m_pCurrentStream)
{
hr = m_pCurrentStream->Initialize(pAppStream,
lBrightness,
lContrast,
lRotation,
lDeskewX,
lDeskewY,
lXExtent,
lYExtent,
lBitDepth);
}
else
{
hr = E_OUTOFMEMORY;
}
}
else
{
(*ppDestination) = pAppStream;
(*ppDestination)->AddRef();
}
}
if (SUCCEEDED(hr) && m_pCurrentStream)
{
hr = m_pCurrentStream->QueryInterface(IID_IStream, (void**)ppDestination);
}
if (pAppStream)
{
pAppStream->Release();
}
if (pCurrentWiaItem)
{
pCurrentWiaItem->Release();
}
return hr;
}
/*****************************************************************************
*
* Class Object
*
*******************************************************************************/
class CFilterClass : public IClassFactory
{
public:
STDMETHODIMP
QueryInterface(__in const IID& iid_requested, __out void** ppInterfaceOut)
{
HRESULT hr = S_OK;
hr = ppInterfaceOut ? S_OK : E_POINTER;
if (SUCCEEDED(hr))
{
*ppInterfaceOut = NULL;
}
//
// We support IID_IUnknown and IID_IClassFactory
//
if (SUCCEEDED(hr))
{
if (IID_IUnknown == iid_requested)
{
*ppInterfaceOut = static_cast<IUnknown*>(this);
}
else if (IID_IClassFactory == iid_requested)
{
*ppInterfaceOut = static_cast<IClassFactory*>(this);
}
else
{
hr = E_NOINTERFACE;
}
}
if (SUCCEEDED(hr))
{
reinterpret_cast<IUnknown*>(*ppInterfaceOut)->AddRef();
}
return hr;
}
STDMETHODIMP_(ULONG)
AddRef(void)
{
LockModule();
return 2;
}
STDMETHODIMP_(ULONG)
Release(void)
{
UnlockModule();
return 1;
}
STDMETHODIMP
CreateInstance(__in IUnknown *pUnkOuter,
__in REFIID riid,
__out void **ppv)
{
CImageFilter *pImageFilter = NULL;
HRESULT hr;
hr = ppv ? S_OK : E_POINTER;
if (SUCCEEDED(hr))
{
*ppv = 0;
}
if (SUCCEEDED(hr))
{
if (pUnkOuter)
{
hr = CLASS_E_NOAGGREGATION;
}
}
if (SUCCEEDED(hr))
{
pImageFilter = new CImageFilter();
hr = pImageFilter ? S_OK : E_OUTOFMEMORY;
}
if (SUCCEEDED(hr))
{
pImageFilter->AddRef();
hr = pImageFilter->QueryInterface(riid, ppv);
pImageFilter->Release();
}
return hr;
}
STDMETHODIMP
LockServer(BOOL bLock)
{
if (bLock)
{
LockModule();
}
else
{
UnlockModule();
}
return S_OK;
}
};
STDAPI DllCanUnloadNow(void)
{
return (g_cLocks == 0) ? S_OK : S_FALSE;
}
STDAPI DllGetClassObject(__in REFCLSID rclsid,
__in REFIID riid,
__out void **ppv)
{
static CFilterClass s_FilterClass;
if (rclsid == CLSID_WiaImageFilter)
{
return s_FilterClass.QueryInterface(riid, ppv);
}
*ppv = 0;
return CLASS_E_CLASSNOTAVAILABLE;
}
//
// Registered in driver INF file - what about un-regestering?
//
STDAPI DllUnregisterServer()
{
return S_OK;
}
STDAPI DllRegisterServer()
{
return S_OK;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -