📄 surface.cpp
字号:
/* ***** BEGIN LICENSE BLOCK *****
* Source last modified: $Id: surface.cpp,v 1.4.4.1 2004/07/09 01:59:28 hubbe Exp $
*
* Portions Copyright (c) 1995-2004 RealNetworks, Inc. All Rights Reserved.
*
* The contents of this file, and the files included with this file,
* are subject to the current version of the RealNetworks Public
* Source License (the "RPSL") available at
* http://www.helixcommunity.org/content/rpsl unless you have licensed
* the file under the current version of the RealNetworks Community
* Source License (the "RCSL") available at
* http://www.helixcommunity.org/content/rcsl, in which case the RCSL
* will apply. You may also obtain the license terms directly from
* RealNetworks. You may not use this file except in compliance with
* the RPSL or, if you have a valid RCSL with RealNetworks applicable
* to this file, the RCSL. Please see the applicable RPSL or RCSL for
* the rights, obligations and limitations governing use of the
* contents of the file.
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU General Public License Version 2 or later (the
* "GPL") in which case the provisions of the GPL are applicable
* instead of those above. If you wish to allow use of your version of
* this file only under the terms of the GPL, and not to allow others
* to use your version of this file under the terms of either the RPSL
* or RCSL, indicate your decision by deleting the provisions above
* and replace them with the notice and other provisions required by
* the GPL. If you do not delete the provisions above, a recipient may
* use your version of this file under the terms of any one of the
* RPSL, the RCSL or the GPL.
*
* This file is part of the Helix DNA Technology. RealNetworks is the
* developer of the Original Code and owns the copyrights in the
* portions it created.
*
* This file, and the files included with this file, is distributed
* and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY
* KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS
* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET
* ENJOYMENT OR NON-INFRINGEMENT.
*
* Technology Compatibility Kit Test Suite(s) Location:
* http://www.helixcommunity.org/content/tck
*
* Contributor(s):
*
* ***** END LICENSE BLOCK ***** */
#include "hxcom.h"
#include "hxtypes.h"
#include "hxmtypes.h"
#include "hxwintyp.h"
#include "chxxtype.h"
#include "hxwin.h"
#include "hxengin.h"
#include "hxcodec.h"
#include "hxalloc.h"
#ifdef _WINDOWS
#include "diballoc.h"
#ifdef _WIN32
#include <vfw.h>
#else
#include <drawdib.h>
#endif // _WIN32
#endif // _WINDOWS
//#include "color.h"
#include "coloracc.h"
#include "hxcolor.h"
#include "hxvctrl.h"
#include "hxvsurf.h"
#include "hxsite2.h"
#include "ihxpckts.h"
#include "surface.h"
#include "vidosurf.h"
#ifdef _WIN32
#include "fullsurf.h"
#endif // _WIN32
#include "sitewnd.h"
#include "mmx_util.h"
#ifndef WIDTHBYTES
#define WIDTHBYTES(i) ((unsigned long)((i+31)&(~31))/8)
#endif
#include "dbgtimer.h" // for blit time debugging
#include "hxheap.h"
#ifdef _DEBUG
#undef HX_THIS_FILE
static const char HX_THIS_FILE[] = __FILE__;
#endif
CHXSurface::CHXSurface(IUnknown* pContext, CHXSiteWindowed* pSite)
: m_lRefCount(0)
, m_pContext(pContext)
, m_pConverter(NULL)
, m_Brightness((float) DEF_BRIGHTNESS)
, m_Contrast((float) DEF_CONTRAST)
, m_Saturation((float) DEF_SATURATION)
, m_Hue((float) DEF_HUE)
, m_Sharpness((float) DEF_SHARPNESS)
, m_PrevBrightness((float) MAX_BRIGHTNESS)
, m_PrevContrast((float) MAX_CONTRAST)
, m_PrevSaturation((float) MAX_SATURATION)
, m_PrevSharpness((float) MAX_SHARPNESS)
, m_PrevHue((float) MAX_HUE)
, m_pSite(pSite)
, m_PreferredFormat(HXCOLOR_RGB3_ID)
, m_nBitDepth(32)
{
if (pContext)
{
pContext->AddRef();
}
#ifndef _WIN16
// Load color conversion library
m_pConverter = new ColorFuncAccess(m_pContext);
HX_ASSERT(m_pConverter);
if (!m_pConverter)
{
return;
}
m_pConverter->InitColorConverter();
#endif /* _WIN16 */
}
CHXSurface::~CHXSurface()
{
#ifndef _WIN16
if (m_pConverter)
{
delete m_pConverter;
m_pConverter = NULL;
}
#endif /* _WIN16 */
HX_RELEASE(m_pContext);
}
// *** IUnknown methods ***
/////////////////////////////////////////////////////////////////////////
// Method:
// IUnknown::QueryInterface
// Purpose:
// Implement this to export the interfaces supported by your
// object.
//
STDMETHODIMP
CHXSurface::QueryInterface(REFIID riid, void** ppvObj)
{
QInterfaceList qiList[] =
{
{ GET_IIDHANDLE(IID_IUnknown), this },
{ GET_IIDHANDLE(IID_IHXVideoSurface), (IHXVideoSurface*) this },
{ GET_IIDHANDLE(IID_IHXVideoControl), (IHXVideoControl*) this },
};
return ::QIFind(qiList, QILISTSIZE(qiList), riid, ppvObj);
}
/////////////////////////////////////////////////////////////////////////
// Method:
// IUnknown::AddRef
// Purpose:
// Everyone usually implements this the same... feel free to use
// this implementation.
//
STDMETHODIMP_(ULONG32)
CHXSurface::AddRef()
{
return InterlockedIncrement(&m_lRefCount);
}
/////////////////////////////////////////////////////////////////////////
// Method:
// IUnknown::Release
// Purpose:
// Everyone usually implements this the same... feel free to use
// this implementation.
//
STDMETHODIMP_(ULONG32)
CHXSurface::Release()
{
if (InterlockedDecrement(&m_lRefCount) > 0)
{
return m_lRefCount;
}
delete this;
return 0;
}
STDMETHODIMP
CHXSurface::Blt(UCHAR* pImageData,
HXBitmapInfoHeader* pBitmapInfo,
REF(HXxRect) inDestRect,
REF(HXxRect) inSrcRect)
{
//DebugTimer timer("CHXSurface::Blt");
#ifdef XXXBHG_TRACE_CODE
char szOut[256]; /* Flawfinder: ignore */
sprintf(szOut,"CHXSurface::Blt(%lx Dest[%d,%d,%d,%d] Src[%d,%d,%d,%d])\r\n",this, /* Flawfinder: ignore */
inDestRect.left,inDestRect.top,inDestRect.right,inDestRect.bottom,
inSrcRect.left,inSrcRect.top,inSrcRect.right,inSrcRect.bottom
);
OutputDebugString(szOut);
#endif
HX_RESULT hr = HXR_OK;
UCHAR* pNewImageData = NULL;
HXBitmapInfoHeader* pNewBitmapInfo = NULL;
BOOL bInterpolate = FALSE;
CHXxRect rDestRect = inDestRect;
CHXxRect rSrcRect = inSrcRect;
INT32 ulOldWidth = rSrcRect.Width();
INT32 ulOldHeight = rSrcRect.Height();
INT32 ulNewWidth = ulOldWidth;
INT32 ulNewHeight = ulOldHeight;
// This whole segment of code will be removed once we implement Yuriy's
// color converters for all Windows builds.
#ifndef _MACINTOSH
// Convert the data from YUV if necessary
if (pBitmapInfo->biCompression == HXCOLOR_YUV420_ID)
{
UCHAR* uBase = pImageData + (pBitmapInfo->biWidth * pBitmapInfo->biHeight);
UCHAR* vBase = uBase + ((pBitmapInfo->biWidth * pBitmapInfo->biHeight) / 4);
INT32 ulYOffset = (rSrcRect.top * pBitmapInfo->biWidth) + rSrcRect.left;
INT32 ulUVOffset = ((pBitmapInfo->biWidth * rSrcRect.top) / 4) + (rSrcRect.left / 2);
UCHAR* ySrc = pImageData + ulYOffset;
UCHAR* uSrc = uBase + ulUVOffset;
UCHAR* vSrc = vBase + ulUVOffset;
INT32 ulSrcPitch = pBitmapInfo->biWidth;
#ifdef _MACINTOSH
INT32 ulDstPitch = rSrcRect.Width();
#else
INT32 ulDstPitch = -rSrcRect.Width();
#endif
UINT16 nNewBitDepth = CalculateNewBitDepth(m_PreferredFormat);
INT32 ulSizeImage = WIDTHBYTES((rSrcRect.Width() * nNewBitDepth) * rSrcRect.Height());
bInterpolate = ((rSrcRect.Width()*2 == rDestRect.Width()) &&
(rSrcRect.Height()*2 == rDestRect.Height()));
if (bInterpolate)
{
#ifdef XXXBHG_TRACE_CODE
OutputDebugString("let's interpolate!\r\n");
#endif
ulNewWidth = rDestRect.Width();
ulNewHeight = rDestRect.Height();
ulSizeImage = WIDTHBYTES((rDestRect.Width() * nNewBitDepth) * rDestRect.Height());
#ifdef _MACINTOSH
ulDstPitch = rDestRect.Width();
#else
ulDstPitch = -rDestRect.Width();
#endif
}
pNewBitmapInfo = new HXBitmapInfoHeader();
pNewImageData = new UCHAR[ulSizeImage];
memcpy(pNewBitmapInfo, pBitmapInfo, sizeof(HXBitmapInfoHeader)); /* Flawfinder: ignore */
#ifdef XXXBHG_TRACE_CODE
OutputDebugString("color conversion!\r\n");
#endif
// Actually convert the data to RGB format
PerformYUVConversion(ySrc, uSrc, vSrc, ulSrcPitch, pNewImageData,
rSrcRect.Width(), rSrcRect.Height(),
ulDstPitch, m_PreferredFormat, bInterpolate);
// Adjust bitmap info header to account for conversion
pNewBitmapInfo->biWidth = ulNewWidth;
pNewBitmapInfo->biHeight = ulNewHeight;
pNewBitmapInfo->biSizeImage = ulSizeImage;
AdjustBitmapHeader(pNewBitmapInfo, m_PreferredFormat);
//Reset the src rect's origin so BltImageToDC() can go ahead and
// honor the source rect passed to it when calling DrawDibDraw(),
// SetDIBitsToDevice(), and StretchDIBits():
rSrcRect.left = 0;
rSrcRect.top = 0;
rSrcRect.right = ulNewWidth;
rSrcRect.bottom = ulNewHeight;
// Use the new data instead of that which was passed in
pBitmapInfo = pNewBitmapInfo;
pImageData = pNewImageData;
}
else if (pBitmapInfo->biCompression == HXCOLOR_RGB3_ID ||
pBitmapInfo->biCompression == HXCOLOR_RGB555_ID ||
pBitmapInfo->biCompression == HXCOLOR_RGB565_ID ||
pBitmapInfo->biCompression == HXCOLOR_RGB24_ID)
{
pNewBitmapInfo = new HXBitmapInfoHeader();
memcpy(pNewBitmapInfo, pBitmapInfo, sizeof(HXBitmapInfoHeader)); /* Flawfinder: ignore */
AdjustBitmapHeader(pNewBitmapInfo, pNewBitmapInfo->biCompression);
// Use the new data instead of that which was passed in
pBitmapInfo = pNewBitmapInfo;
}
if (bInterpolate)
{
// we also need to fake out the source size so things don't stretch
// further down the road.
rSrcRect.right = rSrcRect.left + ulNewWidth;
rSrcRect.bottom = rSrcRect.top + ulNewHeight;
}
#endif
// Call the platform dependent blitter
hr = BltImage(pImageData, pBitmapInfo, rDestRect, rSrcRect);
if (bInterpolate)
{
// we need to adjust back from our previous fake out
// so things don't freak out even more further down the road.
rSrcRect.right = rSrcRect.left + ulOldWidth;
rSrcRect.bottom = rSrcRect.top + ulOldHeight;
}
if (pNewImageData)
{
delete []pNewImageData;
pNewImageData = NULL;
}
if (pNewBitmapInfo)
{
delete pNewBitmapInfo;
pNewBitmapInfo = NULL;
}
return hr;
}
STDMETHODIMP
CHXSurface::BeginOptimizedBlt(HXBitmapInfoHeader* pBitmapInfo)
{
// Check for a bad header
HX_ASSERT(pBitmapInfo);
HX_ASSERT(pBitmapInfo->biSizeImage >= (pBitmapInfo->biWidth *
pBitmapInfo->biBitCount * pBitmapInfo->biHeight)/8);
if (!pBitmapInfo)
{
return HXR_FAIL;
}
if (pBitmapInfo->biCompression == HX_RGB ||
pBitmapInfo->biCompression == HX_BITFIELDS ||
pBitmapInfo->biCompression == HXCOLOR_RGB3_ID ||
pBitmapInfo->biCompression == HXCOLOR_RGB555_ID ||
pBitmapInfo->biCompression == HXCOLOR_RGB565_ID ||
pBitmapInfo->biCompression == HXCOLOR_RGB24_ID ||
pBitmapInfo->biCompression == HXCOLOR_8BIT_ID ||
pBitmapInfo->biCompression == HXCOLOR_YUV420_ID)
{
m_pSite->SetOptimizedFormat(pBitmapInfo);
return HXR_OK;
}
return HXR_FAIL;
}
STDMETHODIMP
CHXSurface::OptimizedBlt(UCHAR* pImageBits,
REF(HXxRect) rDestRect,
REF(HXxRect) rSrcRect)
{
//DebugTimer timer("CHXSurface::OptimizedBlt");
HXBitmapInfoHeader* pOptimizedFormat = m_pSite->GetOptimizedFormat();
HX_ASSERT(pOptimizedFormat);
if (!pOptimizedFormat)
{
return HXR_UNEXPECTED;
}
return Blt(pImageBits, pOptimizedFormat, rDestRect, rSrcRect);
}
STDMETHODIMP
CHXSurface::EndOptimizedBlt(void)
{
HXBitmapInfoHeader* pOptimizedFormat = m_pSite->GetOptimizedFormat();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -