core/vbl/vbl_bit_array_2d.cxx
Go to the documentation of this file.
00001 // This is core/vbl/vbl_bit_array_2d.cxx
00002 #ifdef VCL_NEEDS_PRAGMA_INTERFACE
00003 #pragma implementation
00004 #endif
00005 //:
00006 // \file
00007 
00008 #include "vbl_bit_array_2d.h"
00009 
00010 #include <vcl_iostream.h>
00011 #include <vcl_climits.h>  // for CHAR_BIT
00012 #include <vcl_cassert.h>
00013 #include <vcl_cstring.h> // for memcmp()
00014 
00015 //: Copy constructor
00016 vbl_bit_array_2d::vbl_bit_array_2d(vbl_bit_array_2d const& that)
00017   : data_(0), num_rows_(0), num_cols_(0)
00018 {
00019   if ( that.data_)
00020   {
00021     construct(that.num_rows_, that.num_cols_);
00022     vcl_memcpy(data_, that.data_, this->size());
00023   }
00024 }
00025 
00026 vbl_bit_array_2d::vbl_bit_array_2d(unsigned int m, unsigned int n, bool v[])
00027 {
00028   construct(m,n);
00029   for (unsigned int x=0; x<m; ++x)
00030     for (unsigned int y=0; y<n; ++y)
00031       set(x,y, v[m*y+x]);
00032 }
00033 
00034 //: Assignment operator
00035 vbl_bit_array_2d& vbl_bit_array_2d::operator=(vbl_bit_array_2d const& that)
00036 {
00037   if (num_rows_ != that.num_rows_ ||
00038       num_cols_ != that.num_cols_)
00039     resize(that.num_rows_, that.num_cols_);
00040 
00041   vcl_memcpy(data_, that.data_, this->size());
00042   return *this;
00043 }
00044 
00045 //: Resizes and pads with zeros; keeps existing data
00046 void vbl_bit_array_2d::enlarge( unsigned int num_rows, unsigned int num_cols)
00047 {
00048   assert (num_rows >= num_rows_ && num_cols >= num_cols_);
00049 
00050   unsigned char *tempdata= data_;
00051   unsigned int tempm= num_rows_;
00052   unsigned int tempn= num_cols_;
00053 
00054   construct( num_rows, num_cols);
00055   fill(false); // fill with zeros
00056 
00057   if (tempdata)
00058   {
00059     for (unsigned int i=0; i< tempm; ++i)
00060     {
00061       // find start of new column
00062       unsigned long byteindex;
00063       unsigned int bitindex;
00064       index( i, 0, byteindex, bitindex);
00065 
00066       // find start of old column
00067       unsigned long oldbyteindex= (unsigned long)(double(i*tempn)/CHAR_BIT);
00068 
00069       // copy i-th column
00070       vcl_memcpy(data_+byteindex, tempdata+oldbyteindex, (tempn+CHAR_BIT-1)/CHAR_BIT);
00071     }
00072     delete[] tempdata;
00073   }
00074 }
00075 
00076 //: Fill with value
00077 void vbl_bit_array_2d::fill(bool value)
00078 {
00079   register unsigned char v = value ? ~(unsigned char)0 : 0;
00080   vcl_memset(data_, v, this->size());
00081 }
00082 
00083 unsigned long vbl_bit_array_2d::size() const
00084 {
00085   return (num_rows_*num_cols_+CHAR_BIT-1)/CHAR_BIT;
00086 }
00087 
00088 void vbl_bit_array_2d::construct(unsigned int num_rows, unsigned int num_cols)
00089 {
00090   // quick return if possible
00091   if (num_rows==0 || num_cols==0) { num_rows_=num_cols_=0; data_ = 0; return; }
00092   num_rows_ = num_rows;
00093   num_cols_ = num_cols;
00094   data_ = new unsigned char [this->size()];
00095   data_[this->size()-1]=0; // avoids uninitialized data problems in operator==()
00096 }
00097 
00098 void vbl_bit_array_2d::index( unsigned int x, unsigned int y, unsigned long &byteindex, unsigned int &bitindex) const
00099 {
00100   unsigned long idx= x* num_cols_ + y;
00101 
00102   byteindex= (unsigned long)(double(idx)/CHAR_BIT);
00103   bitindex = idx%CHAR_BIT;
00104 }
00105 
00106 bool vbl_bit_array_2d::operator==(vbl_bit_array_2d const &a) const
00107 {
00108   if (rows() != a.rows() || cols() != a.cols())
00109     return false;
00110   return 0 == vcl_memcmp(data_, a.data_, this->size());
00111 }
00112 
00113 bool vbl_bit_array_2d::operator() (unsigned int i, unsigned int j) const
00114 {
00115   unsigned long byteindex;
00116   unsigned int bitindex;
00117   index( i, j, byteindex, bitindex);
00118 
00119   unsigned char mask= (unsigned char)(1<<bitindex);
00120 
00121   return (data_[byteindex] & mask) != 0;
00122 }
00123 
00124 bool vbl_bit_array_2d::operator() (unsigned int i, unsigned int j)
00125 {
00126   unsigned long byteindex;
00127   unsigned int bitindex;
00128   index( i, j, byteindex, bitindex);
00129 
00130   unsigned char mask= (unsigned char)(1<<bitindex);
00131 
00132   return (data_[byteindex] & mask) != 0;
00133 }
00134 
00135 void vbl_bit_array_2d::put(unsigned int i, unsigned int j, bool const &x)
00136 {
00137   unsigned long byteindex;
00138   unsigned int bitindex;
00139 
00140   index( i, j, byteindex, bitindex);
00141 
00142   unsigned char mask= (unsigned char)(x?(1<<bitindex):0);
00143   unsigned char nmask= (unsigned char)(~(1<<bitindex));
00144 
00145   data_[byteindex]= mask|(nmask & data_[byteindex]);
00146 }
00147 
00148 bool vbl_bit_array_2d::get(unsigned int i, unsigned int j) const
00149 {
00150   return operator()(i,j);
00151 }
00152 
00153 //
00154 vcl_ostream& operator<< (vcl_ostream &os, const vbl_bit_array_2d &array)
00155 {
00156   for (unsigned int i=0; i< array.rows(); i++)
00157   {
00158     for (unsigned int j=0; j< array.columns(); j++)
00159       os << array(i,j) << ' ';
00160 
00161     os << vcl_endl;
00162   }
00163   return os;
00164 }