diballoc.cpp
上传用户:zhongxx05
上传日期:2007-06-06
资源大小:33641k
文件大小:10k
- /* ***** 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;
- }
-