pxgifff.cpp

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

CPP
1,531
字号

STDMETHODIMP CGIFFileFormat::CloseDone(HX_RESULT status)
{
    return HXR_OK;
}

STDMETHODIMP CGIFFileFormat::WriteDone(HX_RESULT status)
{
    return HXR_UNEXPECTED;
}

void CGIFFileFormat::ReportError(UINT32 ulErrorID, const char* pszArg)
{
    // Try to get the string from the resource manager
    BYTE      ucSeverity = HXLOG_CRIT;
    HX_RESULT lRMACode   = HXR_FAIL;
    CHXString cErrStr;
    HX_RESULT retVal = GetResourceErrorString(ulErrorID, cErrStr);
    if (retVal != HXR_OK)
    {
        switch (ulErrorID)
        {
            case IDS_ERR_GIF_BADBITRATE:
                cErrStr = ERRSTR_GIF_BADBITRATE;
                break;
            case IDS_ERR_GIF_BADDURATION:
                cErrStr = ERRSTR_GIF_BADDURATION;
                break;
            case IDS_ERR_GIF_BADPREROLL:
                cErrStr = ERRSTR_GIF_BADPREROLL;
                break;
            case IDS_ERR_GIF_BADURL:
                cErrStr = ERRSTR_GIF_BADURL;
                break;
            case IDS_ERR_GIF_BADTARGET:
                cErrStr = ERRSTR_GIF_BADTARGET;
                break;
            case IDS_ERR_GIF_BADBGCOLOR:
                cErrStr = ERRSTR_GIF_BADBGCOLOR;
                break;
            case IDS_ERR_GIF_BADRELFLAG:
                cErrStr = ERRSTR_GIF_BADRELFLAG;
                break;
            case IDS_ERR_GIF_BITRATEZERO:
                cErrStr = ERRSTR_GIF_BITRATEZERO;
                break;
            case IDS_ERR_GIF_ILLEGALTARGET:
                cErrStr = ERRSTR_GIF_ILLEGALTARGET;
                break;
            case IDS_ERR_GIF_BADTIMEFORMAT:
                cErrStr = ERRSTR_GIF_BADTIMEFORMAT;
                break;
            case IDS_ERR_GIF_UNKPLAYERCOMMAND:
                cErrStr = ERRSTR_GIF_UNKPLAYERCOMMAND;
                break;
            case IDS_ERR_GIF_NOTARGETBROWSER:
                cErrStr = ERRSTR_GIF_NOTARGETBROWSER;
                break;
            case IDS_ERR_GIF_CORRUPTFILE:
                cErrStr = ERRSTR_GIF_CORRUPTFILE;
                break;
            default:
                cErrStr = ERRSTR_GIF_GENERALERROR;
                break;
        }
    }

    if (ulErrorID == IDS_ERR_GIF_CORRUPTFILE)
    {
        if (pszArg)
        {
            char* pszStr = new char [strlen((const char*) cErrStr) + strlen(pszArg) + 1];
            if (pszStr)
            {
                sprintf(pszStr, (const char*) cErrStr, pszArg); /* Flawfinder: ignore */
                cErrStr = pszStr;
            }
            HX_VECTOR_DELETE(pszStr);
            ucSeverity = HXLOG_DEBUG;
            lRMACode   = HXR_OK;
        }
    }
 
    if (m_pError)
    {
        m_pError->Report(ucSeverity, lRMACode, 0, (const char*) cErrStr,  NULL);
    }
}

HX_RESULT CGIFFileFormat::GetResourceErrorString(UINT32 ulErrorID, CHXString& rErrorStr)
{
    IHXExternalResourceManager* pResMgr = NULL;
    HX_RESULT retVal = m_pContext->QueryInterface(IID_IHXExternalResourceManager, (void**) &pResMgr);
    if (retVal != HXR_OK)
    {
        return retVal;
    }

	IHXExternalResourceReader* pResRdr = NULL;
    retVal = pResMgr->CreateExternalResourceReader(CORE_RESOURCE_SHORT_NAME, pResRdr);
    if (retVal != HXR_OK)
    {
        HX_RELEASE(pResMgr);
        return retVal;
    }

#ifdef _WINDOWS
    char szDLLPath[1024]; /* Flawfinder: ignore */
    GetModuleFileName((HMODULE)g_hInstance, szDLLPath, sizeof(szDLLPath));
    pResRdr->SetDefaultResourceFile(szDLLPath);
#endif

    IHXXResource* pRes = pResRdr->GetResource(HX_RT_STRING, ulErrorID);
    if(!pRes)
    {
        HX_RELEASE(pResRdr);
        HX_RELEASE(pResMgr);
        return HXR_FAIL;
    }

    // Assign the error string to the out parameter
    rErrorStr = (const char*) pRes->ResourceData();

    // Release all references
    HX_RELEASE(pRes);
    HX_RELEASE(pResRdr);
    HX_RELEASE(pResMgr);

    return HXR_OK;
}

HX_RESULT CGIFFileFormat::ParseFile()
{
    HX_RESULT retVal = HXR_OK;

    if (m_pFileObject && m_pFragFileBuffer)
    {
        // We don't need the file object anymore
        HX_RELEASE(m_pFileObject);

        // We need to get an IHXBuffer interface from the IHXFragmentedBuffer
        HX_RELEASE(m_pFileBuffer);
        retVal = m_pFragFileBuffer->QueryInterface(IID_IHXBuffer,
                                                   (void**) &m_pFileBuffer);
        if (SUCCEEDED(retVal))
        {
            // Get the buffer (this causes the initial gather)
            BYTE* pBuf = m_pFileBuffer->GetBuffer();
            if (pBuf)
            {
                // Get the size
                UINT32 ulBufSize = m_pFileBuffer->GetSize();

                // Now we allocate a CGIFCodec
                HX_DELETE(m_pGIFCodec);
                m_pGIFCodec = new CGIFCodec();
                if (m_pGIFCodec)
                {
                    // Initialize the wire format - this verifies this is a GIF
                    // and sets up for parsing
                    retVal = m_pGIFCodec->InitParseWireFormat(pBuf, ulBufSize);
                }
                else
                {
                    retVal = HXR_OUTOFMEMORY;
                }
            }
            else
            {
                retVal = HXR_FAIL;
            }
        }
        HX_RELEASE(m_pFragFileBuffer);
    }
    else
    {
        retVal = HXR_UNEXPECTED;
    }

    return retVal;
}

HX_RESULT CGIFFileFormat::MakeAllPackets()
{
    HX_RESULT retVal = HXR_OK;

    // We don't know how many packets we'll have up front, so we'll put
    // them on a list and move them to an array when we're done.
    CHXSimpleList* pList = new CHXSimpleList();
    if (pList)
    {
        // Loop through the packets
        while (SUCCEEDED(retVal) && !m_pGIFCodec->ParseFinished())
        {
            // Ask the CGIF Codec for the next size
            UINT32 ulLength = 0;
            retVal          = m_pGIFCodec->GetPacketBufferLength(ulLength);
            if (SUCCEEDED(retVal))
            {
                // Create buffer to hold the packet
                IHXBuffer* pBuffer = NULL;
                retVal              = m_pCommonClassFactory->CreateInstance(CLSID_IHXBuffer,
                                                                            (void**) &pBuffer);
                if (SUCCEEDED(retVal))
                {
                    // Set the size of the IHXBuffer
                    retVal = pBuffer->SetSize(ulLength + 4); // Extra 4 is for flags
                    if (SUCCEEDED(retVal))
                    {
                        // Get the packet from the CGIFCodec
                        BOOL bFirstInImage = FALSE;
                        retVal = m_pGIFCodec->GetPacketBuffer(pBuffer->GetBuffer() + 4,
                                                              pBuffer->GetSize()   - 4,
                                                              bFirstInImage);
                        if (SUCCEEDED(retVal))
                        {
                            // If this is a new image (and not the very first image), then update
                            // the current image index and the start time
                            if (bFirstInImage)
                            {
                                m_lCurImgIndex++;
                                if (m_lCurImgIndex >= 0 && m_lCurImgIndex < (INT32) m_pGIFCodec->GetNumImages())
                                {
                                    m_lCurrentTime = m_plImageStartTime[m_lCurImgIndex];
                                }
                                else
                                {
                                    retVal = HXR_UNEXPECTED;
                                }
                            }
                            if (SUCCEEDED(retVal))
                            {
                                // Set the flags
                                UINT32 ulFlags = 0;
                                if (bFirstInImage)
                                {
                                    ulFlags |= 0x01;
                                }
                                // Put the flags into the packet
                                BYTE *pBuf = pBuffer->GetBuffer();
                                Pack32(pBuf, ulFlags);
                                // Create an IHXPacket
                                IHXPacket* pPacket = NULL;
                                retVal              = m_pCommonClassFactory->CreateInstance(CLSID_IHXPacket,
                                                                                            (void**) &pPacket);
                                if (SUCCEEDED(retVal))
                                {
                                    INT32 lTimeStamp = m_lCurrentTime;
                                    if (lTimeStamp < 0)
                                    {
                                        lTimeStamp = 0;
                                    }
                                    // Fill in the Packet with the relevant data
                                    // XXX-MEH
                                    // This is a result of a client core bug which causes
                                    // the core not to deliver timestamps which are past the duration
                                    // of the stream. Specifically, it's causing animated GIFs whose
                                    // duration is set artificially low not to receive all their
                                    // packets. As a workaround, we set all GIF packet timestamps to 0.
                                    retVal = pPacket->Set(pBuffer,           // the actual data from the file
                                                          0,                 // timestamp
                                                          0,                 // our stream number (always 0)
                                                          HX_ASM_SWITCH_ON, // yes, we are using ASM (sort of)
                                                          0);                // always rule 0
                                    if (SUCCEEDED(retVal))
                                    {
                                        // Update the current timestamp
                                        m_lCurrentTime += ((pBuffer->GetSize() + 24) * 8000 / m_ulBitRate) + 1;
                                        // AddRef the packet before putting it on the list
                                        pPacket->AddRef();
                                        // Put this packet onto the tail of the list
                                        pList->AddTail((void*) pPacket);
                                    }
                                }
                                HX_RELEASE(pPacket);
                            }
                        }
                    }
                }
                HX_RELEASE(pBuffer);
            }
        }
    }
    else
    {
        retVal = HXR_OUTOFMEMORY;
    }

    // Terminate the parsing
    m_pGIFCodec->TermParse();
    // Now we can release the GIF codec
    HX_DELETE(m_pGIFCodec);
    // Release the file buffer
    HX_RELEASE(m_pFileBuffer);

    if (SUCCEEDED(retVal))
    {
        // Clear out any existing packets
        if (m_ppPacket && m_ulNumPackets)
        {
            for (UINT32 i = 0; i < m_ulNumPackets; i++)
            {
                HX_RELEASE(m_ppPacket[i]);
            }
            m_ulNumPackets = 0;
            HX_VECTOR_DELETE(m_ppPacket);
        }
        // Allocate the array
        m_ulNumPackets = pList->GetCount();
        m_ppPacket     = new IHXPacket* [m_ulNumPackets];
        if (m_ppPacket)
        {
            // Run through the list, transferring packet pointers to the array
            UINT32       i   = 0;
            LISTPOSITION pos = pList->GetHeadPosition();
            while (pos)
            {
                // No need to AddRef()/Release() since we know there's only one ref
                IHXPacket* pPacket = (IHXPacket*) pList->GetNext(pos);
                m_ppPacket[i++]     = pPacket;
            }
            // Now we can clear out the list
            pList->RemoveAll();
            // Reset the current packet index
            m_ulCurrentPacketIndex = 0;
        }
        else
        {
            retVal = HXR_OUTOFMEMORY;
        }
    }

    // Now we can delete the list
    HX_DELETE(pList);

    return retVal;
}

/************************************************************************
 *	Method:
 *	    IHXThreadSafeMethods::IsThreadSafe
 */
STDMETHODIMP_(UINT32)
CGIFFileFormat::IsThreadSafe()
{
    return HX_THREADSAFE_METHOD_FF_GETPACKET |
	HX_THREADSAFE_METHOD_FSR_READDONE;
}

HX_RESULT STDAPICALLTYPE CGIFFileFormat::HXCreateInstance(IUnknown** ppIUnknown)
{
    HX_RESULT retVal = HXR_OK;

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

    return HXR_OK;
}

⌨️ 快捷键说明

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