📄 basesurf.cpp
字号:
BlockOut.right =
(int)((double)(BlockOut.right-m_pSite->m_topleft.x)/scaleX+.5);
BlockOut.bottom =
(int)((double)(BlockOut.bottom-m_pSite->m_topleft.y)/scaleY+.5);
// Ensure we start on even pixels (for yuv blending/conversion)
BlockOut.left &= ~1;
BlockOut.top &= ~1;
if( (BlockOut.right-BlockOut.left) & 1 )
{
BlockOut.right &= ~1;
}
if( (BlockOut.bottom-BlockOut.top) & 1 )
{
BlockOut.bottom &= ~1;
}
int nSizeX = BlockOut.right-BlockOut.left;
int nSizeY = BlockOut.bottom-BlockOut.top;
//Take care of odd number lines and pels that are
//not a multimple of four.
int nSizeOutX = (nSizeX+3)&~3;
int nSizeOutY = (nSizeY+1)&~1;
int nPSiteRectLeft =
(int)((double)(pReg->rects[nIdx].x1-pSite->m_topleft.x)/scaleX+.5);
int nPSiteRectTop =
(int)((double)(pReg->rects[nIdx].y1-pSite->m_topleft.y)/scaleY+.5);
//Now blend into the new buffer.
//Have to pass pointers to the actual pixel.
int nPImagePitch = GETBITMAPPITCH(&pImage->bmiImage);
int nPImageOutPitch = GETBITMAPPITCH(&pImageOut->bmiImage);
int nPImageDataPitch = nPImageOutPitch;
if( BlockOut.left+xx < 0)
xx = -BlockOut.left;
if( BlockOut.top+yy < 0)
yy = -BlockOut.top;
if( BlockOut.left+xx+nSizeX > pImageOut->bmiImage.biWidth )
xx -= 1;
if( BlockOut.top+yy+nSizeY > pImageOut->bmiImage.biHeight )
yy -= 1;
zm_pColorAcc->I420andYUVA(
//Botton YUV image
pImageOut->pucImage,
pImageOut->bmiImage.biWidth, pImageOut->bmiImage.biHeight,
nPImageDataPitch,
BlockOut.left+xx, BlockOut.top+yy,
//Top source YUVA Image
pImage->pucImage,
pImage->bmiImage.biWidth, pImage->bmiImage.biHeight,
nPImagePitch,
nPSiteRectLeft, nPSiteRectTop,
//Output Image
pImageOut->pucImage,
pImageOut->bmiImage.biWidth, pImageOut->bmiImage.biHeight,
nPImageOutPitch,
BlockOut.left+xx, BlockOut.top+yy,
nSizeX, nSizeY,
// Output color format.
CID_I420
);
//Now keep drawing up the line through all
//overlapping ARGB images.
pSite->m_pVideoSurface->_RecursiveYUVBlend( pImageOut,
boundingRect,
pSurface,
lXOffset+xx,
lYOffset+yy
);
}
}
}
return bRetVal;
}
BOOL CBaseSurface::_SetUpBlendRects( HXBitmapInfoHeader* pBitmapInfo,
UCHAR* pImageData)
{
BOOL bRetVal = FALSE;
CHXMapPtrToPtr::Iterator i;
//YUV optimized blending. We must blend 'up' the chain in this
//case. For each alpha notifier we have we must grab that sites
//YUVA buffer and blend it against ourselves.
CHXSimpleList::Iterator jj = m_imageBlocks.Begin();
HXDestroyRegion(m_pAdditionalColorKey);
m_pAdditionalColorKey = HXCreateRegion();
if( m_pSite->m_AlphaBlendNotifiers.GetCount()==0 )
{
m_bYUVBlending = FALSE;
return bRetVal;
}
for( i=m_pSite->m_AlphaBlendNotifiers.Begin() ;
i!=m_pSite->m_AlphaBlendNotifiers.End() ;
++i)
{
CHXBaseSite* pSite = (CHXBaseSite*)*i;
HXREGION* pReg = NULL;
//Find the region we need to blend with.
CHXMapPtrToPtr::Iterator j = pSite->m_AlphaBlendSites.Begin();
CHXBaseSite* pTmp = NULL;
while( j != pSite->m_AlphaBlendSites.End() && pTmp != m_pSite )
{
pTmp = (CHXBaseSite*)j.get_key();
if( pTmp == m_pSite )
{
pReg = (HXREGION*)*j;
break;
}
++j;
}
if( !pReg )
{
break;
}
//Find the YUVA buffer we need to blend against....
Image* pImage = NULL;
j = pSite->m_pVideoSurface->m_YUVAImageList.Begin();
pTmp = NULL;
while( j!=pSite->m_pVideoSurface->m_YUVAImageList.End() )
{
pTmp = (CHXBaseSite*)j.get_key();
if( pTmp == m_pSite )
{
pImage = (Image*)*j;
break;
}
++j;
}
//Now blend with this image....
if( pReg && pImage )
{
bRetVal = TRUE;
//blend by extents, blt by rects, and save for Blt().
for(int nIdx=0 ; nIdx<pReg->numRects ; nIdx++ )
{
//reuse the last imageblock....
ImageBlock* pBlockOut = NULL;
Image* pImageOut = NULL;
if( jj == m_imageBlocks.End() )
{
//We ran out of image blocks.
pBlockOut = new ImageBlock;
pImageOut = new Image;
memset( pImageOut, 0, sizeof(Image) );
memset( pBlockOut, 0, sizeof(ImageBlock) );
pBlockOut->pImage = pImageOut;
m_imageBlocks.AddTail((void*)pBlockOut);
jj = m_imageBlocks.End();
}
else
{
pBlockOut = (ImageBlock*)*jj;
++jj;
pImageOut = pBlockOut->pImage;
}
pBlockOut->pSrcSite = pSite;
//Downscale all rects....
double scaleX = 1;
double scaleY = 1;
scaleX = m_scaleFactorX/pSite->m_pVideoSurface->m_scaleFactorX;
scaleY = m_scaleFactorY/pSite->m_pVideoSurface->m_scaleFactorY;
pBlockOut->rect.left =
(int)((double)(pReg->rects[nIdx].x1-m_pSite->m_topleft.x)/scaleX+.5);
pBlockOut->rect.top =
(int)((double)(pReg->rects[nIdx].y1-m_pSite->m_topleft.y)/scaleY+.5);
pBlockOut->rect.right =
(int)((double)(pReg->rects[nIdx].x2-m_pSite->m_topleft.x)/scaleX+.5);
pBlockOut->rect.bottom =
(int)((double)(pReg->rects[nIdx].y2-m_pSite->m_topleft.y)/scaleY+.5);
// Ensure we start on even pixels (for yuv blending/conversion)
pBlockOut->rect.left &= ~1;
pBlockOut->rect.top &= ~1;
if( (pBlockOut->rect.right-pBlockOut->rect.left) & 1 )
{
pBlockOut->rect.right &= ~1;
}
if( (pBlockOut->rect.bottom-pBlockOut->rect.top) & 1 )
{
pBlockOut->rect.bottom &= ~1;
}
int nSizeX = pBlockOut->rect.right-pBlockOut->rect.left;
int nSizeY = pBlockOut->rect.bottom-pBlockOut->rect.top;
//Take care of odd number lines and pels that are
//not a multimple of four.
int nSizeOutX = (nSizeX+3)&~3;
int nSizeOutY = (nSizeY+1)&~1;
int nPSiteRectLeft =
(int)((double)(pReg->rects[nIdx].x1-pSite->m_topleft.x)/scaleX+.5);
int nPSiteRectTop =
(int)((double)(pReg->rects[nIdx].y1-pSite->m_topleft.y)/scaleY+.5);
pBlockOut->startX = nPSiteRectLeft;
pBlockOut->startY = nPSiteRectTop;
#ifdef _WIN32
int nResult = MakeBitmap( (LPBITMAPINFO)&(pImageOut->bmiImage),
sizeof(pImageOut->bmiImage),
CID_I420,
nSizeOutX,
nSizeOutY,
NULL,
0);
#else
int nResult = MakeBitmap( (HXBitmapInfo*)&(pImageOut->bmiImage),
sizeof(pImageOut->bmiImage),
CID_I420,
nSizeOutX,
nSizeOutY,
NULL,
0);
#endif
//Alloc it.
if( pImageOut->pucImage )
{
pImageOut->pucImage = (UCHAR*)
realloc( pImageOut->pucImage,
sizeof(UCHAR)*pImageOut->bmiImage.biSizeImage
);
}
else
{
pImageOut->pucImage = (UCHAR*)
malloc( sizeof(UCHAR)*pImageOut->bmiImage.biSizeImage);
}
if( pBitmapInfo && pImageData )
{
//Now blend into the new buffer.
//Have to pass pointers to the actual pixel.
int nPImageDataPitch = GETBITMAPPITCH(pBitmapInfo);
int nPImagePitch = GETBITMAPPITCH(&pImage->bmiImage);
int nPImageOutPitch = GETBITMAPPITCH(&pImageOut->bmiImage);
//Sanity check for rapid SetSize calls.
BOOL bDoIt =
nSizeX <= pImage->bmiImage.biWidth &&
nSizeY <= pImage->bmiImage.biHeight &&
nSizeX <= pBitmapInfo->biWidth &&
nSizeY <= pBitmapInfo->biHeight &&
pBlockOut->rect.right <= pBitmapInfo->biWidth &&
pBlockOut->rect.left <= pBitmapInfo->biWidth &&
pBlockOut->rect.bottom <= pBitmapInfo->biHeight &&
pBlockOut->rect.top <= pBitmapInfo->biHeight &&
pBlockOut->rect.right >=0 &&
pBlockOut->rect.left >=0 &&
pBlockOut->rect.bottom >=0 &&
pBlockOut->rect.top >=0 &&
nPSiteRectLeft >= 0 &&
nPSiteRectTop >= 0;
if( bDoIt )
{
zm_pColorAcc->I420andYUVA(
//Botton YUV image
pImageData,
pBitmapInfo->biWidth, pBitmapInfo->biHeight,
nPImageDataPitch,
pBlockOut->rect.left, pBlockOut->rect.top,
//Top source YUVA Image
pImage->pucImage,
pImage->bmiImage.biWidth, pImage->bmiImage.biHeight,
nPImagePitch,
nPSiteRectLeft, nPSiteRectTop,
//Output Image
pImageOut->pucImage,
pImageOut->bmiImage.biWidth, pImageOut->bmiImage.biHeight,
nPImageOutPitch,
0, 0,
nSizeX, nSizeY,
// Output color format.
CID_I420
);
//Now keep drawing up the line through all
//overlapping ARGB images.
pSite->m_pVideoSurface->_RecursiveYUVBlend( pImageOut,
pBlockOut->rect,
this, 0, 0);
}
}
}
if( m_imageBlocks.GetCount() )
{
//Save the last time we did a blend on this site. This is used to
//help keep animated images blended over paused or stopped YUV
//content because on YUV we blend from the bottom up.
m_ulLastBlendTime = HX_GET_BETTERTICKCOUNT();
}
//Merge the region to m_Region for the YUV image.
HXUnionRegion( m_pAdditionalColorKey, pReg, m_pAdditionalColorKey);
//Remove the region from the overlapping ARGB surface
//so it doesn't blt any more unless it changes.
if( pSite && pSite->m_Region )
HXSubtractRegion( pSite->m_Region, pReg, pSite->m_Region );
}
}
return bRetVal;
}
BOOL CBaseSurface::_AlphaSetupAndBlending(HXBitmapInfoHeader* pBitmapInfo,
UCHAR* pImageData,
HXxRect& rSrcRect,
HXxRect& rDestRect
)
{
BOOL bDoAlpha = FALSE;
CHXMapPtrToPtr::Iterator i;
if (!pImageData)
return bDoAlpha;
//Are borders being drawn?
INT32 nCID = GETBITMAPCOLOR(pBitmapInfo);
HX_ASSERT( m_pSite );
if( ( m_pucLastImage==NULL ||
m_bmiLastImage.biWidth!=m_pSite->m_size.cx ||
m_bmiLastImage.biHeight!=m_pSite->m_size.cy
) &&
(( m_pSite->_BordersActive() ||
m_pSite->_FadeTransitionActive() ||
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -