diff options
Diffstat (limited to 'src/Float32Data2D.cpp')
-rw-r--r-- | src/Float32Data2D.cpp | 523 |
1 files changed, 523 insertions, 0 deletions
diff --git a/src/Float32Data2D.cpp b/src/Float32Data2D.cpp new file mode 100644 index 0000000..e51935f --- /dev/null +++ b/src/Float32Data2D.cpp @@ -0,0 +1,523 @@ +/* +----------------------------------------------------------------------- +Copyright 2012 iMinds-Vision Lab, University of Antwerp + +Contact: astra@ua.ac.be +Website: http://astra.ua.ac.be + + +This file is part of the +All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA Toolbox"). + +The ASTRA Toolbox is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +The ASTRA Toolbox is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with the ASTRA Toolbox. If not, see <http://www.gnu.org/licenses/>. + +----------------------------------------------------------------------- +$Id$ +*/ + +#include "astra/Float32Data2D.h" +#include <iostream> +#include <cstring> + +#ifdef _MSC_VER +#include <malloc.h> +#else +#include <cstdlib> +#endif + +namespace astra { + + + //---------------------------------------------------------------------------------------- + // Constructors +//---------------------------------------------------------------------------------------- + +//---------------------------------------------------------------------------------------- +// Default constructor. +CFloat32Data2D::CFloat32Data2D() +{ + _clear(); + m_bInitialized = false; +} + +//---------------------------------------------------------------------------------------- +// Create an instance of the CFloat32Data2D class, allocating (but not initializing) the data block. +CFloat32Data2D::CFloat32Data2D(int _iWidth, int _iHeight) +{ + m_bInitialized = false; + _initialize(_iWidth, _iHeight); +} + +//---------------------------------------------------------------------------------------- +// Create an instance of the CFloat32Data2D class with initialization of the data block. +CFloat32Data2D::CFloat32Data2D(int _iWidth, int _iHeight, const float32* _pfData) +{ + m_bInitialized = false; + _initialize(_iWidth, _iHeight, _pfData); +} + +//---------------------------------------------------------------------------------------- +// Create an instance of the CFloat32Data2D class with initialization of the data block. +CFloat32Data2D::CFloat32Data2D(int _iWidth, int _iHeight, float32 _fScalar) +{ + m_bInitialized = false; + _initialize(_iWidth, _iHeight, _fScalar); +} + +//---------------------------------------------------------------------------------------- +// Copy constructor +CFloat32Data2D::CFloat32Data2D(const CFloat32Data2D& _other) +{ + m_bInitialized = false; + *this = _other; +} + +//---------------------------------------------------------------------------------------- +// Assignment operator +CFloat32Data2D& CFloat32Data2D::operator=(const CFloat32Data2D& _dataIn) +{ + ASTRA_ASSERT(_dataIn.m_bInitialized); + + if (m_bInitialized) { + if (m_iWidth == _dataIn.m_iWidth && m_iHeight == _dataIn.m_iHeight) { + // Same dimensions, so no need to re-allocate memory + + m_fGlobalMin = _dataIn.m_fGlobalMin; + m_fGlobalMax = _dataIn.m_fGlobalMax; + m_fGlobalMean = _dataIn.m_fGlobalMean; + + ASTRA_ASSERT(m_iSize == (size_t)m_iWidth * m_iHeight); + ASTRA_ASSERT(m_pfData); + + memcpy(m_pfData, _dataIn.m_pfData, m_iSize * sizeof(float32)); + } else { + // Re-allocate data + _unInit(); + _initialize(_dataIn.getWidth(), _dataIn.getHeight(), _dataIn.getDataConst()); + } + } else { + _initialize(_dataIn.getWidth(), _dataIn.getHeight(), _dataIn.getDataConst()); + } + + return (*this); +} + +//---------------------------------------------------------------------------------------- +// Destructor. Free allocated memory +CFloat32Data2D::~CFloat32Data2D() +{ + if (m_bInitialized) + { + _unInit(); + } +} + +//---------------------------------------------------------------------------------------- +// Initializes an instance of the CFloat32Data2D class, allocating (but not initializing) the data block. +bool CFloat32Data2D::_initialize(int _iWidth, int _iHeight) +{ + // basic checks + ASTRA_ASSERT(_iWidth > 0); + ASTRA_ASSERT(_iHeight > 0); + + if (m_bInitialized) + { + _unInit(); + } + + // calculate size + m_iWidth = _iWidth; + m_iHeight = _iHeight; + m_iSize = (size_t)m_iWidth * m_iHeight; + + // allocate memory for the data, but do not fill it + m_pfData = 0; + m_ppfData2D = 0; + _allocateData(); + + // set minmax to default values + m_fGlobalMin = 0.0; + m_fGlobalMax = 0.0; + m_fGlobalMean = 0.0; + + // initialization complete + return true; + +} + +//---------------------------------------------------------------------------------------- +// Initializes an instance of the CFloat32Data2D class with initialization of the data block. +bool CFloat32Data2D::_initialize(int _iWidth, int _iHeight, const float32 *_pfData) +{ + // basic checks + ASTRA_ASSERT(_iWidth > 0); + ASTRA_ASSERT(_iHeight > 0); + ASTRA_ASSERT(_pfData != NULL); + + if (m_bInitialized) + { + _unInit(); + } + + // calculate size + m_iWidth = _iWidth; + m_iHeight = _iHeight; + m_iSize = (size_t)m_iWidth * m_iHeight; + + // allocate memory for the data + m_pfData = 0; + m_ppfData2D = 0; + _allocateData(); + + // fill the data block with a copy of the input data + size_t i; + for (i = 0; i < m_iSize; ++i) { + m_pfData[i] = _pfData[i]; + } + + // initialization complete + return true; +} + +//---------------------------------------------------------------------------------------- +// Initializes an instance of the CFloat32Data2D class with a scalar initialization of the data block. +bool CFloat32Data2D::_initialize(int _iWidth, int _iHeight, float32 _fScalar) +{ + // basic checks + ASTRA_ASSERT(_iWidth > 0); + ASTRA_ASSERT(_iHeight > 0); + + if (m_bInitialized) { + _unInit(); + } + + // calculate size + m_iWidth = _iWidth; + m_iHeight = _iHeight; + m_iSize = (size_t)m_iWidth * m_iHeight; + + // allocate memory for the data + m_pfData = 0; + m_ppfData2D = 0; + _allocateData(); + + // fill the data block with a copy of the input data + size_t i; + for (i = 0; i < m_iSize; ++i) + { + m_pfData[i] = _fScalar; + } + + // initialization complete + return true; +} + + + //---------------------------------------------------------------------------------------- + // Memory Allocation +//---------------------------------------------------------------------------------------- + +//---------------------------------------------------------------------------------------- +// Allocate memory for m_pfData and m_ppfData2D arrays. +void CFloat32Data2D::_allocateData() +{ + // basic checks + ASTRA_ASSERT(!m_bInitialized); + + ASTRA_ASSERT(m_iSize > 0); + ASTRA_ASSERT(m_iSize == (size_t)m_iWidth * m_iHeight); + ASTRA_ASSERT(m_pfData == NULL); + ASTRA_ASSERT(m_ppfData2D == NULL); + + // allocate contiguous block +#ifdef _MSC_VER + 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); +#endif + + // 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++) + { + m_ppfData2D[iy] = &(m_pfData[iy * m_iWidth]); + } +} + +//---------------------------------------------------------------------------------------- +// Free memory for m_pfData and m_ppfData2D arrays. +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 +#ifdef _MSC_VER + _aligned_free(m_pfData); +#else + free(m_pfData); +#endif +} + + +//---------------------------------------------------------------------------------------- +// Clear all member variables, setting all numeric variables to 0 and all pointers to NULL. +void CFloat32Data2D::_clear() +{ + m_iWidth = 0; + m_iHeight = 0; + m_iSize = 0; + + m_pfData = NULL; + m_ppfData2D = NULL; + + m_fGlobalMin = 0.0f; + m_fGlobalMax = 0.0f; +} + +//---------------------------------------------------------------------------------------- +// Un-initialize the object, bringing it back in the unitialized state. +void CFloat32Data2D::_unInit() +{ + ASTRA_ASSERT(m_bInitialized); + + _freeData(); + _clear(); + m_bInitialized = false; +} +//---------------------------------------------------------------------------------------- + + + + //---------------------------------------------------------------------------------------- + // Data Operations +//---------------------------------------------------------------------------------------- + +//---------------------------------------------------------------------------------------- +// Copy the data block pointed to by _pfData to the data block pointed to by m_pfData. +void CFloat32Data2D::copyData(const float32* _pfData) +{ + // basic checks + ASTRA_ASSERT(m_bInitialized); + ASTRA_ASSERT(_pfData != NULL); + ASTRA_ASSERT(m_pfData != NULL); + ASTRA_ASSERT(m_iSize > 0); + + // copy data + size_t i; + for (i = 0; i < m_iSize; ++i) { + m_pfData[i] = _pfData[i]; + } +} + +//---------------------------------------------------------------------------------------- +// scale m_pfData from 0 to 255. + +void CFloat32Data2D::scale() +{ + // basic checks + ASTRA_ASSERT(m_bInitialized); + ASTRA_ASSERT(m_pfData != NULL); + ASTRA_ASSERT(m_iSize > 0); + + _computeGlobalMinMax(); + for (size_t i = 0; i < m_iSize; i++) + { + // do checks + m_pfData[i]= (m_pfData[i] - m_fGlobalMin) / (m_fGlobalMax - m_fGlobalMin) * 255; ; + } + + +} + +//---------------------------------------------------------------------------------------- +// Set each element of the data to a specific scalar value +void CFloat32Data2D::setData(float32 _fScalar) +{ + // basic checks + ASTRA_ASSERT(m_bInitialized); + ASTRA_ASSERT(m_pfData != NULL); + ASTRA_ASSERT(m_iSize > 0); + + // copy data + size_t i; + for (i = 0; i < m_iSize; ++i) + { + m_pfData[i] = _fScalar; + } +} + +//---------------------------------------------------------------------------------------- +// Clear Data +void CFloat32Data2D::clearData() +{ + // basic checks + ASTRA_ASSERT(m_bInitialized); + ASTRA_ASSERT(m_pfData != NULL); + ASTRA_ASSERT(m_iSize > 0); + + // set data + size_t i; + for (i = 0; i < m_iSize; ++i) { + m_pfData[i] = 0.0f; + } +} +//---------------------------------------------------------------------------------------- + + + + //---------------------------------------------------------------------------------------- + // Statistics Operations +//---------------------------------------------------------------------------------------- + +//---------------------------------------------------------------------------------------- +// Update data statistics, such as minimum and maximum value, after the data has been modified. +void CFloat32Data2D::updateStatistics() +{ + _computeGlobalMinMax(); +} + +//---------------------------------------------------------------------------------------- +// Find the minimum and maximum data value. +void CFloat32Data2D::_computeGlobalMinMax() +{ + // basic checks + ASTRA_ASSERT(m_bInitialized); + ASTRA_ASSERT(m_pfData != NULL); + ASTRA_ASSERT(m_iSize > 0); + + // initial values + m_fGlobalMin = m_pfData[0]; + m_fGlobalMax = m_pfData[0]; + m_fGlobalMean = 0.0f; + + // loop + for (size_t i = 0; i < m_iSize; i++) + { + // do checks + float32 v = m_pfData[i]; + if (v < m_fGlobalMin) { + m_fGlobalMin = v; + } + if (v > m_fGlobalMax) { + m_fGlobalMax = v; + } + m_fGlobalMean +=v; + } + m_fGlobalMean /= m_iSize; +} +//---------------------------------------------------------------------------------------- + + +CFloat32Data2D& CFloat32Data2D::clampMin(float32& _fMin) +{ + ASTRA_ASSERT(m_bInitialized); + for (size_t i = 0; i < m_iSize; i++) { + if (m_pfData[i] < _fMin) + m_pfData[i] = _fMin; + } + return (*this); +} + +CFloat32Data2D& CFloat32Data2D::clampMax(float32& _fMax) +{ + ASTRA_ASSERT(m_bInitialized); + for (size_t i = 0; i < m_iSize; i++) { + if (m_pfData[i] > _fMax) + m_pfData[i] = _fMax; + } + return (*this); +} + + +//---------------------------------------------------------------------------------------- +// Operator Overloading +//---------------------------------------------------------------------------------------- +CFloat32Data2D& CFloat32Data2D::operator+=(const CFloat32Data2D& v) +{ + ASTRA_ASSERT(m_bInitialized); + ASTRA_ASSERT(v.m_bInitialized); + ASTRA_ASSERT(getSize() == v.getSize()); + for (size_t i = 0; i < m_iSize; i++) { + m_pfData[i] += v.m_pfData[i]; + } + return (*this); +} + +CFloat32Data2D& CFloat32Data2D::operator-=(const CFloat32Data2D& v) +{ + ASTRA_ASSERT(m_bInitialized); + ASTRA_ASSERT(v.m_bInitialized); + ASTRA_ASSERT(getSize() == v.getSize()); + for (size_t i = 0; i < m_iSize; i++) { + m_pfData[i] -= v.m_pfData[i]; + } + return (*this); +} + +CFloat32Data2D& CFloat32Data2D::operator*=(const CFloat32Data2D& v) +{ + ASTRA_ASSERT(m_bInitialized); + ASTRA_ASSERT(v.m_bInitialized); + ASTRA_ASSERT(getSize() == v.getSize()); + for (size_t i = 0; i < m_iSize; i++) { + m_pfData[i] *= v.m_pfData[i]; + } + return (*this); +} + +CFloat32Data2D& CFloat32Data2D::operator*=(const float32& f) +{ + ASTRA_ASSERT(m_bInitialized); + for (size_t i = 0; i < m_iSize; i++) { + m_pfData[i] *= f; + } + return (*this); +} + +CFloat32Data2D& CFloat32Data2D::operator/=(const float32& f) +{ + ASTRA_ASSERT(m_bInitialized); + for (size_t i = 0; i < m_iSize; i++) { + m_pfData[i] /= f; + } + return (*this); +} + +CFloat32Data2D& CFloat32Data2D::operator+=(const float32& f) +{ + ASTRA_ASSERT(m_bInitialized); + for (size_t i = 0; i < m_iSize; i++) { + m_pfData[i] += f; + } + return (*this); +} + +CFloat32Data2D& CFloat32Data2D::operator-=(const float32& f) +{ + ASTRA_ASSERT(m_bInitialized); + for (size_t i = 0; i < m_iSize; i++) { + m_pfData[i] -= f; + } + return (*this); +} + + + + +} // end namespace astra |