1 /* ***** BEGIN LICENSE BLOCK ***** 2 * 3 * $Id: arrays.h,v 1.21 2008/03/14 08:17:36 asuraparaju Exp $ $Name: Dirac_1_0_2 $ 4 * 5 * Version: MPL 1.1/GPL 2.0/LGPL 2.1 6 * 7 * The contents of this file are subject to the Mozilla Public License 8 * Version 1.1 (the "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * http://www.mozilla.org/MPL/ 11 * 12 * Software distributed under the License is distributed on an "AS IS" basis, 13 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for 14 * the specific language governing rights and limitations under the License. 15 * 16 * The Original Code is BBC Research and Development code. 17 * 18 * The Initial Developer of the Original Code is the British Broadcasting 19 * Corporation. 20 * Portions created by the Initial Developer are Copyright (C) 2004. 21 * All Rights Reserved. 22 * 23 * Contributor(s): Thomas Davies (Original Author), 24 * Peter Meerwald (pmeerw@users.sourceforge.net) 25 * Mike Ferenduros (mike_ferenzduros@users.sourceforge.net) 26 * Anuradha Suraparaju 27 * 28 * Alternatively, the contents of this file may be used under the terms of 29 * the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser 30 * Public License Version 2.1 (the "LGPL"), in which case the provisions of 31 * the GPL or the LGPL are applicable instead of those above. If you wish to 32 * allow use of your version of this file only under the terms of the either 33 * the GPL or LGPL and not to allow others to use your version of this file 34 * under the MPL, indicate your decision by deleting the provisions above 35 * and replace them with the notice and other provisions required by the GPL 36 * or LGPL. If you do not delete the provisions above, a recipient may use 37 * your version of this file under the terms of any one of the MPL, the GPL 38 * or the LGPL. 39 * ***** END LICENSE BLOCK ***** */ 40 41 #ifndef _ARRAYS_H_ 42 #define _ARRAYS_H_ 43 44 //basic array types used for pictures etc 45 46 #include <memory> 47 #include <cstddef> 48 #include <stdexcept> 49 #include <iostream> 50 #include <algorithm> 51 #include <cstring> 52 53 namespace dirac 54 { 55 //! Range type. 56 /*! 57 Range type encapsulating a closed range of values [first,last]. 58 Used to initialies OneDArrays. 59 */ 60 class Range 61 { 62 public: 63 //! Constructor 64 /*! 65 Constructor taking a start and an end point for the range. 66 */ Range(int s,int e)67 Range(int s, int e): m_fst(s), m_lst(e){} 68 69 //! Returns the start of the range. First()70 int First() const {return m_fst;} 71 72 //! Returns the end point of the range. Last()73 int Last() const {return m_lst;} 74 75 private: 76 int m_fst ,m_lst; 77 }; 78 79 ////////////////////////////// 80 //One-Dimensional Array type// 81 ////////////////////////////// 82 83 //! A template class for one-dimensional arrays. 84 /*! 85 A template class for one-D arrays. Can be used wherever built-in 86 arrays are used, and eliminates the need for explicit memory 87 (de-)allocation. Also supports arrays not based at zero. 88 */ 89 template <class T> class OneDArray 90 { 91 public: 92 //! Default constructor. 93 /*! 94 Default constructor produces an empty array. 95 */ 96 OneDArray(); 97 98 //! 'Length' constructor. 99 /*! 100 Length constructor produces a zero-based array. 101 */ 102 OneDArray(const int len); 103 104 //! Range constructor 105 /*! 106 Range constructor produces an array with values indexed within the 107 range parameters. 108 \param r a range of indexing values. 109 */ 110 OneDArray(const Range& r); 111 112 //! Destructor. 113 /*! 114 Destructor frees the data allocated in the constructors. 115 */ ~OneDArray()116 ~OneDArray() 117 { 118 FreePtr(); 119 } 120 121 //! Copy constructor. 122 /*! 123 Copy constructor copies both data and metadata. 124 */ 125 OneDArray(const OneDArray<T>& cpy); 126 127 //! Assignment= 128 /*! 129 Assignment= assigns both data and metadata. 130 */ 131 OneDArray<T>& operator=(const OneDArray<T>& rhs); 132 133 //! Resize the array, throwing away the current data. 134 void Resize(int l); 135 136 //! Element access. 137 T& operator[](const int pos){return m_ptr[pos-m_first];} 138 139 //! Element access. 140 const T& operator[](const int pos) const {return m_ptr[pos-m_first];} 141 142 //! Returns the length of the array. Length()143 int Length() const {return m_length;} 144 145 //! Returns the index of the first element. First()146 int First() const {return m_first;} 147 148 //! Returns the index of the last element. Last()149 int Last() const {return m_last;} 150 151 private: 152 void Init(const int len); 153 154 void Init(const Range& r); 155 156 void FreePtr(); 157 158 int m_first, m_last; 159 int m_length; 160 T* m_ptr; 161 }; 162 163 //public member functions// 164 /////////////////////////// 165 166 template <class T> OneDArray()167 OneDArray<T>::OneDArray() 168 { 169 Init(0); 170 } 171 172 template <class T> OneDArray(const int len)173 OneDArray<T>::OneDArray(const int len) 174 { 175 Init(len); 176 } 177 178 template <class T> OneDArray(const Range & r)179 OneDArray<T>::OneDArray(const Range& r) 180 { 181 Init(r); 182 } 183 184 template <class T> OneDArray(const OneDArray<T> & cpy)185 OneDArray<T>::OneDArray(const OneDArray<T>& cpy) 186 { 187 m_first = cpy.m_first; 188 m_last = cpy.m_last; 189 m_length = m_last - m_first + 1; 190 191 if (m_first==0) 192 Init(m_length); 193 else 194 Init(Range(m_first , m_last)); 195 196 memcpy( m_ptr , cpy.m_ptr , m_length * sizeof( T ) ); 197 } 198 199 template <class T> 200 OneDArray<T>& OneDArray<T>::operator=(const OneDArray<T>& rhs) 201 { 202 if (&rhs != this) 203 { 204 FreePtr(); 205 m_first = rhs.m_first; 206 m_last = rhs.m_last; 207 m_length = rhs.m_length; 208 209 if (m_first == 0) 210 Init(m_length); 211 else 212 Init(Range(m_first , m_last)); 213 214 memcpy( m_ptr , rhs.m_ptr , m_length * sizeof( T ) ); 215 216 } 217 return *this; 218 } 219 220 template <class T> Resize(int l)221 void OneDArray<T>::Resize(int l) 222 { 223 if (l != m_length) 224 { 225 FreePtr(); 226 Init(l); 227 } 228 } 229 230 //private member functions// 231 //////////////////////////// 232 233 template <class T> Init(const int len)234 void OneDArray<T>::Init(const int len) 235 { 236 Range r(0 , len-1); 237 238 Init(r); 239 240 } 241 242 template <class T> Init(const Range & r)243 void OneDArray<T>::Init(const Range& r) 244 { 245 246 m_first = r.First(); 247 m_last = r.Last(); 248 m_length = m_last - m_first + 1; 249 250 if ( m_length>0 ) 251 { 252 m_ptr = new T[ m_length ]; 253 } 254 else 255 { 256 m_length = 0; 257 m_first = 0; 258 m_last = -1; 259 m_ptr = NULL; 260 } 261 } 262 263 template <class T> FreePtr()264 void OneDArray<T>::FreePtr() 265 { 266 if ( m_length>0 ) 267 delete[] m_ptr; 268 } 269 270 271 ////////////////////////////// 272 //Two-Dimensional Array type// 273 ////////////////////////////// 274 275 //! A template class for two-dimensional arrays. 276 /*! 277 A template class to do two-d arrays, so that explicit memory 278 (de-)allocation is not required. Only zero-based arrays are 279 currently supported so that access is fast. Accessing elements along 280 a row is therefore much faster than accessing them along a column. 281 Rows are contiguous in memory, so array[y][x] is equivalent to 282 array[0][x+y*LengthX()]. 283 */ 284 template <class T> class TwoDArray 285 { 286 typedef T* element_type; 287 288 public: 289 290 //! Default constructor. 291 /*! 292 Default constructor creates an empty array. 293 */ TwoDArray()294 TwoDArray(){ Init(0,0); } 295 296 //! Constructor. 297 /*! 298 The constructor creates an array of given width height. 299 */ TwoDArray(const int height,const int width)300 TwoDArray( const int height , const int width ){Init(height , width);} 301 302 //! Constructor. 303 /*! 304 The constructor creates an array of given width and length height 305 and initialises it to a value 306 */ 307 TwoDArray( const int height , const int width , T val); 308 309 //! Destructor 310 /*! 311 Destructor frees the data allocated in the constructor. 312 */ ~TwoDArray()313 virtual ~TwoDArray(){ 314 FreeData(); 315 } 316 317 //! Copy constructor. 318 /*! 319 Copy constructor copies data and metadata. 320 */ 321 TwoDArray(const TwoDArray<T>& Cpy); 322 323 //! Assignment = 324 /*! 325 Assignement = assigns both data and metadata. 326 */ 327 TwoDArray<T>& operator=(const TwoDArray<T>& rhs); 328 329 //! Copy Contents 330 /*! 331 Copy contents of array into output array retaining the dimensions 332 of the output array. If output array is larger that array then 333 pad with last true value. 334 Return true is copy was successful 335 */ 336 bool CopyContents(TwoDArray<T>& out) const; 337 338 //! Fill contents 339 /*! 340 Initialise the array with the val provided. 341 */ 342 void Fill(T val); 343 344 //! Resizes the array, deleting the current data. 345 void Resize(const int height, const int width); 346 347 //! Element access. 348 /*! 349 Accesses the rows of the arrays, which are returned in the form 350 of pointers to the row data NOT OneDArray objects. 351 */ 352 inline element_type& operator[](const int pos){return m_array_of_rows[pos];} 353 354 //! Element access. 355 /*! 356 Accesses the rows of the arrays, which are returned in the form of 357 pointers to the row data NOT OneDArray objects. 358 */ 359 inline const element_type& operator[](const int pos) const {return m_array_of_rows[pos];} 360 361 //! Returns the width LengthX()362 int LengthX() const { return m_length_x; } 363 364 //! Returns the height LengthY()365 int LengthY() const { return m_length_y; } 366 367 //! Returns the index of the first element of a row FirstX()368 int FirstX() const { return m_first_x; } 369 370 //! Returns the index of the first element of a column FirstY()371 int FirstY() const { return m_first_y; } 372 373 //! Returns the index of the last element of a row LastX()374 int LastX() const { return m_last_x; } 375 376 //! Returns the index of the first element of a column LastY()377 int LastY() const { return m_last_y; } 378 379 private: 380 //! Initialise the array 381 void Init(const int height,const int width); 382 383 //! Free all the allocated data 384 void FreeData(); 385 386 int m_first_x; 387 int m_first_y; 388 389 int m_last_x; 390 int m_last_y; 391 392 int m_length_x; 393 int m_length_y; 394 395 element_type* m_array_of_rows; 396 }; 397 398 //public member functions// 399 /////////////////////////// 400 401 template <class T> TwoDArray(const int height,const int width,const T val)402 TwoDArray<T>::TwoDArray( const int height , const int width , const T val) 403 { 404 Init( height , width ); 405 std::fill_n( m_array_of_rows[0], m_length_x*m_length_y, val); 406 } 407 408 template <class T> TwoDArray(const TwoDArray<T> & Cpy)409 TwoDArray<T>::TwoDArray(const TwoDArray<T>& Cpy) 410 { 411 m_first_x = Cpy.m_first_x; 412 m_first_y = Cpy.m_first_y; 413 m_last_x = Cpy.m_last_x; 414 m_last_y = Cpy.m_last_y; 415 416 m_length_x = m_last_x - m_first_x + 1; 417 m_length_y = m_last_y - m_first_y + 1; 418 419 if (m_first_x == 0 && m_first_y == 0) 420 Init(m_length_y , m_length_x); 421 else{ 422 //based 2D arrays not yet supported 423 } 424 425 memcpy( m_array_of_rows[0] , (Cpy.m_array_of_rows)[0] , m_length_x * m_length_y * sizeof( T ) ); 426 427 } 428 429 template <class T> 430 TwoDArray<T>& TwoDArray<T>::operator=(const TwoDArray<T>& rhs) 431 { 432 if (&rhs != this) 433 { 434 FreeData(); 435 436 m_first_x = rhs.m_first_x; 437 m_first_y = rhs.m_first_y; 438 439 m_last_x = rhs.m_last_x; 440 m_last_y = rhs.m_last_y; 441 442 m_length_x = m_last_x - m_first_x + 1; 443 m_length_y = m_last_y - m_first_y + 1; 444 445 if (m_first_x == 0 && m_first_y == 0) 446 Init(m_length_y , m_length_x); 447 else 448 { 449 //based 2D arrays not yet supported 450 } 451 452 memcpy( m_array_of_rows[0], (rhs.m_array_of_rows)[0], m_length_x * m_length_y * sizeof( T ) ); 453 454 } 455 456 return *this; 457 458 } 459 460 template <class T> CopyContents(TwoDArray<T> & out)461 bool TwoDArray<T>::CopyContents(TwoDArray<T>& out) const 462 { 463 if (&out != this) 464 { 465 int rows = std::min (m_length_y, out.m_length_y); 466 int cols = std::min (m_length_x, out.m_length_x); 467 for (int j = 0; j < rows; ++j) 468 { 469 memcpy( out.m_array_of_rows[j], m_array_of_rows[j], cols * sizeof( T )) ; 470 for (int i = cols; i <out.m_length_x; ++i) 471 out.m_array_of_rows[j][i] = out.m_array_of_rows[j][cols-1]; 472 } 473 for (int j = rows; j < out.m_length_y; ++j) 474 { 475 memcpy( out.m_array_of_rows[j], out.m_array_of_rows[rows-1], out.m_length_x * sizeof( T )) ; 476 } 477 } 478 return true; 479 } 480 481 template <class T> Fill(T val)482 void TwoDArray<T>::Fill( T val) 483 { 484 if (m_length_x && m_length_y) 485 std::fill_n( m_array_of_rows[0], m_length_x*m_length_y, val); 486 } 487 488 template <class T> Resize(const int height,const int width)489 void TwoDArray<T>::Resize(const int height, const int width) 490 { 491 if (height != m_length_y || width != m_length_x) 492 { 493 FreeData(); 494 Init(height , width); 495 } 496 } 497 498 //private member functions// 499 //////////////////////////// 500 501 template <class T> Init(const int height,const int width)502 void TwoDArray<T>::Init(const int height , const int width) 503 { 504 m_length_x = width; 505 m_length_y = height; 506 m_first_x = 0; 507 m_first_y = 0; 508 509 m_last_x = m_length_x-1; 510 m_last_y = m_length_y-1; 511 512 if (m_length_y>0) 513 { 514 // allocate the array containing ptrs to all the rows 515 m_array_of_rows = new element_type[ m_length_y ]; 516 517 if ( m_length_x>0 ) 518 { 519 // Allocate the whole thing as a single big block 520 m_array_of_rows[0] = new T[ m_length_x * m_length_y ]; 521 522 // Point the pointers 523 for (int j=1 ; j<m_length_y ; ++j) 524 m_array_of_rows[j] = m_array_of_rows[0] + j * m_length_x; 525 } 526 else 527 { 528 m_length_x = 0; 529 m_first_x = 0; 530 m_last_x = -1; 531 } 532 } 533 else 534 { 535 m_length_x = 0; 536 m_length_y = 0; 537 m_first_x = 0; 538 m_first_y = 0; 539 m_last_x = -1; 540 m_last_y = -1; 541 m_array_of_rows = NULL; 542 } 543 } 544 545 template <class T> FreeData()546 void TwoDArray<T>::FreeData() 547 { 548 if (m_length_y>0) 549 { 550 if (m_length_x>0) 551 { 552 delete[] m_array_of_rows[0]; 553 } 554 555 m_length_y = m_length_x = 0; 556 // deallocate the array of rows 557 delete[] m_array_of_rows; 558 } 559 } 560 561 // Related functions 562 563 //! A function for extracting array data 564 template <class T > 565 std::ostream & operator<< (std::ostream & stream, TwoDArray<T> & array) 566 { 567 for (int j=0 ; j<array.LengthY() ; ++j) 568 { 569 for (int i=0 ; i<array.LengthX() ; ++i) 570 { 571 stream << array[j][i] << " "; 572 }// i 573 stream << std::endl; 574 }// j 575 576 return stream; 577 } 578 579 //! A function for inserting array data 580 template <class T > 581 std::istream & operator>> (std::istream & stream, TwoDArray<T> & array) 582 { 583 for (int j=0 ; j<array.LengthY() ; ++j) 584 { 585 for (int i=0 ; i<array.LengthX() ; ++i) 586 { 587 stream >> array[j][i]; 588 }// i 589 }// j 590 591 return stream; 592 } 593 594 } //namespace dirac 595 #endif 596