summaryrefslogtreecommitdiffstats
path: root/src/Float32Data2D.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/Float32Data2D.cpp')
-rw-r--r--src/Float32Data2D.cpp523
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