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

📄 wictobmscn.cpp

📁 WDK 自带的xpsdrv filter之 color
💻 CPP
📖 第 1 页 / 共 2 页
字号:
            }
        }
        else
        {
            //
            // Set the out buffer pointer and size to the WIC pixel data
            //
            m_pData  = pWicPxData;
            m_cbData = cbWicPxData;
        }
    }

    ERR_ON_HR(hr);
    return hr;
}

/*++

Routine Name:

    CWICToBMFormatScan::Commit

Routine Description:

    Commits the internal scanline data to the WIC data buffer

Arguments:

    pWicPxData  - Pointer to the WIC data
    cbWicPxData - Count of bytes in the WIC data buffer

Return Value:

    HRESULT
    S_OK - On success
    E_*  - On error

--*/
HRESULT
CWICToBMFormatScan::Commit(
    __in_bcount(cbWicPxData) PBYTE      pWicPxData,
    __in                     CONST UINT cbWicPxData
    )
{
    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
            //
            eICMFormDst = g_lutWICToBMFormat[m_convData.m_pixFormTarget].m_bmFormTarget;
            dstColType  = g_lutWICToBMFormat[m_convData.m_pixFormTarget].m_colDataType;

            if (m_convData.m_bmFormTarget <  kICMPixelFormatMax &&
                m_convData.m_bmFormTarget >= kICMPixelFormatMin)
            {
                eICMFormSrc = m_convData.m_bmFormTarget;
                srcColType = g_lutBMFormatData[eICMFormSrc].m_colDataType;
            }
            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))
    {
        if (pWicPxData != m_pData)
        {
            //
            // We need to convert the scan buffer and write back into the WIC buffer
            //
            PBYTE  pDst = pWicPxData;
            UINT   cDstChannels   = g_lutWICToBMFormat[m_convData.m_pixFormTarget].m_cChannels;
            size_t cbDstBytesPerPixel = g_lutColorDataSize[dstColType] * cDstChannels;

            PBYTE  pSrc = m_pScanBuffer;
            UINT   cSrcChannels   = g_lutBMFormatData[eICMFormSrc].m_cChannels;
            size_t cbSrcBytesPerPixel = g_lutColorDataSize[srcColType] * cSrcChannels;

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

            if (srcColType == m_convData.m_colDataType)
            {
                while (pSrc < pSrcEnd &&
                       pDst < pDstEnd)
                {
                    if (pDst + cbSrcBytesPerPixel < pDstEnd)
                    {
                        CopyMemory(pDst, pSrc, cbSrcBytesPerPixel);
                    }

                    pSrc += cbSrcBytesPerPixel;
                    pDst += cbDstBytesPerPixel;
                }
            }
            else
            {
                //
                // We should only ever be required to convert from 16 bpc RGB to floating point
                // and fixed point scRGB formats
                //
                if (eICMFormSrc == kBM_16b_RGB &&
                    (eICMFormDst == kBM_32b_scRGB ||
                     eICMFormDst == kBM_32b_scARGB))
                {
                    WORD*  pSrcData = reinterpret_cast<WORD*>(pSrc);
                    FLOAT* pDstData = reinterpret_cast<FLOAT*>(pDst);
                    UINT cAlpha = eICMFormDst == kBM_32b_scARGB ? 1 : 0;

                    while (pSrcData <= reinterpret_cast<WORD*>(pSrcEnd) - cSrcChannels &&
                           pDstData <= reinterpret_cast<FLOAT*>(pDstEnd) - cDstChannels)
                    {
                        pDstData += cAlpha;

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

                        pSrcData += cSrcChannels;
                        pDstData += cDstChannels - cAlpha;
                    }
                }
                else if (eICMFormSrc == kBM_16b_RGB &&
                         (eICMFormDst == kBM_S2DOT13FIXED_scRGB ||
                          eICMFormDst == kBM_S2DOT13FIXED_scARGB))
                {
                    WORD* pSrcData = reinterpret_cast<WORD*>(pSrc);
                    WORD* pDstData = reinterpret_cast<WORD*>(pDst);
                    UINT cAlpha = eICMFormDst == kBM_S2DOT13FIXED_scARGB ? 1 : 0;

                    while (pSrcData <= reinterpret_cast<WORD*>(pSrcEnd) - cSrcChannels &&
                           pDstData <= reinterpret_cast<WORD*>(pDstEnd) - cDstChannels)
                    {
                        pDstData += cAlpha;

                        for (UINT cChan = 0;
                             cChan < (cDstChannels - cAlpha) && cChan < cSrcChannels;
                             cChan++)
                        {
                            //
                            // Note: We are only converting to 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] ^ kS2Dot13Neg : pSrcData[cChan] ^ 0xFFFF;
                        }

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

    ERR_ON_HR(hr);
    return hr;
}

/*++

Routine Name:

    CWICToBMFormatScan::GetData

Routine Description:

    Retrieves the BMFORMAT buffer ready for processing

Arguments:

    ppData    - Pointer to a pointer that recieves the address of the data buffer.
                Note: the buffer is only valid for the lifetime of the CWICToBMFormatScan object.
    pBmFormat - Pointer to a BMFORMAT enum that recieves the type
    pcWidth   - Pointer to storage that recieves the pixel width
    pcbStride - Pointer to storage that recieves the scanline stride

Return Value:

    HRESULT
    S_OK - On success
    E_*  - On error

--*/
HRESULT
CWICToBMFormatScan::GetData(
    __deref_out_bcount(*pcbStride) PBYTE*    ppData,
    __out                          BMFORMAT* pBmFormat,
    __out                          UINT*     pcWidth,
    __out                          UINT*     pcbStride
    )
{
    HRESULT hr = S_OK;

    if (SUCCEEDED(hr = CHECK_POINTER(ppData, E_POINTER)) &&
        SUCCEEDED(hr = CHECK_POINTER(pBmFormat, E_POINTER)) &&
        SUCCEEDED(hr = CHECK_POINTER(pcWidth, E_POINTER)) &&
        SUCCEEDED(hr = CHECK_POINTER(pcbStride, E_POINTER)) &&
        SUCCEEDED(hr = CHECK_POINTER(m_pData, E_PENDING)))
    {
        if (m_convData.m_bmFormTarget >= kICMPixelFormatMin &&
            m_convData.m_bmFormTarget <  kICMPixelFormatMax)
        {
            *pBmFormat = g_lutBMFormatData[m_convData.m_bmFormTarget].m_bmFormat;
            *pcWidth   = m_cWidth;
            *ppData    = m_pData;
            *pcbStride = static_cast<UINT>(m_cbData);
        }
        else
        {
            hr = E_FAIL;
        }
    }

    ERR_ON_HR(hr);
    return hr;
}

/*++

Routine Name:

    CWICToBMFormatScan::CreateScanBuffer

Routine Description:

    Creates the intermediate scanline buffer

Arguments:

    cWidth - Pixel width of the scanline

Return Value:

    HRESULT
    S_OK - On success
    E_*  - On error

--*/
HRESULT
CWICToBMFormatScan::CreateScanBuffer(
    __in CONST UINT   cWidth,
    __in CONST SIZE_T cbDataType,
    __in CONST UINT   cChannels
    )
{
    HRESULT hr = S_OK;

    if (cWidth     > MAX_PIXELWIDTH_COUNT ||
        cbDataType > MAX_COLDATATYPE_SIZE ||
        cChannels  > MAX_COLCHANNEL_COUNT)
    {
        hr = E_INVALIDARG;
    }

    size_t cbScanBuffer = 0;

    if (SUCCEEDED(hr))
    {
        if (FAILED(SizeTMult(cWidth, cbDataType, &cbScanBuffer)) ||
            FAILED(SizeTMult(cbScanBuffer, cChannels, &cbScanBuffer)))
        {
            hr = HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW);
        }

    }

    if (SUCCEEDED(hr))
    {
        if (cbScanBuffer != m_cbScanBuffer)
        {
            FreeScanBuffer();
            m_pScanBuffer = new BYTE[cbScanBuffer];
            if (SUCCEEDED(hr = CHECK_POINTER(m_pScanBuffer, E_OUTOFMEMORY)))
            {
                m_cbScanBuffer = cbScanBuffer;
            }
        }
    }

    ERR_ON_HR(hr);
    return hr;
}

/*++

Routine Name:

    CWICToBMFormatScan::FreeScanBuffer

Routine Description:

    Free the intermediate scanline buffer

Arguments:

    None

Return Value:

    None

--*/
VOID
CWICToBMFormatScan::FreeScanBuffer(
    VOID
    )
{
    if (m_pScanBuffer != NULL)
    {
        delete[] m_pScanBuffer;
        m_pScanBuffer = NULL;
    }

    m_cbScanBuffer = 0;
}


⌨️ 快捷键说明

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