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

📄 wictobmscn.cpp

📁 WDK 自带的xpsdrv filter之 color
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*++

Copyright (c) 2005 Microsoft Corporation

All rights reserved.

THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
PARTICULAR PURPOSE.

File Name:

   wictobmscn.cpp

Abstract:

   WIC pixel format to BMFORMAT conversion class implementation. This class provides methods
   for converting between a source WIC scanline to a target destination BMFORMAT scanline.

--*/

#include "precomp.h"
#include "debug.h"
#include "globals.h"
#include "wictobmscn.h"

/*++

Routine Name:

    CWICToBMFormatScan::CWICToBMFormatScan

Routine Description:

    CWICToBMFormatScan constructor

Arguments:

    None

Return Value:

    None

--*/
CWICToBMFormatScan::CWICToBMFormatScan() :
    m_pScanBuffer(NULL),
    m_cbScanBuffer(0),
    m_cWidth(0),
    m_pData(NULL),
    m_cbData(0),
    m_bInitialized(FALSE)
{
}

/*++

Routine Name:

    CWICToBMFormatScan::~CWICToBMFormatScan

Routine Description:

    CWICToBMFormatScan destructor

Arguments:

    None

Return Value:

    None

--*/
CWICToBMFormatScan::~CWICToBMFormatScan()
{
    FreeScanBuffer();
}

/*++

Routine Name:

    CWICToBMFormatScan::Initialize

Routine Description:

    Initializes the WIC to BMFORMAT transform data from the WICToBMFORMAT structure

Arguments:

    WICToBM - Structure containing WIC pixel format to BMFORMAT conversion information

Return Value:

    HRESULT
    S_OK - On success
    E_*  - On error

--*/
HRESULT
CWICToBMFormatScan::Initialize(
    __in CONST WICToBMFORMAT& WICToBM
    )
{
    HRESULT hr = S_OK;

    m_convData = WICToBM;

    if (m_convData.m_pixFormTarget <= kWICPixelFormatMin ||
        m_convData.m_pixFormTarget >= kWICPixelFormatMax ||
        m_convData.m_bmFormTarget  <  kICMPixelFormatMin ||
        m_convData.m_bmFormTarget  >= kICMPixelFormatMax)
    {
        hr = E_INVALIDARG;
    }

    if (SUCCEEDED(hr) &&
        !IsVista())
    {
        //
        // When processing color data down-level from Vista, we cannot use fixed or float
        // BMFORMAT types. In these circumstances we need to convert to a 16 bpc equivalent,
        // then back again.
        //
        if (m_convData.m_bmFormTarget == kBM_32b_scRGB ||
            m_convData.m_bmFormTarget == kBM_32b_scARGB ||
            m_convData.m_bmFormTarget == kBM_S2DOT13FIXED_scRGB ||
            m_convData.m_bmFormTarget == kBM_S2DOT13FIXED_scARGB)
        {
            m_convData.m_bNeedsScanBuffer = TRUE;
            m_convData.m_bmFormTarget = kBM_16b_RGB;
        }
    }

    if (SUCCEEDED(hr))
    {
        m_bInitialized = TRUE;
    }

    ERR_ON_HR(hr);
    return hr;
}

/*++

Routine Name:

    CWICToBMFormatScan::SetData

Routine Description:

    Set the current WIC data. This method takes the WIC scanline data and
    applies any necessary conversion to achieve the required BMFORMAT

Arguments:

    bIsSrc      - Indicates if this is a source scanline (i.e. is the conversion required as the scanline is input)
    pWicPxData  - Pointer to the WIC data
    cbWicPxData - Count of bytes in the WIC data buffer
    cWidth      - Count of pixels inthe scanline

Return Value:

    HRESULT
    S_OK - On success
    E_*  - On error

--*/
HRESULT
CWICToBMFormatScan::SetData(
    __in                     CONST BOOL bIsSrc,
    __in_bcount(cbWicPxData) PBYTE      pWicPxData,
    __in                     CONST UINT cbWicPxData,
    __in                     CONST UINT cWidth
    )
{
    HRESULT hr = m_bInitialized ? S_OK : E_PENDING;

    COLORDATATYPE   srcColType  = COLOR_BYTE;
    EICMPixelFormat eICMFormSrc = kBM_RGBTRIPLETS;

    COLORDATATYPE   dstColType = COLOR_BYTE;
    EICMPixelFormat eICMFormDst = kBM_RGBTRIPLETS;

    //
    // Validate input
    //
    if (SUCCEEDED(hr) &&
        SUCCEEDED(hr = CHECK_POINTER(pWicPxData, E_POINTER)))
    {
        if (m_convData.m_pixFormTarget >= kWICPixelFormatMin &&
            m_convData.m_pixFormTarget <  kWICPixelFormatMax)
        {
            //
            // Set up the destination and source formats
            //
            eICMFormSrc = g_lutWICToBMFormat[m_convData.m_pixFormTarget].m_bmFormTarget;
            srcColType  = g_lutWICToBMFormat[m_convData.m_pixFormTarget].m_colDataType;

            if (m_convData.m_bmFormTarget <  kICMPixelFormatMax &&
                m_convData.m_bmFormTarget >= kICMPixelFormatMin)
            {
                dstColType  = g_lutBMFormatData[m_convData.m_bmFormTarget].m_colDataType;
                eICMFormDst = m_convData.m_bmFormTarget;
            }
            else
            {
                hr = E_FAIL;
            }
        }
        else
        {
            hr = E_FAIL;
        }
    }

    //
    // Validate source and destination formats
    //
    if (SUCCEEDED(hr))
    {
        if (eICMFormSrc <  kICMPixelFormatMin ||
            eICMFormSrc >= kICMPixelFormatMax ||
            eICMFormDst <  kICMPixelFormatMin ||
            eICMFormDst >= kICMPixelFormatMax)
        {
            RIP("Invalid pixel format.\n");

            hr = E_FAIL;
        }
        else if (srcColType < COLOR_BYTE ||
                 srcColType > COLOR_S2DOT13FIXED ||
                 dstColType < COLOR_BYTE ||
                 dstColType > COLOR_S2DOT13FIXED)
        {
            RIP("Invalid color data type.\n");

            hr = E_FAIL;
        }
    }

    if (SUCCEEDED(hr))
    {
        m_cWidth = cWidth;
        if (m_convData.m_bNeedsScanBuffer)
        {
            //
            // We need to convert in one way or another - create a buffer to
            // hold the intermediate scanline data
            //
            if (SUCCEEDED(hr) &&
                SUCCEEDED(hr = CreateScanBuffer(m_cWidth,
                                                g_lutColorDataSize[dstColType],
                                                g_lutBMFormatData[eICMFormDst].m_cChannels)))
            {
                if (bIsSrc)
                {
                    //
                    // We need to initialise the buffer from the WIC buffer passed in. Here we
                    // are doing one of two things:
                    //
                    // 1. Copying data directly as we have parity between the WIC and
                    //     ICM pixel formats
                    // 2. Convert from the WIC format to the ICM format and copy.
                    //

                    //
                    // Set up the source and destination pointers
                    //
                    PBYTE  pSrc = pWicPxData;
                    UINT   cSrcChannels   = g_lutWICToBMFormat[m_convData.m_pixFormTarget].m_cChannels;
                    size_t cbSrcBytesPerPixel = g_lutColorDataSize[srcColType] * cSrcChannels;

                    PBYTE  pDst = m_pScanBuffer;
                    UINT   cDstChannels   = g_lutBMFormatData[eICMFormDst].m_cChannels;
                    size_t cbDstBytesPerPixel = g_lutColorDataSize[dstColType] * cDstChannels;

                    PBYTE pSrcEnd = pSrc + cbWicPxData;
                    PBYTE pDstEnd = pDst + m_cbScanBuffer;

                    if (dstColType == m_convData.m_colDataType)
                    {
                        while (pSrc < pSrcEnd &&
                               pDst < pDstEnd)
                        {
                            if (pSrc + cbDstBytesPerPixel < pSrcEnd)
                            {
                                CopyMemory(pDst, pSrc, cbDstBytesPerPixel);
                            }
                            pSrc += cbSrcBytesPerPixel;
                            pDst += cbDstBytesPerPixel;
                        }
                    }
                    else
                    {
                        //
                        // We should only ever be required to convert from floating point and fixed point
                        // scRGB formats to 16 bpc RGB
                        //
                        if (eICMFormDst == kBM_16b_RGB &&
                            (eICMFormSrc == kBM_32b_scRGB ||
                             eICMFormSrc == kBM_32b_scARGB))
                        {
                            FLOAT* pSrcData = reinterpret_cast<FLOAT*>(pSrc);
                            WORD*  pDstData = reinterpret_cast<WORD*>(pDst);

                            while (pSrcData <= reinterpret_cast<FLOAT*>(pSrcEnd) - cSrcChannels &&
                                   pDstData <= reinterpret_cast<WORD*>(pDstEnd) - cDstChannels)
                            {
                                for (UINT cChan = 0;
                                     cChan < cDstChannels && cChan < cSrcChannels;
                                     cChan++)
                                {
                                    //
                                    // Note: We are only converting from FLOAT and not applying gamma modification
                                    // as the transform should account for this given the input scRGB ICC source profile.
                                    //
                                    if (pSrcData[cChan] <= -2.0f)
                                    {
                                        pDstData[cChan] = 0;
                                    }
                                    else if (pSrcData[cChan] >= 2.0f)
                                    {
                                        pDstData[cChan] = 0xFFFF;
                                    }
                                    else
                                    {
                                        pDstData[cChan] = static_cast<WORD>(kMaxWordAsFloat * (pSrcData[cChan] + 2.0) / 4.0f);
                                    }
                                }

                                pSrcData += cSrcChannels;
                                pDstData += cDstChannels;
                            }
                        }
                        else if (eICMFormDst == kBM_16b_RGB &&
                                 (eICMFormSrc == kBM_S2DOT13FIXED_scRGB ||
                                  eICMFormSrc == kBM_S2DOT13FIXED_scARGB))
                        {
                            WORD* pSrcData = reinterpret_cast<WORD*>(pSrc);
                            WORD* pDstData = reinterpret_cast<WORD*>(pDst);

                            while (pSrcData <= reinterpret_cast<WORD*>(pSrcEnd) - cSrcChannels &&
                                   pDstData <= reinterpret_cast<WORD*>(pDstEnd) - cDstChannels)
                            {
                                for (UINT cChan = 0;
                                     cChan < cDstChannels && cChan < cSrcChannels;
                                     cChan++)
                                {
                                    //
                                    // Note: We are only converting from S2DOT13FIXED and not applying gamma modification
                                    // as the transform should account for this given the input scRGB ICC source profile.
                                    //
                                    pDstData[cChan] = pSrcData[cChan] & kS2Dot13Neg ? pSrcData[cChan] ^ 0xFFFF : pSrcData[cChan] | kS2Dot13Neg;
                                }

                                pSrcData += cSrcChannels;
                                pDstData += cDstChannels;
                            }
                        }
                        else
                        {
                            hr = E_NOTIMPL;
                        }
                    }
                }

                //
                // Set the out buffer pointer and size to the copy buffer
                //
                if (SUCCEEDED(hr))
                {
                    m_pData  = m_pScanBuffer;
                    m_cbData = m_cbScanBuffer;
                }

⌨️ 快捷键说明

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