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 + -
显示快捷键?