📄 diballoc.cpp
字号:
/* ***** BEGIN LICENSE BLOCK *****
* Version: RCSL 1.0/RPSL 1.0
*
* Portions Copyright (c) 1995-2002 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
* Version 1.0 (the "RPSL") available at
* http://www.helixcommunity.org/content/rpsl unless you have licensed
* the file under the RealNetworks Community Source License Version 1.0
* (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.
*
* 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 "hxtypes.h"
#include <windows.h>
#include <windowsx.h>
#include "hxmap.h"
#include "hxassert.h"
#include "hxerrors.h"
#include "hxalloc.h"
#include "diballoc.h"
#include "hxheap.h"
///////////////////
// private data
#ifdef _DEBUG
#undef HX_THIS_FILE
static const char HX_THIS_FILE[] = __FILE__;
#endif
#ifdef _WIN32
CHXImageSample::CHXImageSample(CHXMemoryAllocator *pAllocator):
CHXMemoryBlock(pAllocator),
m_bInitialized(FALSE)
{
}
BOOL CHXImageSample::Allocate(ULONG32 uSize)
{
HX_ASSERT_VALID_PTR(m_pAllocator);
if (m_bInitialized && uSize <= m_DibData.bmiHeader.biSizeImage)
{
// Create a file mapping object and map into our address space
m_DibData.hMapping = CreateFileMapping((HANDLE)0xFFFFFFFF, // Use system page file
NULL, // No security attributes
PAGE_READWRITE, // Full access to memory
(DWORD) 0, // Less than 4Gb in size
uSize, // Size of buffer
NULL); // No name to section
if(m_DibData.hMapping != NULL)
{
m_DibData.hBitmap =
CreateDIBSection((HDC) NULL, // NO device context
(BITMAPINFO*)&m_DibData, // Format information
DIB_RGB_COLORS, // Use the palette
(VOID **) &m_pMemBuffer, // Pointer to image data
NULL, // Mapped memory handle
(DWORD) 0); // Offset into memory
}
if (m_pMemBuffer != NULL)
{
m_MemBufferSize = uSize;
// Initialise the DIB information structure
GetObject(m_DibData.hBitmap,sizeof(DIBSECTION), (VOID *)&m_DibData.DibSection);
return(TRUE);
}
}
// we consider it a improper to allocate with 0 size.
return(FALSE);
}
void CHXImageSample::Free()
{
HX_ASSERT_VALID_PTR(m_pMemBuffer);
if (m_pMemBuffer != NULL)
{
DeleteBitmap(m_DibData.hBitmap);
m_DibData.hBitmap = NULL;
CloseHandle(m_DibData.hMapping);
m_DibData.hMapping = NULL;
memset((char*)&m_DibData.DibSection, 0, sizeof(DIBSECTION));
m_pMemBuffer = NULL;
m_MemBufferSize = 0;
}
}
void CHXImageSample::SetDibData(DIBDATA* pDibData)
{
m_DibData = *pDibData;
m_bInitialized = TRUE;
}
DIBDATA* CHXImageSample::GetDibData()
{
return &m_DibData;
}
///////////////////////////////////////////////////////////////////////////////
// CHXDibSection Implementation
///////////////////////////////////////////////////////////////////////////////
CHXDibSectionAllocator::CHXDibSectionAllocator(BOOL bThreadSafe/*=FALSE*/):
CHXMemoryAllocator(bThreadSafe),
m_pbi(NULL)
{
}
CHXDibSectionAllocator::~CHXDibSectionAllocator()
{
if (m_pbi != NULL)
{
delete [] m_pbi;
m_pbi = NULL;
}
}
HX_RESULT
CHXDibSectionAllocator::SetProperties(HX20ALLOCPROPS* pRequest,
HX20ALLOCPROPS* pActual)
{
HX_RESULT theErr = HXR_OK;
if (m_bThreadSafe) EnterCriticalSection(&m_critsec);
// if we don't have a format set yet then we cannot
// set properties, otherwise if the requested size is less than or
// equal to the dib section memory size than allow it to succeed.
if (m_pbi != NULL && m_pbi->bmiHeader.biSizeImage >= pRequest->uBufferSize)
{
pActual->uBufferSize = m_pbi->bmiHeader.biSizeImage;
pActual->nNumBuffers = m_Count = pRequest->nNumBuffers;
}
else
{
pActual->uBufferSize = m_uSize;
pActual->nNumBuffers = m_Count;
}
if (m_bThreadSafe) LeaveCriticalSection(&m_critsec);
return(theErr);
}
HX_RESULT
CHXDibSectionAllocator::SetDibFormat(BITMAPINFO* pbi)
{
// if there are buffers allocated, then empyt the free list
// so we don't give anyone a buffer of the wrong size
if (m_AllocCount != 0)
{
if (!m_freeList.IsEmpty())
{
while(!m_freeList.IsEmpty())
{
CHXMemoryBlock * pMemBlock = (CHXMemoryBlock *)m_freeList.RemoveHead();
pMemBlock->Free();
delete pMemBlock;
m_AllocCount--;
}
}
}
// find out how big the bitmap info struct is
ULONG32 numColors;
switch (pbi->bmiHeader.biBitCount)
{
case 4: numColors = 16; break;
case 8: numColors = 256; break;
case 16: numColors = 3; break;
case 24: numColors = 0; break;
}
ULONG32 ulSize = sizeof(BITMAPINFO) + (numColors * sizeof(DWORD));
// get rid of the old one
delete [] m_pbi;
m_pbi = NULL;
// allocat a new one
m_pbi = (BITMAPINFO*)new UCHAR[ulSize];
if (m_pbi != NULL)
{
// set it's members up
memcpy(m_pbi, pbi, ulSize); /* Flawfinder: ignore */
// set the buffer size since the dib format defines the buffer size.
m_uSize = m_pbi->bmiHeader.biSizeImage;
return HXR_OK;
}
else
{
return HXR_OUTOFMEMORY;
}
}
UCHAR*
CHXDibSectionAllocator::GetPacketBuffer(IHXUnknown** pPacketBuffer)
{
HX_ASSERT_VALID_PTR(this);
HX_ASSERT_VALID_PTR(pPacketBuffer);
UCHAR * pRetVal = NULL;
*pPacketBuffer = NULL;
if (m_bThreadSafe) EnterCriticalSection(&m_critsec);
if (m_uSize > 0)
{
// Get the next free buffer from the buffer pool
if (!m_freeList.IsEmpty())
{
// Get the first buffer
CHXImageSample * pImageSample = (CHXImageSample *)m_freeList.RemoveHead();
// Add ref the block so we know we are using it
pImageSample->AddRef();
// setup the map so we don't loose the block
pRetVal = pImageSample->GetSampleBase();
m_MemBlockMap.SetAt(pRetVal, pImageSample);
*pPacketBuffer = (IHXUnknown *)pImageSample;
}
// if we didn't find any blocks in the list allocate a new one
if (pRetVal == NULL)
{
CHXImageSample * pImageSample = new CHXImageSample(this);
if (pImageSample != NULL)
{
DIBDATA dibData;
// find out how big the bitmap info struct is
ULONG32 numColors;
switch (m_pbi->bmiHeader.biBitCount)
{
case 4: numColors = 16; break;
case 8: numColors = 256; break;
case 16: numColors = 3; break;
case 24: numColors = 0; break;
}
ULONG32 ulSize = sizeof(BITMAPINFO) + (numColors * sizeof(DWORD));
memcpy(&dibData, m_pbi, ulSize); /* Flawfinder: ignore */
pImageSample->SetDibData(&dibData);
if (pImageSample->Allocate(m_uSize))
{
pImageSample->AddRef();
pRetVal = pImageSample->GetSampleBase();
m_MemBlockMap.SetAt(pRetVal, pImageSample);
m_AllocCount++;
*pPacketBuffer = (IHXUnknown *)pImageSample;
}
}
}
}
if (m_bThreadSafe) LeaveCriticalSection(&m_critsec);
return(pRetVal);
}
#endif /* _WIN32 */
CHXDIBits::CHXDIBits()
{
m_hDIB = NULL;
}
CHXDIBits::~CHXDIBits()
{
if (m_hDIB)
{
GlobalFree(m_hDIB);
m_hDIB = NULL;
}
}
HX_RESULT
CHXDIBits::GetDIBits(HDC hDC,
HBITMAP hBM,
UCHAR*& pBits,
BITMAPINFOHEADER*& pHeader)
{
HX_RESULT hr = HXR_OK;
WORD wBits = 0;
DWORD dwLen = 0;
BITMAP bm;
BITMAPINFOHEADER bi;
LPBITMAPINFOHEADER lpbi = NULL;
pBits = NULL;
pHeader = NULL;
if (!hDC || !hBM)
{
hr = HXR_FAILED;
goto cleanup;
}
GetObject(hBM, sizeof(bm), &bm);
wBits = (WORD)(bm.bmPlanes * bm.bmBitsPixel);
bi.biSize = sizeof(BITMAPINFOHEADER);
bi.biWidth = bm.bmWidth;
bi.biHeight = bm.bmHeight;
bi.biPlanes = 1;
bi.biBitCount = wBits;
bi.biCompression = BI_RGB;
bi.biSizeImage = WIDTHBYTES(bm.bmWidth * wBits) * bm.bmHeight;
bi.biXPelsPerMeter = 0;
bi.biYPelsPerMeter = 0;
bi.biClrUsed = 0;
bi.biClrImportant = 0;
dwLen = bi.biSize + DibNumColors(&bi) * sizeof(RGBQUAD) + bi.biSizeImage;
if (!m_hDIB)
{
m_hDIB = GlobalAlloc(GMEM_MOVEABLE, dwLen);
}
else if (m_hDIB && (GlobalSize(m_hDIB) != dwLen))
{
GlobalFree(m_hDIB);
m_hDIB = GlobalAlloc(GMEM_MOVEABLE, dwLen);
}
lpbi = (LPBITMAPINFOHEADER)GlobalLock(m_hDIB);
if (!lpbi)
{
// This is bad, it's not clear how callers of this class can
// really handle a failure case. So, we need to make sure that
// all our callers do handle this correctly.
HX_ASSERT(lpbi);
hr = HXR_FAILED;
goto cleanup;
}
*lpbi = bi;
::GetDIBits(hDC,
hBM,
0,
(WORD)bi.biHeight,
DibPtr(lpbi),
(LPBITMAPINFO)lpbi,
DIB_RGB_COLORS);
bi = *lpbi;
lpbi->biClrUsed = DibNumColors(lpbi);
pBits = (UCHAR*)DibPtr(lpbi);
pHeader = lpbi;
GlobalUnlock(m_hDIB);
cleanup:
return hr;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -