/* ***** BEGIN LICENSE BLOCK ***** * * $Id: arrays.h,v 1.17 2007/03/19 16:18:59 asuraparaju Exp $ $Name: Dirac_0_7_0 $ * * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Mozilla Public License * Version 1.1 (the "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for * the specific language governing rights and limitations under the License. * * The Original Code is BBC Research and Development code. * * The Initial Developer of the Original Code is the British Broadcasting * Corporation. * Portions created by the Initial Developer are Copyright (C) 2004. * All Rights Reserved. * * Contributor(s): Thomas Davies (Original Author), * Peter Meerwald (pmeerw@users.sourceforge.net) * Mike Ferenduros (mike_ferenzduros@users.sourceforge.net) * Anuradha Suraparaju * * Alternatively, the contents of this file may be used under the terms of * the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser * Public License Version 2.1 (the "LGPL"), in which case the provisions of * the GPL or the LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the either * the GPL or LGPL and not to allow others to use your version of this file * under the MPL, indicate your decision by deleting the provisions above * and replace them with the notice and other provisions required by the GPL * or LGPL. If you do not delete the provisions above, a recipient may use * your version of this file under the terms of any one of the MPL, the GPL * or the LGPL. * ***** END LICENSE BLOCK ***** */ #ifndef _ARRAYS_H_ #define _ARRAYS_H_ //basic array types used for pictures etc #include #include #include #include #include namespace dirac { typedef short ValueType; typedef int CalcValueType; //! Range type. /*! Range type encapsulating a closed range of values [first,last]. Used to initialies OneDArrays. */ class Range { public: //! Constructor /*! Constructor taking a start and an end point for the range. */ Range(int s, int e): m_fst(s), m_lst(e){} //! Returns the start of the range. const int First() const {return m_fst;} //! Returns the end point of the range. const int Last() const {return m_lst;} private: int m_fst ,m_lst; }; ////////////////////////////// //One-Dimensional Array type// ////////////////////////////// //! A template class for one-dimensional arrays. /*! A template class for one-D arrays. Can be used wherever built-in arrays are used, and eliminates the need for explicit memory (de-)allocation. Also supports arrays not based at zero. */ template class OneDArray { public: //! Default constructor. /*! Default constructor produces an empty array. */ OneDArray(); //! 'Length' constructor. /*! Length constructor produces a zero-based array. */ OneDArray(const int len); //! Range constructor /*! Range constructor produces an array with values indexed within the range parameters. \param r a range of indexing values. */ OneDArray(const Range& r); //! Destructor. /*! Destructor frees the data allocated in the constructors. */ ~OneDArray() { FreePtr(); } //! Copy constructor. /*! Copy constructor copies both data and metadata. */ OneDArray(const OneDArray& cpy); //! Assignment= /*! Assignment= assigns both data and metadata. */ OneDArray& operator=(const OneDArray& rhs); //! Resize the array, throwing away the current data. void Resize(int l); //! Element access. T& operator[](const int pos){return m_ptr[pos-m_first];} //! Element access. const T& operator[](const int pos) const {return m_ptr[pos-m_first];} //! Returns the length of the array. int Length() const {return m_length;} //! Returns the index of the first element. int First() const {return m_first;} //! Returns the index of the last element. int Last() const {return m_last;} private: void Init(const int len); void Init(const Range& r); void FreePtr(); int m_first, m_last; int m_length; T* m_ptr; }; //public member functions// /////////////////////////// template OneDArray::OneDArray() { Init(0); } template OneDArray::OneDArray(const int len) { Init(len); } template OneDArray::OneDArray(const Range& r) { Init(r); } template OneDArray::OneDArray(const OneDArray& cpy) { m_first = cpy.m_first; m_last = cpy.m_last; m_length = m_last - m_first + 1; if (m_first==0) Init(m_length); else Init(Range(m_first , m_last)); memcpy( m_ptr , cpy.m_ptr , m_length * sizeof( T ) ); } template OneDArray& OneDArray::operator=(const OneDArray& rhs) { if (&rhs != this) { FreePtr(); m_first = rhs.m_first; m_last = rhs.m_last; m_length = rhs.m_length; if (m_first == 0) Init(m_length); else Init(Range(m_first , m_last)); memcpy( m_ptr , rhs.m_ptr , m_length * sizeof( T ) ); } return *this; } template void OneDArray::Resize(int l) { if (l != m_length) { FreePtr(); Init(l); } } //private member functions// //////////////////////////// template void OneDArray::Init(const int len) { Range r(0 , len-1); Init(r); } template void OneDArray::Init(const Range& r) { m_first = r.First(); m_last = r.Last(); m_length = m_last - m_first + 1; if ( m_length>0 ) { m_ptr = new T[ m_length ]; } else { m_length = 0; m_first = 0; m_last = -1; m_ptr = NULL; } } template void OneDArray::FreePtr() { if ( m_length>0 ) delete[] m_ptr; } ////////////////////////////// //Two-Dimensional Array type// ////////////////////////////// //! A template class for two-dimensional arrays. /*! A template class to do two-d arrays, so that explicit memory (de-)allocation is not required. Only zero-based arrays are currently supported so that access is fast. Accessing elements along a row is therefore much faster than accessing them along a column. Rows are contiguous in memory, so array[y][x] is equivalent to array[0][x+y*LengthX()]. */ template class TwoDArray { typedef T* element_type; public: //! Default constructor. /*! Default constructor creates an empty array. */ TwoDArray(){ Init(0,0); } //! Constructor. /*! The constructor creates an array of given width height. */ TwoDArray( const int height , const int width ){Init(height , width);} //! Constructor. /*! The constructor creates an array of given width and length height and initialises it to a value */ TwoDArray( const int height , const int width , T val); //! Destructor /*! Destructor frees the data allocated in the constructor. */ virtual ~TwoDArray(){ FreeData(); } //! Copy constructor. /*! Copy constructor copies data and metadata. */ TwoDArray(const TwoDArray& Cpy); //! Assignment = /*! Assignement = assigns both data and metadata. */ TwoDArray& operator=(const TwoDArray& rhs); //! Resizes the array, deleting the current data. void Resize(const int height, const int width); //! Element access. /*! Accesses the rows of the arrays, which are returned in the form of pointers to the row data NOT OneDArray objects. */ inline element_type& operator[](const int pos){return m_array_of_rows[pos];} //! Element access. /*! Accesses the rows of the arrays, which are returned in the form of pointers to the row data NOT OneDArray objects. */ inline const element_type& operator[](const int pos) const {return m_array_of_rows[pos];} //! Returns the width const int LengthX() const { return m_length_x; } //! Returns the height const int LengthY() const { return m_length_y; } //! Returns the index of the first element of a row const int FirstX() const { return m_first_x; } //! Returns the index of the first element of a column const int FirstY() const { return m_first_y; } //! Returns the index of the last element of a row const int LastX() const { return m_last_x; } //! Returns the index of the first element of a column const int LastY() const { return m_last_y; } private: //! Initialise the array void Init(const int height,const int width); //! Free all the allocated data void FreeData(); int m_first_x; int m_first_y; int m_last_x; int m_last_y; int m_length_x; int m_length_y; element_type* m_array_of_rows; }; //public member functions// /////////////////////////// template TwoDArray::TwoDArray( const int height , const int width , const T val) { Init( height , width ); std::fill_n( m_array_of_rows[0], m_length_x*m_length_y, val); } template TwoDArray::TwoDArray(const TwoDArray& Cpy) { m_first_x = Cpy.m_first_x; m_first_y = Cpy.m_first_y; m_last_x = Cpy.m_last_x; m_last_y = Cpy.m_last_y; m_length_x = m_last_x - m_first_x + 1; m_length_y = m_last_y - m_first_y + 1; if (m_first_x == 0 && m_first_y == 0) Init(m_length_y , m_length_x); else{ //based 2D arrays not yet supported } memcpy( m_array_of_rows[0] , (Cpy.m_array_of_rows)[0] , m_length_x * m_length_y * sizeof( T ) ); } template TwoDArray& TwoDArray::operator=(const TwoDArray& rhs) { if (&rhs != this) { FreeData(); m_first_x = rhs.m_first_x; m_first_y = rhs.m_first_y; m_last_x = rhs.m_last_x; m_last_y = rhs.m_last_y; m_length_x = m_last_x - m_first_x + 1; m_length_y = m_last_y - m_first_y + 1; if (m_first_x == 0 && m_first_y == 0) Init(m_length_y , m_length_x); else { //based 2D arrays not yet supported } memcpy( m_array_of_rows[0], (rhs.m_array_of_rows)[0], m_length_x * m_length_y * sizeof( T ) ); } return *this; } template void TwoDArray::Resize(const int height, const int width) { if (height != m_length_y || width != m_length_x) { FreeData(); Init(height , width); } } //private member functions// //////////////////////////// template void TwoDArray::Init(const int height , const int width) { m_length_x = width; m_length_y = height; m_first_x = 0; m_first_y = 0; m_last_x = m_length_x-1; m_last_y = m_length_y-1; if (m_length_y>0) { // allocate the array containing ptrs to all the rows m_array_of_rows = new element_type[ m_length_y ]; if ( m_length_x>0 ) { // Allocate the whole thing as a single big block m_array_of_rows[0] = new T[ m_length_x * m_length_y ]; // Point the pointers for (int j=1 ; j void TwoDArray::FreeData() { if (m_length_y>0) { if (m_length_x>0) { delete[] m_array_of_rows[0]; } m_length_y = m_length_x = 0; // deallocate the array of rows delete[] m_array_of_rows; } } // Related functions //! A function for extracting array data template std::ostream & operator<< (std::ostream & stream, TwoDArray & array) { for (int j=0 ; j std::istream & operator>> (std::istream & stream, TwoDArray & array) { for (int j=0 ; j> array[j][i]; }// i }// j return stream; } } //namespace dirac #endif