📄 imagefilter.cpp
字号:
if (SUCCEEDED(hr))
{
hr = m_pCachingStream->Seek(ullPos, STREAM_SEEK_SET, NULL);
}
}
}
if (SUCCEEDED(hr))
{
m_lBrightness = lBrightness;
m_lContrast = lContrast;
m_lRotation = lRotation;
m_lDeskewX = lDeskewX;
m_lDeskewY = lDeskewY;
}
return hr;
}
/*****************************************************************************
*
* @func STDMETHODIMP | CMyFilterStream::Flush | Reads unfiltered data, performs filtering and writes
* data to application stream
*
* @comm
*
* Flush is called when the image processing filter receives a WIA_TRANSFER_MSG_END_OF_STREAM message.
* Flush calls DoFiltering where the actual filtering is done.
*
* Note that this simple implementation performs all its filtering only after it has received all
* unfiltered image data and stored it in m_pCachingStream. A "real" implementation should be able
* to work on bands of data (at least if no deskew and rotation has to be performed).
*
* @rvalue S_OK |
* The function succeeded.
* @rvalue E_XXX |
* The function failed
*
*****************************************************************************/
HRESULT
CMyFilterStream::Flush(
VOID)
{
HRESULT hr;
hr = DoFiltering(
m_lBrightness,
m_lContrast,
m_lRotation,
m_lDeskewX,
m_lDeskewY,
m_pCachingStream,
m_pAppStream,
&m_cBytesWritten);
//
// Note: m_pAppStream and m_pCachingStream are released by ReleaseStreams which must be always called after Flush
//
return hr;
}
///
/// Query Interface
///
STDMETHODIMP
CMyFilterStream::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_IStream
//
if (SUCCEEDED(hr))
{
if (IID_IUnknown == iid_requested)
{
*ppInterfaceOut = static_cast<IUnknown*>(this);
}
else if (IID_IStream == iid_requested)
{
*ppInterfaceOut = static_cast<IStream*>(this);
}
else
{
hr = E_NOINTERFACE;
}
}
if (SUCCEEDED(hr))
{
reinterpret_cast<IUnknown*>(*ppInterfaceOut)->AddRef();
}
return hr;
}
///
/// AddRef
///
STDMETHODIMP_(ULONG)
CMyFilterStream::AddRef(void)
{
if (m_nRefCount == 0)
{
LockModule();
}
return InterlockedIncrement(&m_nRefCount);
}
///
/// Release
///
STDMETHODIMP_(ULONG)
CMyFilterStream::Release(void)
{
ULONG nRetval = InterlockedDecrement(&m_nRefCount);
if (0 == nRetval)
{
delete this;
UnlockModule();
}
return nRetval;
}
STDMETHODIMP
CMyFilterStream::Seek(LARGE_INTEGER dlibMove, DWORD dwOrigin, __out ULARGE_INTEGER *plibNewPosition)
{
return m_pCachingStream->Seek(dlibMove,dwOrigin,plibNewPosition);
}
STDMETHODIMP
CMyFilterStream::SetSize(ULARGE_INTEGER libNewSize)
{
return m_pCachingStream->SetSize(libNewSize);
}
STDMETHODIMP
CMyFilterStream::LockRegion(ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType)
{
return m_pCachingStream->LockRegion(libOffset,cb,dwLockType);
}
STDMETHODIMP
CMyFilterStream::CopyTo(__in IStream *pstm, ULARGE_INTEGER cb, __out ULARGE_INTEGER *pcbRead, __out ULARGE_INTEGER *pcbWritten)
{
return m_pCachingStream->CopyTo(pstm,cb,pcbRead,pcbWritten);
}
STDMETHODIMP
CMyFilterStream::Commit(DWORD grfCommitFlags)
{
return m_pCachingStream->Commit(grfCommitFlags);
}
STDMETHODIMP
CMyFilterStream::Revert(void)
{
return m_pCachingStream->Revert();
}
STDMETHODIMP
CMyFilterStream::UnlockRegion(ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType)
{
return m_pCachingStream->UnlockRegion(libOffset,cb,dwLockType);
}
STDMETHODIMP
CMyFilterStream::Stat(__out STATSTG *pstatstg, DWORD grfStatFlag)
{
return m_pCachingStream->Stat(pstatstg, grfStatFlag);
}
STDMETHODIMP
CMyFilterStream::Clone(__out IStream **ppstm)
{
return m_pCachingStream->Clone(ppstm);
}
STDMETHODIMP
CMyFilterStream::Read(__out void *pv, ULONG cb, __out ULONG *pcbRead)
{
return m_pCachingStream->Read(pv,cb,pcbRead);
}
STDMETHODIMP
CMyFilterStream::ReleaseStreams()
{
if (m_pAppStream)
{
m_pAppStream->Release();
m_pAppStream = NULL;
}
if (m_pCachingStream)
{
m_pCachingStream->Release();
m_pCachingStream = NULL;
}
return S_OK;
}
/*****************************************************************************
*
* @func STDMETHODIMP | CMyFilterStream::Write | Filtering streams implementation of Write
*
* @parm const void * | pv |
* Pointer to the memory buffer.
*
* @parm ULONG | cb |
* Specifies the number of bytes of data to write from the stream object.
*
* @parm ULONG | pcbWritten |
* Pointer to a ULONG variable that receives the actual number of bytes written from the stream object.
*
* @comm
* Write simply writes unfiltered data from the driver into its internal caching stream.
*
* @rvalue S_OK |
* The function succeeded.
* @rvalue E_XXX |
* The function failed
*
*****************************************************************************/
STDMETHODIMP
CMyFilterStream::Write(__in const void *pv, ULONG cb, __out ULONG *pcbWritten)
{
return m_pCachingStream->Write(pv, cb, pcbWritten);
}
///
/// Constructor
///
CImageFilter::CImageFilter(
VOID) : m_pWiaItem(NULL), m_pAppWiaTransferCallback(NULL), m_nRefCount(0), m_pCurrentStream(NULL)
{
//
// Nothing
//
}
///
/// Destructor
///
CImageFilter::~CImageFilter(
VOID)
{
if (m_pWiaItem)
{
m_pWiaItem->Release();
m_pWiaItem = NULL;
}
if (m_pAppWiaTransferCallback)
{
m_pAppWiaTransferCallback->Release();
m_pAppWiaTransferCallback = NULL;
}
}
///
/// QueryInterface
///
STDMETHODIMP
CImageFilter::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, IID_IWiaImageFilter and IID_IWiaTransferCallback
//
if (SUCCEEDED(hr))
{
if (IID_IUnknown == iid_requested)
{
*ppInterfaceOut = static_cast<IWiaImageFilter*>(this);
}
else if (IID_IWiaImageFilter == iid_requested)
{
*ppInterfaceOut = static_cast<IWiaImageFilter*>(this);
}
else if (IID_IWiaTransferCallback == iid_requested)
{
*ppInterfaceOut = static_cast<IWiaTransferCallback*>(this);
}
else
{
hr = E_NOINTERFACE;
}
}
if (SUCCEEDED(hr))
{
reinterpret_cast<IUnknown*>(*ppInterfaceOut)->AddRef();
}
return hr;
}
///
/// AddRef
///
STDMETHODIMP_(ULONG)
CImageFilter::AddRef(void)
{
if (m_nRefCount == 0)
{
LockModule();
}
return InterlockedIncrement(&m_nRefCount);
}
///
/// Release
///
STDMETHODIMP_(ULONG)
CImageFilter::Release(void)
{
ULONG nRetval = InterlockedDecrement(&m_nRefCount);
if (0 == nRetval)
{
delete this;
UnlockModule();
}
return nRetval;
}
/*****************************************************************************
*
* @func STDMETHODIMP | CImageFilter::InitializeFilter | Initializes image processing filter
*
* @parm IWiaItem2 | pWiaItem |
* The WIA item we are doing the download for. This will actually be the parent item
* for some of the item we acquire the image for. See implementation of GetNextStream
* for more details.
*
* @parm IWiaTransferCallback | pWiaTransferCallback |
* Application's callback function
*
* @comm
* Initializes image processing filter. Stores references to applications callback interface
* and IWiaItem2
*
* @rvalue S_OK |
* The function succeeded.
* @rvalue E_XXX |
* The function failed
*
*****************************************************************************/
STDMETHODIMP
CImageFilter::InitializeFilter(
__in IN IWiaItem2 *pWiaItem,
__callback IN IWiaTransferCallback *pWiaTransferCallback)
{
HRESULT hr = S_OK;
m_bTransferCancelled = FALSE;
hr = (pWiaItem && pWiaTransferCallback) ? S_OK : E_INVALIDARG;
//
// Image processing filters supplied with WIA drivers do not
// support storage items.
//
if (SUCCEEDED(hr))
{
GUID guidItemCategory = {0};
hr = pWiaItem->GetItemCategory(&guidItemCategory);
if (SUCCEEDED(hr))
{
if ((WIA_CATEGORY_FINISHED_FILE == guidItemCategory) ||
(WIA_CATEGORY_FOLDER == guidItemCategory))
{
hr = E_NOTIMPL;
}
}
}
//
// InitializeFilter should only be called once ... but we still Release
// any resources we might reference
//
if (SUCCEEDED(hr))
{
if (m_pWiaItem)
{
m_pWiaItem->Release();
m_pWiaItem = NULL;
}
if (m_pAppWiaTransferCallback)
{
m_pAppWiaTransferCallback->Release();
m_pAppWiaTransferCallback = NULL;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -