diballoc.cpp
上传用户:zhongxx05
上传日期:2007-06-06
资源大小:33641k
文件大小:10k
源码类别:

Symbian

开发平台:

C/C++

  1. /* ***** BEGIN LICENSE BLOCK ***** 
  2.  * Version: RCSL 1.0/RPSL 1.0 
  3.  *  
  4.  * Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved. 
  5.  *      
  6.  * The contents of this file, and the files included with this file, are 
  7.  * subject to the current version of the RealNetworks Public Source License 
  8.  * Version 1.0 (the "RPSL") available at 
  9.  * http://www.helixcommunity.org/content/rpsl unless you have licensed 
  10.  * the file under the RealNetworks Community Source License Version 1.0 
  11.  * (the "RCSL") available at http://www.helixcommunity.org/content/rcsl, 
  12.  * in which case the RCSL will apply. You may also obtain the license terms 
  13.  * directly from RealNetworks.  You may not use this file except in 
  14.  * compliance with the RPSL or, if you have a valid RCSL with RealNetworks 
  15.  * applicable to this file, the RCSL.  Please see the applicable RPSL or 
  16.  * RCSL for the rights, obligations and limitations governing use of the 
  17.  * contents of the file.  
  18.  *  
  19.  * This file is part of the Helix DNA Technology. RealNetworks is the 
  20.  * developer of the Original Code and owns the copyrights in the portions 
  21.  * it created. 
  22.  *  
  23.  * This file, and the files included with this file, is distributed and made 
  24.  * available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 
  25.  * EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES, 
  26.  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS 
  27.  * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 
  28.  * 
  29.  * Technology Compatibility Kit Test Suite(s) Location: 
  30.  *    http://www.helixcommunity.org/content/tck 
  31.  * 
  32.  * Contributor(s): 
  33.  *  
  34.  * ***** END LICENSE BLOCK ***** */ 
  35. #include "hxtypes.h"
  36. #include <windows.h>
  37. #include <windowsx.h>
  38. #include "hxmap.h"
  39. #include "hxassert.h"
  40. #include "hxerrors.h"
  41. #include "hxalloc.h"
  42. #include "diballoc.h"
  43. #include "hxheap.h"
  44. ///////////////////
  45. // private data
  46. #ifdef _DEBUG
  47. #undef HX_THIS_FILE
  48. static const char HX_THIS_FILE[] = __FILE__;
  49. #endif
  50. #ifdef _WIN32
  51. CHXImageSample::CHXImageSample(CHXMemoryAllocator *pAllocator):
  52. CHXMemoryBlock(pAllocator),
  53. m_bInitialized(FALSE)
  54. {
  55. }
  56. BOOL CHXImageSample::Allocate(ULONG32 uSize)
  57. {
  58.     HX_ASSERT_VALID_PTR(m_pAllocator);
  59.     if (m_bInitialized && uSize <= m_DibData.bmiHeader.biSizeImage)
  60.     {
  61. // Create a file mapping object and map into our address space
  62. m_DibData.hMapping = CreateFileMapping((HANDLE)0xFFFFFFFF, // Use system page file
  63. NULL, // No security attributes
  64. PAGE_READWRITE, // Full access to memory
  65. (DWORD) 0, // Less than 4Gb in size
  66. uSize, // Size of buffer
  67. NULL); // No name to section
  68. if(m_DibData.hMapping != NULL)
  69. {
  70.     m_DibData.hBitmap = 
  71. CreateDIBSection((HDC) NULL, // NO device context
  72. (BITMAPINFO*)&m_DibData, // Format information
  73. DIB_RGB_COLORS, // Use the palette
  74. (VOID **) &m_pMemBuffer, // Pointer to image data
  75. NULL, // Mapped memory handle
  76. (DWORD) 0); // Offset into memory
  77. }
  78. if (m_pMemBuffer != NULL)
  79. {
  80.     m_MemBufferSize = uSize;
  81.     // Initialise the DIB information structure
  82.     GetObject(m_DibData.hBitmap,sizeof(DIBSECTION), (VOID *)&m_DibData.DibSection);
  83.     
  84.     return(TRUE);
  85. }
  86.     }
  87.     // we consider it a improper to allocate with 0 size.
  88.     return(FALSE);
  89. }
  90. void CHXImageSample::Free()
  91. {
  92.     HX_ASSERT_VALID_PTR(m_pMemBuffer);
  93.     if (m_pMemBuffer != NULL)
  94.     {
  95. DeleteBitmap(m_DibData.hBitmap);
  96. m_DibData.hBitmap = NULL;
  97. CloseHandle(m_DibData.hMapping);
  98. m_DibData.hMapping = NULL;
  99. memset((char*)&m_DibData.DibSection, 0, sizeof(DIBSECTION));
  100. m_pMemBuffer = NULL;
  101. m_MemBufferSize = 0;
  102.     }
  103. }
  104. void CHXImageSample::SetDibData(DIBDATA* pDibData)
  105. {
  106.     m_DibData = *pDibData;
  107.     m_bInitialized = TRUE;
  108. }
  109. DIBDATA* CHXImageSample::GetDibData()
  110. {
  111.     return &m_DibData;
  112. }
  113. ///////////////////////////////////////////////////////////////////////////////
  114. // CHXDibSection Implementation
  115. ///////////////////////////////////////////////////////////////////////////////
  116. CHXDibSectionAllocator::CHXDibSectionAllocator(BOOL bThreadSafe/*=FALSE*/):
  117.     CHXMemoryAllocator(bThreadSafe),
  118.     m_pbi(NULL)
  119. {
  120. }
  121. CHXDibSectionAllocator::~CHXDibSectionAllocator()
  122. {
  123.     if (m_pbi != NULL)
  124.     {
  125. delete [] m_pbi;
  126. m_pbi = NULL;
  127.     }
  128. }
  129. HX_RESULT
  130. CHXDibSectionAllocator::SetProperties(HX20ALLOCPROPS* pRequest, 
  131.     HX20ALLOCPROPS* pActual)
  132. {
  133.     HX_RESULT theErr = HXR_OK;
  134.     if (m_bThreadSafe) EnterCriticalSection(&m_critsec);
  135.     // if we don't have a format set yet then we cannot
  136.     // set properties, otherwise if the requested size is less than or
  137.     // equal to the dib section memory size than allow it to succeed.
  138.     if (m_pbi != NULL && m_pbi->bmiHeader.biSizeImage >= pRequest->uBufferSize)
  139.     {
  140. pActual->uBufferSize = m_pbi->bmiHeader.biSizeImage;
  141. pActual->nNumBuffers = m_Count = pRequest->nNumBuffers;
  142.     }
  143.     else
  144.     {
  145. pActual->uBufferSize = m_uSize;
  146. pActual->nNumBuffers = m_Count;
  147.     }
  148.     if (m_bThreadSafe) LeaveCriticalSection(&m_critsec);
  149.     return(theErr);
  150. }
  151. HX_RESULT 
  152. CHXDibSectionAllocator::SetDibFormat(BITMAPINFO* pbi)
  153. {
  154.     // if there are buffers allocated, then empyt the free list 
  155.     // so we don't give anyone a buffer of the wrong size
  156.     if (m_AllocCount != 0)
  157.     {
  158. if (!m_freeList.IsEmpty())
  159. {
  160.     while(!m_freeList.IsEmpty())
  161.     {
  162. CHXMemoryBlock * pMemBlock = (CHXMemoryBlock *)m_freeList.RemoveHead();
  163. pMemBlock->Free();
  164. delete pMemBlock;
  165. m_AllocCount--;
  166.     }
  167. }
  168.     }
  169.     // find out how big the bitmap info struct is
  170.     ULONG32 numColors;
  171.     switch (pbi->bmiHeader.biBitCount)
  172.     {
  173. case 4: numColors = 16; break;
  174. case 8: numColors = 256; break;
  175. case 16: numColors = 3; break;
  176. case 24: numColors = 0; break;
  177.     }
  178.     ULONG32 ulSize = sizeof(BITMAPINFO) + (numColors * sizeof(DWORD));
  179.     // get rid of the old one
  180.     delete [] m_pbi;
  181.     m_pbi = NULL;
  182.     // allocat a new one
  183.     m_pbi = (BITMAPINFO*)new UCHAR[ulSize];
  184.     
  185.     if (m_pbi != NULL)
  186.     {
  187. // set it's members up 
  188. memcpy(m_pbi, pbi, ulSize); /* Flawfinder: ignore */
  189. // set the buffer size since the dib format defines the buffer size.
  190. m_uSize = m_pbi->bmiHeader.biSizeImage;
  191. return HXR_OK;
  192.     }
  193.     else
  194.     {
  195. return HXR_OUTOFMEMORY;
  196.     }
  197. }
  198. UCHAR* 
  199. CHXDibSectionAllocator::GetPacketBuffer(IHXUnknown** pPacketBuffer)
  200. {
  201.     HX_ASSERT_VALID_PTR(this);
  202.     HX_ASSERT_VALID_PTR(pPacketBuffer);
  203.     UCHAR * pRetVal = NULL;
  204.     *pPacketBuffer = NULL;
  205.     
  206.     if (m_bThreadSafe) EnterCriticalSection(&m_critsec);
  207.     if (m_uSize > 0)
  208.     {
  209. // Get the next free buffer from the buffer pool
  210. if (!m_freeList.IsEmpty())
  211. {
  212.     // Get the first buffer
  213.     CHXImageSample * pImageSample = (CHXImageSample *)m_freeList.RemoveHead();
  214.     
  215.     // Add ref the block so we know we are using it
  216.     pImageSample->AddRef();
  217.     
  218.     // setup the map so we don't loose the block
  219.     pRetVal = pImageSample->GetSampleBase();
  220.     m_MemBlockMap.SetAt(pRetVal, pImageSample);
  221.     *pPacketBuffer = (IHXUnknown *)pImageSample;
  222. }
  223. // if we didn't find any blocks in the list allocate a new one
  224. if (pRetVal == NULL)
  225. {
  226.     CHXImageSample * pImageSample = new CHXImageSample(this);
  227.     if (pImageSample != NULL)
  228.     {
  229. DIBDATA dibData;
  230. // find out how big the bitmap info struct is
  231. ULONG32 numColors;
  232. switch (m_pbi->bmiHeader.biBitCount)
  233. {
  234. case 4: numColors = 16; break;
  235. case 8: numColors = 256; break;
  236. case 16: numColors = 3; break;
  237. case 24: numColors = 0; break;
  238. }
  239. ULONG32 ulSize = sizeof(BITMAPINFO) + (numColors * sizeof(DWORD));
  240. memcpy(&dibData, m_pbi, ulSize); /* Flawfinder: ignore */
  241. pImageSample->SetDibData(&dibData);
  242. if (pImageSample->Allocate(m_uSize))
  243. {
  244. pImageSample->AddRef();
  245. pRetVal = pImageSample->GetSampleBase();
  246. m_MemBlockMap.SetAt(pRetVal, pImageSample);
  247. m_AllocCount++;
  248. *pPacketBuffer = (IHXUnknown *)pImageSample;
  249. }
  250.     }
  251. }
  252.     }
  253.     if (m_bThreadSafe) LeaveCriticalSection(&m_critsec);
  254.     return(pRetVal);
  255. }
  256. #endif /* _WIN32 */
  257. CHXDIBits::CHXDIBits()
  258. {
  259.     m_hDIB = NULL;
  260. }
  261. CHXDIBits::~CHXDIBits()
  262. {
  263.     if (m_hDIB)
  264.     {
  265. GlobalFree(m_hDIB);
  266. m_hDIB = NULL;
  267.     }
  268. }
  269. HX_RESULT
  270. CHXDIBits::GetDIBits(HDC hDC,
  271.      HBITMAP hBM,
  272.      UCHAR*& pBits,
  273.      BITMAPINFOHEADER*& pHeader)
  274. {
  275.     HX_RESULT hr = HXR_OK;
  276.     WORD wBits = 0;
  277.     DWORD    dwLen = 0;
  278.     BITMAP bm;
  279.     BITMAPINFOHEADER bi;
  280.     LPBITMAPINFOHEADER lpbi = NULL;
  281.  
  282.     pBits = NULL;
  283.     pHeader = NULL;
  284.     if (!hDC || !hBM)
  285.     {
  286. hr = HXR_FAILED;
  287. goto cleanup;
  288.     }
  289.     GetObject(hBM, sizeof(bm), &bm);
  290.     wBits = (WORD)(bm.bmPlanes * bm.bmBitsPixel);
  291.   
  292.     bi.biSize = sizeof(BITMAPINFOHEADER);
  293.     bi.biWidth = bm.bmWidth;
  294.     bi.biHeight = bm.bmHeight;
  295.     bi.biPlanes = 1;
  296.     bi.biBitCount = wBits;
  297.     bi.biCompression = BI_RGB;
  298.     bi.biSizeImage = WIDTHBYTES(bm.bmWidth * wBits) * bm.bmHeight;
  299.     bi.biXPelsPerMeter = 0;
  300.     bi.biYPelsPerMeter  = 0;
  301.     bi.biClrUsed = 0;
  302.     bi.biClrImportant = 0;
  303.     dwLen = bi.biSize + DibNumColors(&bi) * sizeof(RGBQUAD) + bi.biSizeImage;
  304.     if (!m_hDIB)
  305.     {
  306. m_hDIB = GlobalAlloc(GMEM_MOVEABLE, dwLen);
  307.     }
  308.     else if (m_hDIB && (GlobalSize(m_hDIB) != dwLen))
  309.     {
  310. GlobalFree(m_hDIB);
  311. m_hDIB = GlobalAlloc(GMEM_MOVEABLE, dwLen);
  312.     }
  313.     lpbi = (LPBITMAPINFOHEADER)GlobalLock(m_hDIB);
  314.     if (!lpbi)
  315.     {
  316. // This is bad, it's not clear how callers of this class can
  317. // really handle a failure case. So, we need to make sure that
  318. // all our callers do handle this correctly.
  319. HX_ASSERT(lpbi);
  320. hr = HXR_FAILED;
  321. goto cleanup;
  322.     }
  323.     *lpbi = bi;
  324.     ::GetDIBits(hDC,
  325.       hBM,
  326.       0,
  327.       (WORD)bi.biHeight,
  328.       DibPtr(lpbi),
  329.       (LPBITMAPINFO)lpbi,
  330.       DIB_RGB_COLORS);
  331.     bi = *lpbi;
  332.     lpbi->biClrUsed = DibNumColors(lpbi);
  333.     pBits = (UCHAR*)DibPtr(lpbi);
  334.     pHeader = lpbi;
  335.     GlobalUnlock(m_hDIB);
  336. cleanup:
  337.     
  338.     return hr;
  339. }
  340.