comimgrend.cpp

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

CPP
711
字号
    ClearPacketList();
    HX_RELEASE(m_pContext);
    HX_RELEASE(m_pSite);
    HX_RELEASE(m_pCommonClassFactory);
    HX_DELETE(m_pPacketList);
    HX_DELETE(m_pBitmapInfoHeader);
    HX_RELEASE(m_pOutputBuffer);
    HX_DELETE(m_pNativeImageDecoder);

    return retVal;
}

STDMETHODIMP CCommonImageRenderer::AttachSite(IHXSite* pSite)
{
    HX_RESULT retVal = HXR_FAIL;

    if (pSite && !m_pSite)
    {
        // Save the site
        m_pSite = pSite;
        m_pSite->AddRef();
        // Set the size of the site
        HXxSize cSize = {m_ulImageWidth, m_ulImageHeight};
        m_pSite->SetSize(cSize);
        // Clear the return value
        retVal = HXR_OK;
    }

    return retVal;
}

STDMETHODIMP CCommonImageRenderer::DetachSite()
{
    HX_RESULT retVal = HXR_OK;

    // Release our ref on the site
    HX_RELEASE(m_pSite);

    return retVal;
}

STDMETHODIMP CCommonImageRenderer::HandleEvent(HXxEvent* pEvent)
{
    HX_RESULT retVal = HXR_FAIL;

    if (pEvent)
    {
        // Set defaults
        pEvent->handled = FALSE;
        pEvent->result  = 0;
        // Switch based on event type
        switch (pEvent->event)
        {
            case HX_SURFACE_UPDATE:
                {
                    if (m_pSite)
                    {
                        // Get the site size
                        HXxSize cSize = {0,0};
                        m_pSite->GetSize(cSize);
                        // Create src and dst rects
                        HXxRect cSrcRect = {0, 0, m_ulImageWidth, m_ulImageHeight};
                        HXxRect cDstRect = {0, 0, cSize.cx,       cSize.cy};
                        // Get the video surface
                        IHXVideoSurface* pSurf = (IHXVideoSurface*) pEvent->param1;
                        if( pSurf && m_pOutputBuffer )
                        {
                            pSurf->AddRef();
                            // Blt to the surface
                            pSurf->Blt(m_pOutputBuffer->GetBuffer(),
                                       m_pBitmapInfoHeader,
                                       cDstRect,
                                       cSrcRect);
                            pSurf->Release();
                            pEvent->handled = TRUE;
                        }
                    }
                }
                break;

            default:
                break;
        }
        // Clear the return value
        retVal = HXR_OK;
    }

    return retVal;
}

STDMETHODIMP_(BOOL) CCommonImageRenderer::NeedsWindowedSites()
{
    return FALSE;
}

STDMETHODIMP CCommonImageRenderer::DecodeDone(HX_RESULT           status,
                                              HXBitmapInfoHeader* pHeader,
                                              IHXBuffer*          pBuffer)
{
    HX_RESULT retVal = HXR_FAIL;

    if (SUCCEEDED(status) && pHeader && pBuffer)
    {
        // Allocate an HXBitmapInfoHeader
        HX_DELETE(m_pBitmapInfoHeader);
        m_pBitmapInfoHeader = new HXBitmapInfoHeader;
        if (m_pBitmapInfoHeader)
        {
            // Copy the bitmap header
            memcpy(m_pBitmapInfoHeader, pHeader, sizeof(HXBitmapInfoHeader));
            // Save the buffer
            HX_RELEASE(m_pOutputBuffer);
            m_pOutputBuffer = pBuffer;
            m_pOutputBuffer->AddRef();
            // Clear the return value
            retVal = HXR_OK;
        }
        m_bDecodeComplete = TRUE;

        //If the HX_SURFACE_UPDATE event came in while we were still
        //waiting on the async decode then we need to blt now to
        //catch up.
        if( !m_bHasForceRedraw )
            _ForceRedraw();
    }

    return retVal;
}

void CCommonImageRenderer::_ForceRedraw()
{
    if( m_pSite )
    {
        HXxSize cSize = {0, 0};
        m_pSite->GetSize(cSize);
        HXxRect cRect = {0, 0, cSize.cx, cSize.cy};
        m_pSite->DamageRect(cRect);
        m_pSite->ForceRedraw();
        m_bHasForceRedraw = TRUE;
    }
}

HX_RESULT STDAPICALLTYPE CCommonImageRenderer::HXCreateInstance(IUnknown** ppIUnknown)
{
    HX_RESULT retVal = HXR_FAIL;

    if (ppIUnknown)
    {
        // Set default
        *ppIUnknown = NULL;
        // Create the object
        CCommonImageRenderer *pObj = new CCommonImageRenderer();
        if (pObj)
        {
            // QI for IUnknown
            retVal = pObj->QueryInterface(IID_IUnknown, (void**) ppIUnknown);
        }
        if (FAILED(retVal))
        {
            HX_DELETE(pObj);
        }
    }

    return retVal;
}

HX_RESULT CCommonImageRenderer::GenerateImageBuffer(CHXSimpleList*  pPacketList,
                                                    IHXValues*      pStreamHeader,
                                                    REF(IHXBuffer*) rpBuffer)
{
    HX_RESULT retVal = HXR_FAIL;

    // First run through and see how big a single buffer we need
    UINT32 ulTotal = SumCopyPacketList(pPacketList, pStreamHeader, NULL);
    if (ulTotal && m_pCommonClassFactory)
    {
        // Create the buffer
        IHXBuffer* pWholeBuffer = NULL;
        retVal = m_pCommonClassFactory->CreateInstance(CLSID_IHXBuffer,
                                                       (void**) &pWholeBuffer);
        if (SUCCEEDED(retVal))
        {
            // Set the size
            retVal = pWholeBuffer->SetSize(ulTotal);
            if (SUCCEEDED(retVal))
            {
                SumCopyPacketList(pPacketList, pStreamHeader, pWholeBuffer);
                // Set the out parameter
                HX_RELEASE(rpBuffer);
                rpBuffer = pWholeBuffer;
                rpBuffer->AddRef();
            }
        }
        HX_RELEASE(pWholeBuffer);
    }

    return retVal;
}

UINT32 CCommonImageRenderer::SumCopyPacketList(CHXSimpleList* pPacketList,
                                               IHXValues*     pStreamHeader,
                                               IHXBuffer*     pWholeBuffer)
{
    UINT32 ulRet = 0;

    if (pPacketList && pPacketList->GetCount() > 0 && pStreamHeader)
    {
        // Get the mime type
        IHXBuffer* pMimeTypeStr = NULL;
        pStreamHeader->GetPropertyCString("MimeType", pMimeTypeStr);
        if (pMimeTypeStr)
        {
            const char* pszMimeType = (const char*) pMimeTypeStr->GetBuffer();
            if (pszMimeType)
            {
                // Get the number of overhead bytes
                UINT32 ulOverheadBytes = 0;
                if (!strcmp(pszMimeType, IMAGE_MIMETYPE_JPEG_STREAMED))
                {
                    // 20 bytes of overhead in JPEG packetization
                    ulOverheadBytes = 20;
                }
                else if (!strcmp(pszMimeType, IMAGE_MIMETYPE_WBMP_STREAMED))
                {
                    // 4 bytes of overhead in WBMP packetization
                    ulOverheadBytes = 4;
                    // If we are the WBMP wire format (coming from
                    // the WBMP file format and not the unified
                    // file format), then we need to add the value
                    // of the opaque data.
                    IHXBuffer* pOpaque = NULL;
                    pStreamHeader->GetPropertyBuffer("OpaqueData", pOpaque);
                    if (pOpaque)
                    {
                        if (pWholeBuffer)
                        {
                            memcpy(pWholeBuffer->GetBuffer() + ulRet,
                                   pOpaque->GetBuffer(),
                                   pOpaque->GetSize());
                        }
                        ulRet += pOpaque->GetSize();
                    }
                    HX_RELEASE(pOpaque);
                }
                // Loop through the packets, either adding up
                // or copying or both
                LISTPOSITION pos = pPacketList->GetHeadPosition();
                while (pos)
                {
                    IHXPacket* pPacket = (IHXPacket*) pPacketList->GetNext(pos);
                    if (pPacket)
                    {
                        IHXBuffer* pBuffer = pPacket->GetBuffer();
                        if (pBuffer)
                        {
                            // Add up (and maybe copy) the actual
                            // bytes minus the overhead
                            if (pWholeBuffer)
                            {
                                memcpy(pWholeBuffer->GetBuffer() + ulRet,
                                       pBuffer->GetBuffer() + ulOverheadBytes,
                                       pBuffer->GetSize()   - ulOverheadBytes);
                            }
                            ulRet += pBuffer->GetSize() - ulOverheadBytes;
                        }
                        HX_RELEASE(pBuffer);
                    }
                }
            }
        }
        HX_RELEASE(pMimeTypeStr);
    }

    return ulRet;
}

void CCommonImageRenderer::ClearPacketList()
{
    if (m_pPacketList)
    {
        LISTPOSITION pos = m_pPacketList->GetHeadPosition();
        while (pos)
        {
            IHXPacket* pPacket = (IHXPacket*) m_pPacketList->GetNext(pos);
            HX_RELEASE(pPacket);
        }
        m_pPacketList->RemoveAll();
    }
}

HX_RESULT CCommonImageRenderer::ParseStreamHeader(IHXValues*      pHeader,
                                                  REF(UINT32)     rulImageWidth,
                                                  REF(UINT32)     rulImageHeight,
                                                  REF(IHXBuffer*) rpMimeTypeStr)
{
    HX_RESULT retVal = HXR_FAIL;

    if (pHeader)
    {
        // Get the mime type string buffer
        HX_RELEASE(rpMimeTypeStr);
        retVal = pHeader->GetPropertyCString("MimeType", rpMimeTypeStr);
        if (SUCCEEDED(retVal))
        {
            // Get the mime type string
            const char* pszMimeType = (const char*) rpMimeTypeStr->GetBuffer();
            // Get the opaque data
            IHXBuffer* pOpaque = NULL;
            pHeader->GetPropertyBuffer("OpaqueData", pOpaque);
            // Default the width and height
            rulImageWidth  = 0;
            rulImageHeight = 0;
            // Parse based on mime type
            if (!strcmp(pszMimeType, IMAGE_MIMETYPE_JPEG) ||
                !strcmp(pszMimeType, IMAGE_MIMETYPE_PNG)  ||
                !strcmp(pszMimeType, IMAGE_MIMETYPE_WBMP))
            {
                // This header came from unified fileformat
                pHeader->GetPropertyULONG32("ImageWidth",  rulImageWidth);
                pHeader->GetPropertyULONG32("ImageHeight", rulImageHeight);
            }
            else if (!strcmp(pszMimeType, IMAGE_MIMETYPE_PNG_STREAMED) ||
                     !strcmp(pszMimeType, IMAGE_MIMETYPE_JPEG_STREAMED))
            {
                if (pOpaque && pOpaque->GetSize() >= 8)
                {
                    BYTE* pBuf = (BYTE*) pOpaque->GetBuffer();
                    rulImageWidth  = (pBuf[0] << 24) | (pBuf[1] << 16) | (pBuf[2] << 8) | pBuf[3];
                    rulImageHeight = (pBuf[4] << 24) | (pBuf[5] << 16) | (pBuf[6] << 8) | pBuf[7];
                }
            }
            else if (!strcmp(pszMimeType, IMAGE_MIMETYPE_WBMP_STREAMED))
            {
                if (pOpaque)
                {
                    // Unpack the stream header
                    UINT32 ulHdrSize = 0;
                    ParseWBMPHeader((BYTE*) pOpaque->GetBuffer(),
                                    pOpaque->GetSize(),
                                    rulImageWidth,
                                    rulImageHeight,
                                    ulHdrSize);
                }
            }
            HX_RELEASE(pOpaque);
            if (!rulImageWidth || !rulImageHeight)
            {
                retVal = HXR_FAIL;
            }
        }
    }

    return retVal;
}

⌨️ 快捷键说明

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