pximage.cpp

来自「symbian 下的helix player源代码」· C++ 代码 · 共 1,933 行 · 第 1/5 页

CPP
1,933
字号
        // Determine the number of bytes we need
        UINT32 ulNumBytes = m_lRowStride * m_cBitmapInfo.biHeight;

        // Check to see if we need to alloc memory. We will allocate
        // if the bAlloc parameter tells us to OR if bAlloc is FALSE
        // AND we have don't already have enough to satisfy the request.
        if (bAlloc || (!bAlloc && m_pImageStore->GetSize() < ulNumBytes))
        {
            // Create a new image store
            HX_RELEASE(m_pImageStore);
            m_pImageStore = (IHXBuffer *) new CHXBuffer();
            if (!m_pImageStore)
            {
                ResetMembers();
                return HXR_OUTOFMEMORY;
            }
            m_pImageStore->AddRef();

            // Set its size
            HX_RESULT retVal     = m_pImageStore->SetSize(ulNumBytes);
            if (retVal != HXR_OK)
            {
                Destroy();
                return retVal;
            }
        }

        // Set the image buffer
        if (m_bRowsInverted)
        {
            m_pImageBuffer = m_pImageStore->GetBuffer() + (m_cBitmapInfo.biHeight - 1) * m_lRowStride;
            m_lRowJump     = - m_lRowStride;
        }
        else
        {
            m_pImageBuffer = m_pImageStore->GetBuffer();
            m_lRowJump     = m_lRowStride;
        }

        // Copy the data
        BYTE* pSrcRow = pImg->m_pImageBuffer + lY * pImg->m_lRowJump + lX * pImg->m_ulBytesPerPixel;
        BYTE* pDstRow = m_pImageBuffer;
        for (INT32 i = m_cBitmapInfo.biHeight; i; i--)
        {
            memcpy(pDstRow, pSrcRow, m_lRowBytes); /* Flawfinder: ignore */
            pSrcRow += pImg->m_lRowJump;
            pDstRow += m_lRowJump;
        }
    }
    else
    {
        // Set member variables
        m_cBitmapInfo          = pImg->m_cBitmapInfo;
        m_cSubImageRect.left   = lX;
        m_cSubImageRect.top    = lY;
        m_cSubImageRect.right  = lX + lW;
        m_cSubImageRect.bottom = lY + lH;
        m_lSubImageWidth       = lW;
        m_lSubImageHeight      = lH;
        m_ulBytesPerPixel      = pImg->m_ulBytesPerPixel;
        m_bRowsInverted        = pImg->m_bRowsInverted;
        m_lRowBytes            = lW * m_ulBytesPerPixel;
        m_bHasAlpha            = pImg->m_bHasAlpha;

        // We ARE NOT copying, so our row stride and jump are the same
        // as the source image
        m_lRowStride = pImg->m_lRowStride;
        m_lRowJump   = pImg->m_lRowJump;

        // Ref the other image store
        HX_RELEASE(m_pImageStore);
        m_pImageStore = pImg->m_pImageStore;
        m_pImageStore->AddRef();

        // Set the image buffer properly (note that we must offset
        // from the other object's m_pImageBuffer member and NOT the
        // image store member - because we may be a subimage of a subimage)
        m_pImageBuffer = pImg->m_pImageBuffer + (lY * m_lRowJump) + (lX * m_ulBytesPerPixel);
    }

    // Set the initialization flag
    m_bInitialized = TRUE;

    return HXR_OK;
}

HX_RESULT PXImage::CreateSubImage(PXImage* pImg, const PXRect& rSubRect,
                                  BOOL bCopy, BOOL bAlloc)
{
    return CreateSubImage(pImg, (INT32) rSubRect.GetX(), (INT32) rSubRect.GetY(),
                          (INT32) rSubRect.GetWidth(), (INT32) rSubRect.GetHeight(),
                          bCopy, bAlloc);
}

HX_RESULT PXImage::CreateSubImage(PXImage* pImg, const HXxRect& rSubRect,
                                  BOOL bCopy, BOOL bAlloc)
{
    return CreateSubImage(pImg, rSubRect.left, rSubRect.top, HXxRECT_WIDTH(rSubRect),
                          HXxRECT_HEIGHT(rSubRect), bCopy, bAlloc);
}
HX_RESULT PXImage::CreateSubImageFromBuffer(PXImage* pImg, INT32 lX, INT32 lY,
                                            INT32 lW, INT32 lH, IHXBuffer* pBuffer)
{
    HX_RESULT retVal = HXR_OK;

    // Check for input error
    if (pImg && lX >= 0 && lY >= 0 && lW >= 0 && lH >= 0)
    {
        // Adjust for default input
        if (lW == 0)
        {
            lW = pImg->GetWidth();
        }
        if (lH == 0)
        {
            lH = pImg->GetHeight();
        }

        // Check for input error
        if (lX + lW >  pImg->GetWidth())
        {
            lW = pImg->GetWidth() - lX;
        }
        if (lY + lH >  pImg->GetHeight())
        {
            lH = pImg->GetHeight() - lY;
        }

        // Reset everything (except image store)
        ResetMembers();

        // Set member variables
        m_cBitmapInfo.biWidth       = lW;
        m_cBitmapInfo.biHeight      = lH;
        m_cBitmapInfo.biBitCount    = pImg->m_cBitmapInfo.biBitCount;
        m_cBitmapInfo.biCompression = pImg->m_cBitmapInfo.biCompression;
        m_cSubImageRect.left        = 0;
        m_cSubImageRect.top         = 0;
        m_cSubImageRect.right       = lW;
        m_cSubImageRect.bottom      = lH;
        m_lSubImageWidth            = lW;
        m_lSubImageHeight           = lH;
        m_bRowsInverted             = pImg->m_bRowsInverted;
        m_ulBytesPerPixel           = pImg->m_ulBytesPerPixel;
        m_lRowBytes                 = lW * m_ulBytesPerPixel;
        m_lRowStride                = (m_lRowBytes + 3) & ~3;
        m_bHasAlpha                 = pImg->m_bHasAlpha;

        // Determine the number of bytes we need
        UINT32 ulNumBytes = m_lRowStride * m_cBitmapInfo.biHeight;

        // Make sure that the buffer we were provided is big enough
        if (pBuffer->GetSize() >= ulNumBytes)
        {
            // Save the buffer
            HX_RELEASE(m_pImageStore);
            m_pImageStore = pBuffer;
            m_pImageStore->AddRef();

            // Set the image buffer
            if (m_bRowsInverted)
            {
                m_pImageBuffer = m_pImageStore->GetBuffer() + (m_cBitmapInfo.biHeight - 1) * m_lRowStride;
                m_lRowJump     = - m_lRowStride;
            }
            else
            {
                m_pImageBuffer = m_pImageStore->GetBuffer();
                m_lRowJump     = m_lRowStride;
            }

            // Copy the data
            BYTE* pSrcRow = pImg->m_pImageBuffer + lY * pImg->m_lRowJump + lX * pImg->m_ulBytesPerPixel;
            BYTE* pDstRow = m_pImageBuffer;
            for (INT32 i = m_cBitmapInfo.biHeight; i; i--)
            {
                memcpy(pDstRow, pSrcRow, m_lRowBytes); /* Flawfinder: ignore */
                pSrcRow += pImg->m_lRowJump;
                pDstRow += m_lRowJump;
            }
        }
        else
        {
            retVal = HXR_INVALID_PARAMETER;
        }
    }
    else
    {
        retVal = HXR_INVALID_PARAMETER;
    }

    if (SUCCEEDED(retVal))
    {
        // Set the initialization flag
        m_bInitialized = TRUE;
    }

    return retVal;
}

HX_RESULT PXImage::CreateSubImageFromBuffer(PXImage* pImg, const PXRect& rSubRect, IHXBuffer* pBuffer)
{
    return CreateSubImageFromBuffer(pImg, (INT32) rSubRect.GetX(), (INT32) rSubRect.GetY(),
                                    (INT32) rSubRect.GetWidth(), (INT32) rSubRect.GetHeight(), pBuffer);
}

void PXImage::Destroy()
{
    HX_RELEASE(m_pImageStore);
    ResetMembers();
}

HX_RESULT PXImage::Fill(const PXColor& rColor)
{
    UINT32 ulColor = MAKE_RGBA32(rColor.GetRed(),
                                 rColor.GetGreen(),
                                 rColor.GetBlue(),
                                 rColor.GetAlpha());
    return Fill32(ulColor);
}

HX_RESULT PXImage::Fill32(UINT32 ulColor)
{
    HX_RESULT retVal = HXR_OK;

    if (m_bInitialized)
    {
        if (m_cBitmapInfo.biBitCount == 32 &&
            CompressionSupported())
        {
            UINT32* pRow    = (UINT32*) m_pImageBuffer;
            INT32   lJump   = m_lRowJump >> 2;
            for (UINT32 ulY = (UINT32) m_lSubImageHeight; ulY; ulY--)
            {
                UINT32* pPixel = pRow;
                for (UINT32 ulX = (UINT32) m_lSubImageWidth; ulX; ulX--)
                {
                    *pPixel++ = ulColor;
                }
                pRow += lJump;
            }
        }
        else
        {
            retVal = HXR_FAIL;
        }
    }
    else
    {
        retVal = HXR_NOT_INITIALIZED;
    }

    return retVal;
}

HX_RESULT PXImage::Blend(PXImage* pImg1, PXImage* pImg2, BYTE* pLUT1, BYTE* pLUT2)
{
    if (!pImg1 || !pImg2 || !pLUT1 || !pLUT2 || !m_bInitialized)
    {
        HX_ASSERT(FALSE);
        return HXR_FAIL;
    }

    FILTER_OUT_UNSUPPORTED_FORMATS;

    if (!Compatible(pImg1) || !Compatible(pImg2) || !SameSize(pImg1) || !SameSize(pImg2))
    {
        HX_ASSERT(FALSE);
        return HXR_FAIL;
    }

    UINT32* pSrcRow1  = (UINT32*) pImg1->m_pImageBuffer;
    UINT32* pSrcRow2  = (UINT32*) pImg2->m_pImageBuffer;
    UINT32* pDstRow   = (UINT32*) m_pImageBuffer;
    INT32   lSrc1Jump = pImg1->m_lRowJump >> 2;
    INT32   lSrc2Jump = pImg2->m_lRowJump >> 2;
    INT32   lDstJump  = m_lRowJump       >> 2;
    for (INT32 lY = m_lSubImageHeight; lY; lY--)
    {
        UINT32* pSrc1 = pSrcRow1;
        UINT32* pSrc2 = pSrcRow2;
        UINT32* pDst  = pDstRow;
        if (pImg2->m_bHasAlpha)
        {
            for (INT32 lX = m_lSubImageWidth; lX; lX--)
            {
                UINT32 ulR = pLUT1[GETRED32(*pSrc1)]   + pLUT2[GETRED32(*pSrc2)];
                UINT32 ulG = pLUT1[GETGREEN32(*pSrc1)] + pLUT2[GETGREEN32(*pSrc2)];
                UINT32 ulB = pLUT1[GETBLUE32(*pSrc1)]  + pLUT2[GETBLUE32(*pSrc2)];
                UINT32 ulA = GETALPHA32(*pSrc2);
                ulA        = (ulA < 128 ? ulA : ulA + 1); // scale to 256
                *pDst      = MAKE_RGB32(ALPHABLEND(GETRED32(*pDst),   ulR, ulA),
                                        ALPHABLEND(GETGREEN32(*pDst), ulG, ulA),
                                        ALPHABLEND(GETBLUE32(*pDst),  ulB, ulA));
                pSrc1++;
                pSrc2++;
                pDst++;
            }
        }
        else
        {
            for (INT32 lX = m_lSubImageWidth; lX; lX--)
            {
                *pDst = MAKE_RGB32(pLUT1[GETRED32(*pSrc1)]   + pLUT2[GETRED32(*pSrc2)],
                                   pLUT1[GETGREEN32(*pSrc1)] + pLUT2[GETGREEN32(*pSrc2)],
                                   pLUT1[GETBLUE32(*pSrc1)]  + pLUT2[GETBLUE32(*pSrc2)]);
                pSrc1++;
                pSrc2++;
                pDst++;
            }
        }
        pSrcRow1 += lSrc1Jump;
        pSrcRow2 += lSrc2Jump;
        pDstRow  += lDstJump;
    }

    return HXR_OK;
}

HX_RESULT PXImage::RecursiveBlend(PXImage* pImg1, BYTE* pLUT1, BYTE* pSelfLUT)
{
    if (!pImg1 || !pLUT1 || !pSelfLUT || !m_bInitialized)
    {
        HX_ASSERT(FALSE);
        return HXR_FAIL;
    }

    FILTER_OUT_UNSUPPORTED_FORMATS;

    if (!Compatible(pImg1) || !SameSize(pImg1))
    {
        HX_ASSERT(FALSE);
        return HXR_FAIL;
    }

    UINT32* pSrcRow1 = (UINT32*) pImg1->m_pImageBuffer;
    UINT32* pDstRow  = (UINT32*) m_pImageBuffer;
    INT32   lSrc1Jump = pImg1->m_lRowJump >> 2;
    INT32   lDstJump  = m_lRowJump       >> 2;
    for (INT32 lY = m_lSubImageHeight; lY; lY--)
    {
        UINT32* pSrc1 = pSrcRow1;
        UINT32* pDst  = pDstRow;
        for (INT32 lX = m_lSubImageWidth; lX; lX--)
        {
            *pDst = MAKE_RGB32(pLUT1[GETRED32(*pSrc1)]   + pSelfLUT[GETRED32(*pDst)],
                               pLUT1[GETGREEN32(*pSrc1)] + pSelfLUT[GETGREEN32(*pDst)],
                               pLUT1[GETBLUE32(*pSrc1)]  + pSelfLUT[GETBLUE32(*pDst)]);
            pSrc1++;
            pDst++;
        }
        pSrcRow1 += lSrc1Jump;
        pDstRow  += lDstJump;
    }

    return HXR_OK;
}

HX_RESULT PXImage::BlendToColor(PXImage* pImg1, const PXColor& rColor, BYTE* pLUT1, BYTE* pLUT2)
{
    if (!pImg1 || !pLUT1 || !pLUT2 || !m_bInitialized)
    {
        HX_ASSERT(FALSE);
        return HXR_FAIL;
    }

    FILTER_OUT_UNSUPPORTED_FORMATS;

    if (!Compatible(pImg1) || !SameSize(pImg1))
    {
        HX_ASSERT(FALSE);
        return HXR_FAIL;
    }

    BYTE ucFadedR = pLUT2[rColor.GetRed()];
    BYTE ucFadedG = pLUT2[rColor.GetGreen()];
    BYTE ucFadedB = pLUT2[rColor.GetBlue()];

    UINT32* pSrcRow1 = (UINT32*) pImg1->m_pImageBuffer;
    UINT32* pDstRow  = (UINT32*) m_pImageBuffer;
    INT32   lSrc1Jump = pImg1->m_lRowJump >> 2;
    INT32   lDstJump  = m_lRowJump       >> 2;
    for (INT32 lY = m_lSubImageHeight; lY; lY--)
    {
        UINT32* pSrc1 = pSrcRow1;
        UINT32* pDst  = pDstRow;
        for (INT32 lX = m_lSubImageWidth; lX; lX--)

⌨️ 快捷键说明

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