⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 imagefilter.cpp

📁 winddk src目录下的WDM源码压缩!
💻 CPP
📖 第 1 页 / 共 4 页
字号:
    if (SUCCEEDED(hr))
    {
        m_pWiaItem = pWiaItem;
        m_pWiaItem->AddRef();

        m_pAppWiaTransferCallback = pWiaTransferCallback;
        m_pAppWiaTransferCallback->AddRef();
    }

    return hr;
}

/*****************************************************************************
 *  
 *  @func STDMETHODIMP | CImageFilter::SetNewCallback | Sets new callback for image processing filter to use
 *  
 *  @parm   IWiaTransferCallback | pWiaTransferCallback |
 *          The new application callback which the filter should use. 
 * 
 *  @comm
 *  Since an application can change the callback to use in the IWiaPreview::UpdatePreview call the image
 *  processing filter must "get notified" of this.
 *  Note, the image processing filter is always required to release its current callback even if it is
 *  passed NULL for the callback.
 *
 *  @rvalue S_OK    | 
 *              The function succeeded.
 *  @rvalue E_XXX   | 
 *              The function failed 
 * 
 *****************************************************************************/
STDMETHODIMP
CImageFilter::SetNewCallback(
   __in_opt __callback  IN   IWiaTransferCallback    *pWiaTransferCallback)
{
    if (m_pAppWiaTransferCallback)
    {
        m_pAppWiaTransferCallback->Release();
        m_pAppWiaTransferCallback = NULL;
    }

    if (pWiaTransferCallback)
    {
        m_pAppWiaTransferCallback = pWiaTransferCallback;
        m_pAppWiaTransferCallback->AddRef();
    }

    return S_OK;
}



/*****************************************************************************
 *  
 *  @func STDMETHODIMP | CImageFilter::FilterPreviewImage | FilterPreviewImage implementation
 * 
  
 *  @parm   IWiaItem2 | pWiaChildItem |
 *          pWiaChildItem2 is the item which the image process is to process.
 *          This item must be a child item of the item, m_pWiaItem, that was passed into InitializeFilter.
 * 
 *  @parm   RECT | InputImageExtents | 
 *          The coordinates (on the flatbed scanner) of the image that the preview component caches internally,
 *          which is also the image that is passed into the pInputStream parameter.
 *          We need this parameter since it is possible that the cached image (pInputStream) was not captured
 *          with XPOS=YPOS=0.
 * 
 *  @parm   IStream | pInputStream | 
 *          Unfiltered image that is stored by WIA Preview Component.
 *
 *  @comm
 *  FilterPreviewImage is called by the preview component, when an application calls UpdatePreview.
 *  We simply read all the properties from pWiaChildItem that are required for us to do the filtering
 *  and then retrieve the application stream. The actual filtering is then performed in DoFiltering.
 *
 *  @rvalue S_OK    | 
 *              The function succeeded.
 *  @rvalue E_XXX   | 
 *              The function failed 
 * 
 *****************************************************************************/
STDMETHODIMP
CImageFilter::FilterPreviewImage(
            IN     LONG                    lFlags,
    __in    IN     IWiaItem2               *pWiaChildItem,
            IN     RECT                    InputImageExtents,
    __in    IN     IStream                 *pInputStream)
{
    IStream     *pAppStream = NULL;
    BSTR        bstrItemName        = NULL;
    BSTR        bstrFullItemName    = NULL;
    GUID        guidItemCategory    = {0};
    LONG        xpos = 0, ypos = 0, width = 0, height = 0;
    LONG        lBrightness = 0;
    LONG        lContrast = 0;
    LONG        lDeskewX = 0;
    LONG        lDeskewY = 0;
    LONG        lRotation = PORTRAIT;
    
    HRESULT     hr;

    //
    // Parameter validation
    //

    hr = (pWiaChildItem && pInputStream) ? S_OK : E_INVALIDARG;

    if (SUCCEEDED(hr))
    {
        // 
        // Check whether the image extents are correct.
        // Error if the right or bottom coordinate is zero.
        // Or Left >= Right or Top >= Bottom.
        //
        
        if ((0 == InputImageExtents.right) ||
            (0 == InputImageExtents.bottom) ||
            (InputImageExtents.left >= InputImageExtents.right) ||
            (InputImageExtents.top >= InputImageExtents.bottom))
        {
            hr = E_INVALIDARG;
        }
    }
    
    if (SUCCEEDED(hr))
    {
        hr = m_pAppWiaTransferCallback ? S_OK : E_UNEXPECTED;
    }

    //
    // Read all properties we need
    //
    if (SUCCEEDED(hr))
    {
        CWiaItem    *pWiaItemWrapper = new CWiaItem();

        hr = pWiaItemWrapper ? S_OK : E_OUTOFMEMORY;

        if (SUCCEEDED(hr))
        {
            hr = pWiaItemWrapper->SetIWiaItem(pWiaChildItem);
        }

        if (SUCCEEDED(hr))
        {
            hr = pWiaItemWrapper->ReadRequiredPropertyGUID(WIA_IPA_ITEM_CATEGORY, &guidItemCategory);

            if (SUCCEEDED(hr) && ((guidItemCategory == WIA_CATEGORY_FINISHED_FILE) || (WIA_CATEGORY_FOLDER == guidItemCategory)))
            {
                //
                // We should never get here for storage items!
                //
                hr = E_INVALIDARG;
            }
        }

        //
        // Error if the following is not satisfied: 
        //     WIA_IPS_MIN_HORIZONTAL_SIZE <= right - left <= WIA_IPS_MAX_HORIZONTAL_SIZE
        //     WIA_IPS_MIN_VERTICAL_SIZE   <= bottom - top <= WIA_IPS_MAX_VERTICAL_SIZE
        //

        if (SUCCEEDED(hr))
        {
            LONG lHorMin = 0, lHorMax = 0, lHorExtent = InputImageExtents.right - InputImageExtents.left;
            LONG lVerMin = 0, lVerMax = 0, lVerExtent = InputImageExtents.bottom - InputImageExtents.top;

            if (SUCCEEDED(hr))
            {
                hr = pWiaItemWrapper->ReadRequiredPropertyLong(WIA_IPS_MIN_HORIZONTAL_SIZE, &lHorMin);
            }
            if (SUCCEEDED(hr))
            {
                hr = pWiaItemWrapper->ReadRequiredPropertyLong(WIA_IPS_MAX_HORIZONTAL_SIZE, &lHorMax);
            }
            if (SUCCEEDED(hr))
            {
                hr = pWiaItemWrapper->ReadRequiredPropertyLong(WIA_IPS_MIN_VERTICAL_SIZE, &lVerMin);
            }
            if (SUCCEEDED(hr))
            {
                hr = pWiaItemWrapper->ReadRequiredPropertyLong(WIA_IPS_MAX_VERTICAL_SIZE, &lVerMax);
                
            }
            if (SUCCEEDED(hr))
            {
                if ((lHorExtent < lHorMin) || (lHorExtent > lHorMax) ||
                    (lVerExtent < lVerMin) || (lVerExtent > lVerMax))
                {
                    hr = E_INVALIDARG;
                }
            }
        }
        
        if(SUCCEEDED(hr))
        {
            GUID guidItemFormat = {0};

            hr = pWiaItemWrapper->ReadRequiredPropertyGUID(WIA_IPA_FORMAT, &guidItemFormat);
            if((SUCCEEDED(hr)) && (IsEqualGUID(guidItemFormat, WiaImgFmt_RAW)))
            {
                //
                // Raw data must be passed "as is" to the application, do not attempt to modify in any way:
                //
                hr = E_INVALIDARG;
            }
        }

        if (SUCCEEDED(hr))
        {
            hr = pWiaItemWrapper->ReadRequiredPropertyLong(WIA_IPS_XPOS, &xpos);
        }

        if (SUCCEEDED(hr))
        {
            hr = pWiaItemWrapper->ReadRequiredPropertyLong(WIA_IPS_YPOS, &ypos);
        }

        if (SUCCEEDED(hr))
        {
            hr = pWiaItemWrapper->ReadRequiredPropertyLong(WIA_IPS_XEXTENT, &width);
        }

        if (SUCCEEDED(hr))
        {
            hr = pWiaItemWrapper->ReadRequiredPropertyLong(WIA_IPS_YEXTENT, &height);
        }

        if (SUCCEEDED(hr))
        {
            hr = pWiaItemWrapper->ReadRequiredPropertyBSTR(WIA_IPA_ITEM_NAME, &bstrItemName);
        }

        if (SUCCEEDED(hr))
        {
            hr = pWiaItemWrapper->ReadRequiredPropertyBSTR(WIA_IPA_FULL_ITEM_NAME, &bstrFullItemName);
        }

        if (SUCCEEDED(hr))
        {
            hr = pWiaItemWrapper->ReadRequiredPropertyLong(WIA_IPS_BRIGHTNESS, &lBrightness);
        }

        if (SUCCEEDED(hr))
        {
            hr = pWiaItemWrapper->ReadRequiredPropertyLong(WIA_IPS_CONTRAST, &lContrast);
        }

        if (SUCCEEDED(hr))
        {
            hr = pWiaItemWrapper->ReadRequiredPropertyLong(WIA_IPS_ROTATION, &lRotation);
        }

        if (SUCCEEDED(hr))
        {
            hr = pWiaItemWrapper->ReadRequiredPropertyLong(WIA_IPS_DESKEW_X, &lDeskewX);
        }

        if (SUCCEEDED(hr))
        {
            hr = pWiaItemWrapper->ReadRequiredPropertyLong(WIA_IPS_DESKEW_Y, &lDeskewY);
        }

        if (pWiaItemWrapper)
        {
            delete pWiaItemWrapper;
        }
    }

    //
    // If the upper left corner of the passed image does not correspond to (0,0)
    // on the flatbed we have to adjust xpos and ypos accordingly in order for us
    // to "cut out" the correct region represented by pWiaChildItem
    //
    if (SUCCEEDED(hr))
    {
        xpos = xpos - InputImageExtents.left;
        ypos = ypos - InputImageExtents.top;
    }

    //
    // Now get the application stream and write to it
    //
    if (SUCCEEDED(hr))
    {
        hr = m_pAppWiaTransferCallback->GetNextStream(0, bstrItemName, bstrFullItemName, &pAppStream);  
    }

    //
    // Do "actual" filtering
    //
    ULONG64 ulBytesWrittenToOutputStream = 0;
    if (SUCCEEDED(hr))
    {
        hr = DoFiltering(lBrightness,
                         lContrast,
                         lRotation,
                         lDeskewX,
                         lDeskewY,
                         pInputStream,
                         pAppStream,
                         &ulBytesWrittenToOutputStream,
                         xpos,
                         ypos,
                         width,
                         height
                         );

    }

    if (pAppStream)
    {
        pAppStream->Release();
    }
    
    return hr;
}


/*****************************************************************************
 *  
 *  @func STDMETHODIMP | CImageFilter::ApplyProperties | Apply properties after filtering.
 *  
 *  @parm   IWiaPropertyStorage | pWiaPropertyStorage |
 *          Pointer to property storage that the image processing filter can write properties to.  
 * 
 *  @comm
 *  ApplyProperties is called by the WIA service after the image processing filter has processed
 *  the raw data. This method allows the image processing filter to write data back to the driver and device.
 *  This may be necessary for filters that implement things such as auto-exposure.
 *  Note, an image processing filter should only use the WriteMultiple method to write properties into
 *  the provided storage.
 *
 *  @rvalue S_OK    | 
 *              The function succeeded.
 *  @rvalue E_XXX   | 
 *              The function failed 
 * 
 *****************************************************************************/
STDMETHODIMP
CImageFilter::ApplyProperties(
    __inout    IN  IWiaPropertyStorage       *pWiaPropertyStorage)
{
    HRESULT hr = S_OK;

    hr = pWiaPropertyStorage ? S_OK : E_INVALIDARG;

    //
    // This filter only writes the MY_TEST_FILTER_PROP property for
    // illustrational purposes.
    // In general if a filter does not need to write any properties it
    // should just return S_OK.
    // 
    if (SUCCEEDED(hr))
    {
        PROPSPEC    PropSpec[1]    = {0};
        PROPVARIANT PropVariant[1] = {0};

        PropVariantInit(PropVariant);

        PropSpec[0].ulKind  = PRSPEC_PROPID;
        PropSpec[0].propid  = MY_TEST_FILTER_PROP;
        PropVariant[0].vt   = VT_I4;
        PropVariant[0].lVal = 1;

        //
        // Set the properties
        //
        hr = pWiaPropertyStorage->WriteMultiple( 1, PropSpec, PropVariant, WIA_IPA_FIRST );
    }

    return hr;
}


/*****************************************************************************
 *  
 *  @func STDMETHODIMP | CImageFilter::TransferCallback | TransferCallback implementation
 * 
  
 *  @parm   LONG | lFlags |
 *          Flags
 * 
 *  @parm   WiaTransferParams | pWiaTransferParams | 
 *          Contains transfer status
 * 
 *  @comm
 *  TransferCallback delegates to the application's callback. It changes the
 *  number of bytes written since we always cache all the data before writing to
 *  the application's stream. We do however not change the percentage since this
 *  represents percentage of total transfer time (a "real" implementation probably
 *  would take the filtering into account here).
 *  We do not write the data to the application's stream until when we receive
 *  a WIA_TRANSFER_MSG_END_OF_STREAM message. 
 *
 *  @rvalue S_OK    | 
 *              The function succeeded.
 *  @rvalue E_XXX   | 
 *              The function failed 
 * 
 *****************************************************************************/
STDMETHODIMP
CImageFilter::TransferCallback(
            IN  LONG                lFlags,
    __in    IN  WiaTransferParams   *pWiaTransferParams)
{
    HRESULT     hr = S_OK;

    if (!m_pAppWiaTransferCallback)
    {
        hr =  E_UNEXPECTED;
    }

    if ((SUCCEEDED(hr)) && (!pWiaTransferParams))
    {
        hr = E_INVALIDARG;
    }

    if (SUCCEEDED(hr))
    {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -