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