From b4324c3d3ee5e27c271a4965680d3bf1fee81827 Mon Sep 17 00:00:00 2001 From: Willem Jan Palenstijn Date: Tue, 22 Apr 2014 14:15:59 +0000 Subject: Add CustomMemory interface to Float32Data2D --- include/astra/Float32Data2D.h | 42 ++++++++++++++++++++++++ src/Float32Data2D.cpp | 75 ++++++++++++++++++++++++++++++++++++++----- 2 files changed, 109 insertions(+), 8 deletions(-) diff --git a/include/astra/Float32Data2D.h b/include/astra/Float32Data2D.h index 062feb5..c5d2c70 100644 --- a/include/astra/Float32Data2D.h +++ b/include/astra/Float32Data2D.h @@ -34,6 +34,13 @@ $Id$ namespace astra { + +class _AstraExport CFloat32CustomMemory { +public: + virtual ~CFloat32CustomMemory()=0; + float32* m_fPtr; +}; + /** * This class represents a two-dimensional block of float32ing point data. * It contains member functions for accessing this data and for performing @@ -141,6 +148,23 @@ protected: */ bool _initialize(int _iWidth, int _iHeight, float32 _fScalar); + /** Initialization. Initializes an instance of the CFloat32Data2D class with pre-allocated memory. + * Can only be called by derived classes. + * + * Initializes an instance of the CFloat32Data2D class. Memory + * is pre-allocated and passed via the abstract CFloat32CustomMemory handle + * class. The handle will be deleted when the memory can be freed. + * You should override the destructor to provide custom behaviour on free. + * If the object has been initialized before, the + * object is reinitialized and memory is freed and reallocated if necessary. + * This function does not set m_bInitialized to true if everything is ok. + * + * @param _iWidth width of the 2D data (x-axis), must be > 0 + * @param _iHeight height of the 2D data (y-axis), must be > 0 + * @param _pfData pointer to a one-dimensional float32 data block + */ + bool _initialize(int _iWidth, int _iHeight, CFloat32CustomMemory* _pCustomMemory); + /** Constructor. Create an instance of the CFloat32Data2D class without initializing the data block. * Can only be called by derived classes. * @@ -180,6 +204,21 @@ protected: */ CFloat32Data2D(int _iWidth, int _iHeight, float32 _fScalar); + /** Constructor. Create an instance of the CFloat32Data2D class with pre-allocated memory. + + * Can only be called by derived classes. + * + * Creates an instance of the CFloat32Data2D class. Memory + * is pre-allocated and passed via the abstract CFloat32CustomMemory handle + * class. The handle will be deleted when the memory can be freed. + * You should override the destructor to provide custom behaviour on free. + * + * @param _iWidth width of the 2D data (x-axis), must be > 0 + * @param _iHeight height of the 2D data (y-axis), must be > 0 + * @param _pfData pointer to a one-dimensional float32 data block + */ + CFloat32Data2D(int _iWidth, int _iHeight, CFloat32CustomMemory* _pCustomMemory); + /** Copy constructor. */ CFloat32Data2D(const CFloat32Data2D&); @@ -418,6 +457,9 @@ public: float32& getData(int _index); + +private: + CFloat32CustomMemory* m_pCustomMemory; }; diff --git a/src/Float32Data2D.cpp b/src/Float32Data2D.cpp index ae84716..151f58d 100644 --- a/src/Float32Data2D.cpp +++ b/src/Float32Data2D.cpp @@ -39,6 +39,10 @@ $Id$ namespace astra { +CFloat32CustomMemory::~CFloat32CustomMemory() { + +} + //---------------------------------------------------------------------------------------- // Constructors @@ -76,6 +80,14 @@ CFloat32Data2D::CFloat32Data2D(int _iWidth, int _iHeight, float32 _fScalar) _initialize(_iWidth, _iHeight, _fScalar); } +//---------------------------------------------------------------------------------------- +// Create an instance of the CFloat32Data2D class with pre-allocated memory. +CFloat32Data2D::CFloat32Data2D(int _iWidth, int _iHeight, CFloat32CustomMemory *_pCustomMemory) +{ + m_bInitialized = false; + _initialize(_iWidth, _iHeight, _pCustomMemory); +} + //---------------------------------------------------------------------------------------- // Copy constructor CFloat32Data2D::CFloat32Data2D(const CFloat32Data2D& _other) @@ -103,6 +115,11 @@ CFloat32Data2D& CFloat32Data2D::operator=(const CFloat32Data2D& _dataIn) memcpy(m_pfData, _dataIn.m_pfData, m_iSize * sizeof(float32)); } else { + if (m_pCustomMemory) { + // Can't re-allocate custom data + ASTRA_ASSERT(false); + return *(CFloat32Data2D*)0; + } // Re-allocate data _unInit(); _initialize(_dataIn.getWidth(), _dataIn.getHeight(), _dataIn.getDataConst()); @@ -224,6 +241,36 @@ bool CFloat32Data2D::_initialize(int _iWidth, int _iHeight, float32 _fScalar) return true; } +//---------------------------------------------------------------------------------------- +// Initializes an instance of the CFloat32Data2D class with pre-allocated memory +bool CFloat32Data2D::_initialize(int _iWidth, int _iHeight, CFloat32CustomMemory* _pCustomMemory) +{ + // basic checks + ASTRA_ASSERT(_iWidth > 0); + ASTRA_ASSERT(_iHeight > 0); + ASTRA_ASSERT(_pCustomMemory != NULL); + + if (m_bInitialized) + { + _unInit(); + } + + // calculate size + m_iWidth = _iWidth; + m_iHeight = _iHeight; + m_iSize = (size_t)m_iWidth * m_iHeight; + + // initialize the data pointers + m_pCustomMemory = _pCustomMemory; + m_pfData = 0; + m_ppfData2D = 0; + _allocateData(); + + // initialization complete + return true; +} + + //---------------------------------------------------------------------------------------- // Memory Allocation @@ -241,14 +288,20 @@ void CFloat32Data2D::_allocateData() ASTRA_ASSERT(m_pfData == NULL); ASTRA_ASSERT(m_ppfData2D == NULL); - // allocate contiguous block + if (!m_pCustomMemory) { + + // allocate contiguous block #ifdef _MSC_VER - m_pfData = (float32*)_aligned_malloc(m_iSize * sizeof(float32), 16); + m_pfData = (float32*)_aligned_malloc(m_iSize * sizeof(float32), 16); #else - int ret = posix_memalign((void**)&m_pfData, 16, m_iSize * sizeof(float32)); - ASTRA_ASSERT(ret == 0); + int ret = posix_memalign((void**)&m_pfData, 16, m_iSize * sizeof(float32)); + ASTRA_ASSERT(ret == 0); #endif + } else { + m_pfData = m_pCustomMemory->m_fPtr; + } + // create array of pointers to each row of the data block m_ppfData2D = new float32*[m_iHeight]; for (int iy = 0; iy < m_iHeight; iy++) @@ -264,15 +317,20 @@ void CFloat32Data2D::_freeData() // basic checks ASTRA_ASSERT(m_pfData != NULL); ASTRA_ASSERT(m_ppfData2D != NULL); - // free memory for index table delete[] m_ppfData2D; - // free memory for data block + + if (!m_pCustomMemory) { + // free memory for data block #ifdef _MSC_VER - _aligned_free(m_pfData); + _aligned_free(m_pfData); #else - free(m_pfData); + free(m_pfData); #endif + } else { + delete m_pCustomMemory; + m_pCustomMemory = 0; + } } @@ -286,6 +344,7 @@ void CFloat32Data2D::_clear() m_pfData = NULL; m_ppfData2D = NULL; + m_pCustomMemory = NULL; m_fGlobalMin = 0.0f; m_fGlobalMax = 0.0f; -- cgit v1.2.3