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

📄 colchan.cpp

📁 WDK 自带的xpsdrv filter之 color
💻 CPP
📖 第 1 页 / 共 3 页
字号:
                    // Make sure the float data runs between 0.0 and 1.0 for nChannel and sRGB and is
                    // truncated and scaled as follows for scRGB:
                    //
                    //    1. Truncate the input color to between -2.0 and +2.0
                    //    2. Offset the value by +2.0 to put it into the 0.0 to 4.0 range
                    //    3. Scale the value by 4.0 to put it into the range 0.0 to 1.0
                    //    4. Set the 16 bit value according to the channel value from 0x0000
                    //       for 0.0 to 0xFFFF for 1.0
                    //
                    if (cbDstData >= cChannels * sizeof(WORD) &&
                        cbData    >= cChannels * sizeof(FLOAT))
                    {
                        PFLOAT pSrcData = reinterpret_cast<PFLOAT>(pData);

                        if (m_dataType == scRGB)
                        {
                            for (UINT cCurrChan = 0;
                                 cCurrChan < cChannels;
                                 cCurrChan++)
                            {
                                FLOAT channelValue = pSrcData[cCurrChan];
                                channelValue = channelValue < -2.0f ? -2.0f : channelValue;
                                channelValue = channelValue >  2.0f ?  2.0f : channelValue;
                                channelValue += 2.0f;
                                channelValue /= 4.0f;
                                pDstData[cCurrChan] = static_cast<WORD>(channelValue * kMaxWordAsFloat);
                            }
                        }
                        else
                        {
                            if (SUCCEEDED(hr = ClampChannelValues(0.0f, 1.0f)))
                            {
                                for (UINT cCurrChan = 0;
                                     cCurrChan < cChannels;
                                     cCurrChan++)
                                {
                                    pDstData[cCurrChan] = static_cast<WORD>(pSrcData[cCurrChan] * kMaxWordAsFloat);
                                }
                            }
                        }
                    }
                    else
                    {
                        hr = HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
                    }
                }
                break;

                case COLOR_S2DOT13FIXED:
                {
                    hr = E_NOTIMPL;
                }
                break;

                default:
                {
                    RIP("Unrecognised color type\n");
                    hr = E_FAIL;
                }
                break;
            }
        }
    }

    ERR_ON_HR(hr);
    return hr;
}


/*++

Routine Name:

    CColorChannelData::ColorFromByte

Routine Description:

    Uses an 8 bpc COLOR structure to set the channel data

Arguments:

    pSrcData  - Pointer to the source COLOR data
    cbSrcData - Size of the source buffer in bytes

Return Value:

    HRESULT
    S_OK - On success
    E_*  - On error

--*/
HRESULT
CColorChannelData::ColorFromByte(
    __in_bcount(cbSrcData) PBYTE       pSrcData,
    __in                   CONST UINT& cbSrcData
    )
{
    HRESULT hr = S_OK;

    DWORD cChannels = 0;
    DWORD cbData = 0;
    PBYTE pData = NULL;

    if (SUCCEEDED(hr = CHECK_POINTER(pSrcData, E_POINTER)) &&
        SUCCEEDED(hr = GetChannelCountNoAlpha(&cChannels)) &&
        SUCCEEDED(hr = GetChannelDataNoAlpha(&cbData, reinterpret_cast<PVOID*>(&pData))))
    {
        ZeroMemory(pData, cbData);

        if (cbSrcData > 0)
        {
            switch (m_channelType)
            {
                case COLOR_BYTE:
                {
                    if (cbData    >= cChannels * sizeof(BYTE) &&
                        cbSrcData >= cChannels * sizeof(BYTE))
                    {
                        //
                        // Just copy src to dst
                        //
                        CopyMemory(pData, pSrcData, cChannels * sizeof(BYTE));
                    }
                    else
                    {
                        hr = HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
                    }
                }
                break;

                case COLOR_WORD:
                {
                    if (cbData    >= cChannels * sizeof(WORD) &&
                        cbSrcData >= cChannels * sizeof(BYTE))
                    {
                        PWORD pDstData = reinterpret_cast<PWORD>(pData);

                        for (UINT cCurrChan = 0;
                             cCurrChan < cChannels;
                             cCurrChan++)
                        {
                            pDstData[cCurrChan] = static_cast<WORD>(MulDiv(pSrcData[cCurrChan], 0xFFFF, 0xFF));
                        }
                    }
                    else
                    {
                        hr = HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
                    }
                }
                break;

                case COLOR_FLOAT:
                {
                    //
                    // Make sure the float data is scaled to 0.0 and 1.0 for nChannel and sRGB and is
                    // scaled as follows for scRGB:
                    //
                    //    1. Convert the WORD value from 0x00 - 0xFF to 0.0f - 1.0f
                    //    1. Scale the value up by 4.0 to put it into the range 0.0 to 2.0
                    //    2. Offset the value by -2.0 to put it into the -2.0 to 2.0 range
                    //
                    if (cbData    >= cChannels * sizeof(FLOAT) &&
                        cbSrcData >= cChannels * sizeof(BYTE))
                    {
                        PFLOAT pDstData = reinterpret_cast<PFLOAT>(pData);

                        if (m_dataType == scRGB)
                        {
                            for (UINT cCurrChan = 0;
                                 cCurrChan < cChannels;
                                 cCurrChan++)
                            {
                                pDstData[cCurrChan] = ((static_cast<FLOAT>(pSrcData[cCurrChan])*4.0f)/kMaxByteAsFloat) - 2.0f;
                            }
                        }
                        else
                        {
                            for (UINT cCurrChan = 0;
                                 cCurrChan < cChannels;
                                 cCurrChan++)
                            {
                                pDstData[cCurrChan] = static_cast<FLOAT>(pSrcData[cCurrChan])/kMaxByteAsFloat;
                            }
                        }
                    }
                    else
                    {
                        hr = HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
                    }
                }
                break;

                case COLOR_S2DOT13FIXED:
                {
                    hr = E_NOTIMPL;
                }
                break;

                default:
                {
                    RIP("Unrecognised color type\n");
                    hr = E_FAIL;
                }
                break;
            }
        }
    }

    ERR_ON_HR(hr);
    return hr;
}

/*++

Routine Name:

    CColorChannelData::ColorFromWord

Routine Description:

    Uses an 16 bpc COLOR structure to set the channel data

Arguments:

    pSrcData  - Pointer to the source COLOR data
    cbSrcData - Size of the source buffer in bytes

Return Value:

    HRESULT
    S_OK - On success
    E_*  - On error

--*/
HRESULT
CColorChannelData::ColorFromWord(
    __in_bcount(cbSrcData) PWORD       pSrcData,
    __in                   CONST UINT& cbSrcData
    )
{
    HRESULT hr = S_OK;

    DWORD cChannels = 0;
    DWORD cbData = 0;
    PBYTE pData = NULL;

    if (SUCCEEDED(hr = CHECK_POINTER(pSrcData, E_POINTER)) &&
        SUCCEEDED(hr = GetChannelCountNoAlpha(&cChannels)) &&
        SUCCEEDED(hr = GetChannelDataNoAlpha(&cbData, reinterpret_cast<PVOID*>(&pData))))
    {
        ZeroMemory(pData, cbData);

        if (cbSrcData > 0)
        {
            switch (m_channelType)
            {
                case COLOR_BYTE:
                {
                    if (cbData    >= cChannels * sizeof(BYTE) &&
                        cbSrcData >= cChannels * sizeof(WORD))
                    {
                        for (UINT cCurrChan = 0;
                             cCurrChan < cChannels;
                             cCurrChan++)
                        {
                            pData[cCurrChan] = static_cast<BYTE>(MulDiv(pSrcData[cCurrChan], 0xFF, 0xFFFF));
                        }
                    }
                    else
                    {
                        hr = HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
                    }
                }
                break;

                case COLOR_WORD:
                {
                    if (cbData    >= cChannels * sizeof(WORD) &&
                        cbSrcData >= cChannels * sizeof(WORD))
                    {
                        //
                        // Just copy src to dst
                        //
                        CopyMemory(pData, pSrcData, cChannels * sizeof(WORD));
                    }
                    else
                    {
                        hr = HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
                    }
                }
                break;

                case COLOR_FLOAT:
                {
                    //
                    // Make sure the float data is scaled to 0.0 and 1.0 for nChannel and sRGB and is
                    // scaled as follows for scRGB:
                    //
                    //    1. Convert the WORD value from 0x0000 - 0xFFFF to 0.0f - 1.0f
                    //    1. Scale the value up by 4.0 to put it into the range 0.0 to 2.0
                    //    2. Offset the value by -2.0 to put it into the -2.0 to 2.0 range
                    //
                    if (cbData    >= cChannels * sizeof(FLOAT) &&
                        cbSrcData >= cChannels * sizeof(WORD))
                    {
                        PFLOAT pDstData = reinterpret_cast<PFLOAT>(pData);

                        if (m_dataType == scRGB)
                        {
                            for (UINT cCurrChan = 0;
                                 cCurrChan < cChannels;
                                 cCurrChan++)
                            {
                                pDstData[cCurrChan] = ((static_cast<FLOAT>(pSrcData[cCurrChan])*4.0f)/kMaxWordAsFloat) - 2.0f;
                            }
                        }
                        else
                        {
                            for (UINT cCurrChan = 0;
                                 cCurrChan < cChannels;
                                 cCurrChan++)
                            {
                                pDstData[cCurrChan] = static_cast<FLOAT>(pSrcData[cCurrChan])/kMaxWordAsFloat;
                            }
                        }
                    }
                    else
                    {
                        hr = HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
                    }
                }
                break;

                case COLOR_S2DOT13FIXED:
                {
                    hr = E_NOTIMPL;
                }
                break;

                default:
                {
                    RIP("Unrecognised color type\n");
                    hr = E_FAIL;
                }
                break;
            }
        }
    }

    ERR_ON_HR(hr);
    return hr;
}

/*++

Routine Name:

    CColorChannelData::GetChannelSizeFromType

Routine Description:

    Retrieves the channel data size from the channel data type

Arguments:

    channelType    - The color channel data type
    pcbChannelSize - Pointer to storage to recieve the channel data size

Return Value:

    HRESULT
    S_OK - On success
    E_*  - On error

--*/
HRESULT
CColorChannelData::GetChannelSizeFromType(
    __in  CONST COLORDATATYPE& channelType,
    __out DWORD*               pcbChannelSize
    )
{
    HRESULT hr = S_OK;

    if (SUCCEEDED(hr = CHECK_POINTER(pcbChannelSize, E_POINTER)))
    {
        if (channelType < COLOR_BYTE ||
            channelType > COLOR_S2DOT13FIXED)
        {
            hr = E_INVALIDARG;
        }
    }

    if (SUCCEEDED(hr))
    {
        *pcbChannelSize = g_cbChannelType[channelType - 1];
    }

    ERR_ON_HR(hr);
    return hr;
}

/*++

Routine Name:

    CColorChannelData::ValidateDataSize

Routine Description:

    Template method that validates the data size given the current channel data type

Arguments:

    None

Return Value:

    HRESULT
    S_OK - On success
    E_*  - On error

--*/
template <class _T>
HRESULT
CColorChannelData::ValidateDataSize(
    VOID
    )
{
    HRESULT hr = S_OK;

    DWORD cbDataSize = 0;
    if (SUCCEEDED(hr = GetChannelSizeFromType(m_channelType, &cbDataSize)))
    {
        //
        // Make sure the data being added matches the data type in size
        //
        if (sizeof(_T) != cbDataSize)
        {
            hr = E_INVALIDARG;
        }
    }

    ERR_ON_HR(hr);
    return hr;
}

/*++

Routine Name:

    CColorChannelData::AllocateChannelBuffers

Routine Description:

    Allocates the channel data buffer

Arguments:

    pcbBuffer - Pointer to variable that recieves the allocated buffer size
    ppBuffer  - Pointer to a pointer that recieves the buffer address

Return Value:

    HRESULT
    S_OK - On success
    E_*  - On error

--*/
HRESULT
CColorChannelData::AllocateChannelBuffers(
    __out                          UINT*  pcbBuffer,
    __deref_out_bcount(*pcbBuffer) PBYTE* ppBuffer
    )
{
    HRESULT hr = S_OK;

    if (SUCCEEDED(hr = CHECK_POINTER(pcbBuffer, E_POINTER)) &&
        SUCCEEDED(hr = CHECK_POINTER(ppBuffer, E_POINTER)))
    {
        //
        // Allocate a buffer for the channel data MAX_CHANNEL_COUNT x MAX_CHANNEL_SIZE
        // This guarantees we have enough storage for the maximum n-channel support
        // in WCS
        //
        *pcbBuffer = MAX_CHANNEL_COUNT*MAX_CHANNEL_SIZE;
        *ppBuffer = new BYTE[*pcbBuffer];

        if (*ppBuffer == NULL)
        {
            *pcbBuffer = 0;
            hr = E_OUTOFMEMORY;
        }
    }

    ERR_ON_HR(hr);
    return hr;
}

/*++

Routine Name:

    CColorChannelData::FreeChannelBuffers

Routine Description:

    Releases channel buffer

Arguments:

    None

Return Value:

    None

--*/
VOID
CColorChannelData::FreeChannelBuffers(
    VOID
    )
{
    if (m_pChannelData != NULL)
    {
        delete[] m_pChannelData;
        m_pChannelData = NULL;
    }
    m_cbChannelData = 0;
}

/*++

Routine Name:

    CColorChannelData::GetAlphaAsFloat

Routine Description:

    Retrieves the alpha value of the channel data as a float

Arguments:

    pAlpha - Pointer to a float that recieves the alpha value

Return Value:

    HRESULT
    S_OK - On success
    E_*  - On error

--*/
HRESULT
CColorChannelData::GetAlphaAsFloat(
    __out PFLOAT pAlpha
    )
{
    HRESULT hr = S_OK;

    if (SUCCEEDED(hr = CHECK_POINTER(pAlpha, E_POINTER)))
    {
        *pAlpha = 0.0f;

        if (HasAlpha())
        {
            switch (m_channelType)
            {
                case COLOR_BYTE:
                {
                    *pAlpha = static_cast<FLOAT>(*m_pChannelData)/kMaxByteAsFloat;
                }
                break;

                case COLOR_WORD:
                {
                    *pAlpha = static_cast<FLOAT>(*reinterpret_cast<WORD*>(m_pChannelData))/kMaxWordAsFloat;
                }
                break;

                case COLOR_FLOAT:
                {
                    *pAlpha = *reinterpret_cast<PFLOAT>(m_pChannelData);
                }
                break;

                case COLOR_S2DOT13FIXED:
                {
                    hr = E_NOTIMPL;
                }
                break;

                default:
                {
                    RIP("Unrecognised channel data format.\n");
                    hr = E_FAIL;
                }
                break;
            }
        }
    }

    ERR_ON_HR(hr);
    return hr;
}


⌨️ 快捷键说明

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