📄 pxpngrnd.cpp
字号:
{ if (ulVal != m_ulMediaChromaKey) bUpdateNeeded = TRUE; m_ulMediaChromaKey = ulVal; m_bMediaChromaKeySpecified = TRUE; } else if (!strcmp(pName, "chromaKeyTolerance")) { if (ulVal != m_ulMediaChromaKeyTolerance) bUpdateNeeded = TRUE; m_ulMediaChromaKeyTolerance = ulVal; } else if (!strcmp(pName, "chromaKeyOpacity")) { if (ulVal > 255) ulVal = 255; if (ulVal != m_ulMediaChromaKeyOpacity) bUpdateNeeded = TRUE; m_ulMediaChromaKeyOpacity = ulVal; } // Did we change any of the above parameters? if (bUpdateNeeded) { // Have we done the initial display buffer update? // If we haven't, then we don't need to do anything, since // the initial display buffer update will capture all // of these transparency-related changes. if (m_bDecodeFinished) { // We have already done the initial display buffer update, // so we will need to re-blt the source image buffer // onto the display buffer using the new transparency // parameters which were just updated. This is probably // the case when one of our transparency-related parameters // is getting animated in SMIL. UpdateDisplayBuffer(); } } // Now pass it off to our grandparent class retVal = CRNBaseRenderer::SetPropertyULONG32(pName, ulVal); } else { retVal = HXR_FAIL; } return retVal;}STDMETHODIMP PXPNGRenderer::SetPropertyCString(const char* pName, IHXBuffer* pVal){ HX_RESULT retVal = HXR_FAIL; if (m_pValues) { // Check for the default SMIL namespace BOOL bUpdateNeeded = FALSE; if (!strcmp(pName, "SMILDefaultNamespace")) { if (m_ulBackgroundOpacity != 0) { bUpdateNeeded = TRUE; // Update the background color m_ulBackgroundColor = (m_ulBackgroundColor & 0x00FFFFFF) | 0xFF000000; } m_ulBackgroundOpacity = 0; } // Do we need to update the display buffer if (bUpdateNeeded) { // Have we done the initial display buffer update? // If we haven't, then we don't need to do anything, since // the initial display buffer update will capture all // of these transparency-related changes. if (m_bDecodeFinished) { // We have already done the initial display buffer update, // so we will need to re-blt the source image buffer // onto the display buffer using the new transparency // parameters which were just updated. This is probably // the case when one of our transparency-related parameters // is getting animated in SMIL. UpdateDisplayBuffer(); } } // Now pass it off to our grandparent class retVal = CRNBaseRenderer::SetPropertyCString(pName, pVal); } return retVal;}HX_RESULT STDAPICALLTYPE PXPNGRenderer::HXCreateInstance(IUnknown** ppIUnknown){ HX_RESULT retVal = HXR_OK; if (ppIUnknown) { // Set default *ppIUnknown = NULL; // Create the object PXPNGRenderer *pObj = new PXPNGRenderer(); 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;}void PXPNGRenderer::DoTransparencyBlt(IHXBuffer* pSrc, IHXBuffer* pDst, BOOL bImageUsesAlphaChannel, UINT32 ulBackgroundColor, UINT32 ulMediaOpacity, BOOL bMediaChromaKeySpecified, UINT32 ulMediaChromaKey, UINT32 ulMediaChromaKeyTolerance, UINT32 ulMediaChromaKeyOpacity, REF(BOOL) rbDisplayUsesAlphaChannel){ if (pSrc && pDst) { // Get the buffer pointers and the number // of 32bpp pixels in each buffer UINT32* pSrcPix = (UINT32*) pSrc->GetBuffer(); UINT32* pDstPix = (UINT32*) pDst->GetBuffer(); UINT32 ulNumSrcPix = pSrc->GetSize() >> 2; UINT32 ulNumDstPix = pDst->GetSize() >> 2; if (pSrcPix && pDstPix && ulNumSrcPix > 0 && ulNumSrcPix == ulNumDstPix) { // Initially set the display alpha channel // flag to FALSE rbDisplayUsesAlphaChannel = FALSE; // Is the background transparent? BOOL bBgTransparent = (ARGB32_ALPHA(ulBackgroundColor) == 255 ? TRUE : FALSE); // Compute the chroma alpha with pre-shift UINT32 ulChromaAlpha = 0; if (bMediaChromaKeySpecified) { if (ulMediaChromaKeyOpacity > 255) ulMediaChromaKeyOpacity = 255; ulChromaAlpha = (255 - ulMediaChromaKeyOpacity) << 24; } // Run through the pixels // XXXMEH - optimization // We can and should break out a few of these cases into // separate loops which don't have any conditional checks // in them (for instance, the straight copy). The compiler // should be able to optimize these uncluttered loops much // better than the one-size-fits-all loop below. while (ulNumSrcPix--) { // Get the src pixel UINT32 ulSrcPix = *pSrcPix++; // First apply the chroma key if (bMediaChromaKeySpecified) { if (DoesChromaKeyMatch(ulSrcPix, ulMediaChromaKey, ulMediaChromaKeyTolerance)) { ulSrcPix = (ulSrcPix & 0x00FFFFFF) | ulChromaAlpha; } } // Next apply the media opacity if (ulMediaOpacity < 255) { UINT32 ulAlpha = ARGB32_ALPHA(ulSrcPix); UINT32 ulOpacity = 255 - ulAlpha; UINT32 ulNewOpacity = ulOpacity * ulMediaOpacity / 255; UINT32 ulNewAlpha = 255 - ulNewOpacity; ulSrcPix = (ulSrcPix & 0x00FFFFFF) | (ulNewAlpha << 24); } // Now alpha blend onto the background color // Note that we only need to do this if the background // is not fully transparent, because if the background // is fully transparent, is has no effect whatsoever. // If this pixel is opaque, then we don't need to // do anything here, since the opaque pixel will // completely occlude the background color if (!bBgTransparent && (ulSrcPix & 0xFF000000)) { UINT32 ulAM = ARGB32_ALPHA(ulSrcPix); UINT32 ulAB = ARGB32_ALPHA(ulBackgroundColor); UINT32 ulDen = (65535 - ulAM * ulAB); UINT32 ulNumL = ulAM * (255 - ulAB); UINT32 ulNumR = 255 * (255 - ulAM); UINT32 ulRed = (ulNumL * ARGB32_RED(ulBackgroundColor) + ulNumR * ARGB32_RED(ulSrcPix)) / ulDen; UINT32 ulGreen = (ulNumL * ARGB32_GREEN(ulBackgroundColor) + ulNumR * ARGB32_GREEN(ulSrcPix)) / ulDen; UINT32 ulBlue = (ulNumL * ARGB32_BLUE(ulBackgroundColor) + ulNumR * ARGB32_BLUE(ulSrcPix)) / ulDen; UINT32 ulAlpha = ulAM * ulAB / 255; ulSrcPix = ((ulAlpha << 24) & 0xFF000000) | ((ulRed << 16) & 0x00FF0000) | ((ulGreen << 8) & 0x0000FF00) | ( ulBlue & 0x000000FF); } // Check the final alpha value if (ulSrcPix & 0xFF000000) { rbDisplayUsesAlphaChannel = TRUE; } // Assign the dst pixel *pDstPix++ = ulSrcPix; } } }}HX_RESULT PXPNGRenderer::UpdateDisplayBuffer(){ HX_RESULT retVal = HXR_OK; if (m_pImage && m_pDisplayImage) { // Get the image store of the decoded image IHXBuffer* pSrc = NULL; retVal = m_pImage->GetImageStore(&pSrc); if (SUCCEEDED(retVal)) { // Get the image store of the display image IHXBuffer* pDst = NULL; retVal = m_pDisplayImage->GetImageStore(&pDst); if (SUCCEEDED(retVal)) { // Process any transparency parameters DoTransparencyBlt(pSrc, pDst, m_bImageUsesAlphaChannel, m_ulBackgroundColor, m_ulMediaOpacity, m_bMediaChromaKeySpecified, m_ulMediaChromaKey, m_ulMediaChromaKeyTolerance, m_ulMediaChromaKeyOpacity, m_bDisplayUsesAlphaChannel); } HX_RELEASE(pDst); } HX_RELEASE(pSrc); } else { retVal = HXR_FAIL; } return retVal;}void PXPNGRenderer::_AttachSite(){ //Lets subscribe to the sub rect messages, HX_SURFACE_UPDATE2. IHXSubRectSite* pSubRectSite = NULL; m_pSite->QueryInterface(IID_IHXSubRectSite, (void**)&pSubRectSite); if( pSubRectSite ) { //If so, since IHXSubRectSite inheirits from IHXSite, lets //just swap the pointers and sign up for the service. HX_RELEASE( m_pSite ); m_pSite = pSubRectSite; pSubRectSite->SendSubRectMessages(TRUE); }}STDMETHODIMP PXPNGRenderer::GetName(REF(const char*) rpszName){ rpszName = (const char*) m_pszName; return HXR_OK;}STDMETHODIMP PXPNGRenderer::GetDescription(REF(const char*) rpszDescription){ rpszDescription = (const char*) m_pszDescription; return HXR_OK;}STDMETHODIMP PXPNGRenderer::GetMimeTypes(REF(const char**) rppszMimeType){ rppszMimeType = (const char**) m_ppszMimeType; return HXR_OK;}STDMETHODIMP_(UINT32) PXPNGRenderer::GetPluginVersion(){ return TARVER_ULONG32_VERSION;}STDMETHODIMP_(UINT32) PXPNGRenderer::GetInitialGranularity(){ return 200;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -