vbl_bit_array_2d.cxx
Go to the documentation of this file.
1 // This is core/vbl/vbl_bit_array_2d.cxx
2 //:
3 // \file
4 
5 #include <iostream>
6 #include <cstring>
7 #include "vbl_bit_array_2d.h"
8 
9 #ifdef _MSC_VER
10 # include <vcl_msvc_warnings.h>
11 #endif
12 #include <climits>// for CHAR_BIT
13 #include <cassert>
14 
15 //: Copy constructor
17  : data_(nullptr), num_rows_(0), num_cols_(0)
18 {
19  if ( that.data_)
20  {
21  construct(that.num_rows_, that.num_cols_);
22  std::memcpy(data_, that.data_, this->size());
23  }
24 }
25 
26 vbl_bit_array_2d::vbl_bit_array_2d(unsigned int m, unsigned int n, bool v[])
27 {
28  construct(m,n);
29  for (unsigned int x=0; x<m; ++x)
30  for (unsigned int y=0; y<n; ++y)
31  set(x,y, v[m*y+x]);
32 }
33 
34 //: Assignment operator
36 {
37  if (num_rows_ != that.num_rows_ ||
38  num_cols_ != that.num_cols_)
39  resize(that.num_rows_, that.num_cols_);
40 
41  std::memcpy(data_, that.data_, this->size());
42  return *this;
43 }
44 
45 //: Resizes and pads with zeros; keeps existing data
46 void vbl_bit_array_2d::enlarge( unsigned int num_rows, unsigned int num_cols)
47 {
48  assert (num_rows >= num_rows_ && num_cols >= num_cols_);
49 
50  unsigned char *tempdata= data_;
51  unsigned int tempm= num_rows_;
52  unsigned int tempn= num_cols_;
53 
54  construct( num_rows, num_cols);
55  fill(false); // fill with zeros
56 
57  if (tempdata)
58  {
59  for (unsigned int i=0; i< tempm; ++i)
60  {
61  // find start of new column
62  unsigned long byteindex;
63  unsigned int bitindex;
64  index( i, 0, byteindex, bitindex);
65 
66  // find start of old column
67  auto oldbyteindex= (unsigned long)(double(i*tempn)/CHAR_BIT);
68 
69  // copy i-th column
70  std::memcpy(data_+byteindex, tempdata+oldbyteindex, (tempn+CHAR_BIT-1)/CHAR_BIT);
71  }
72  delete[] tempdata;
73  }
74 }
75 
76 //: Fill with value
77 void vbl_bit_array_2d::fill(bool value)
78 {
79  unsigned char v = value ? ~(unsigned char)0 : 0;
80  std::memset(data_, v, this->size());
81 }
82 
83 unsigned long vbl_bit_array_2d::size() const
84 {
85  return (num_rows_*num_cols_+CHAR_BIT-1)/CHAR_BIT;
86 }
87 
88 void vbl_bit_array_2d::construct(unsigned int num_rows, unsigned int num_cols)
89 {
90  // quick return if possible
91  if (num_rows==0 || num_cols==0) { num_rows_=num_cols_=0; data_ = nullptr; return; }
92  num_rows_ = num_rows;
93  num_cols_ = num_cols;
94  data_ = new unsigned char [this->size()];
95  data_[this->size()-1]=0; // avoids uninitialized data problems in operator==()
96 }
97 
98 void vbl_bit_array_2d::index( unsigned int x, unsigned int y, unsigned long &byteindex, unsigned int &bitindex) const
99 {
100  unsigned long idx= x* num_cols_ + y;
101 
102  byteindex= (unsigned long)(double(idx)/CHAR_BIT);
103  bitindex = idx%CHAR_BIT;
104 }
105 
107 {
108  if (rows() != a.rows() || cols() != a.cols())
109  return false;
110  return 0 == std::memcmp(data_, a.data_, this->size());
111 }
112 
113 bool vbl_bit_array_2d::operator() (unsigned int i, unsigned int j) const
114 {
115  unsigned long byteindex;
116  unsigned int bitindex;
117  index( i, j, byteindex, bitindex);
118 
119  auto mask= (unsigned char)(1<<bitindex);
120 
121  return (data_[byteindex] & mask) != 0;
122 }
123 
124 bool vbl_bit_array_2d::operator() (unsigned int i, unsigned int j)
125 {
126  unsigned long byteindex;
127  unsigned int bitindex;
128  index( i, j, byteindex, bitindex);
129 
130  auto mask= (unsigned char)(1<<bitindex);
131 
132  return (data_[byteindex] & mask) != 0;
133 }
134 
135 void vbl_bit_array_2d::put(unsigned int i, unsigned int j, bool const &x)
136 {
137  unsigned long byteindex;
138  unsigned int bitindex;
139 
140  index( i, j, byteindex, bitindex);
141 
142  auto mask= (unsigned char)(x?(1<<bitindex):0);
143  auto nmask= (unsigned char)(~(1<<bitindex));
144 
145  data_[byteindex]= mask|(nmask & data_[byteindex]);
146 }
147 
148 bool vbl_bit_array_2d::get(unsigned int i, unsigned int j) const
149 {
150  return operator()(i,j);
151 }
152 
153 //
154 std::ostream& operator<< (std::ostream &os, const vbl_bit_array_2d &array)
155 {
156  for (unsigned int i=0; i< array.rows(); i++)
157  {
158  for (unsigned int j=0; j< array.columns(); j++)
159  os << array(i,j) << ' ';
160 
161  os << std::endl;
162  }
163  return os;
164 }
void enlarge(unsigned int m, unsigned int n)
Resizes and pads with zeros; keeps existing data.
Contains class for a 2d bit array; interface as vbl_array_2d<T>
vbl_bit_array_2d & operator=(vbl_bit_array_2d const &)
Assignment operator.
bool operator()(unsigned int i, unsigned int j) const
unsigned char * data_
unsigned int num_rows_
bool operator==(vbl_bit_array_2d const &a) const
Comparison.
bool get(unsigned int i, unsigned int j) const
void construct(unsigned int m, unsigned int n)
void resize(unsigned int m, unsigned int n)
Delete contents and resize to m rows x n cols.
unsigned int cols() const
simple 2D bit array.
unsigned long size() const
Number of bytes allocated by the data.
unsigned int num_cols_
std::ostream & operator<<(std::ostream &os, const vbl_bit_array_2d &array)
void put(unsigned int i, unsigned int j, bool const &x)
void set(unsigned int i, unsigned int j, bool v=true)
Set the value of a cell; default is to set the value on.
void index(unsigned int x, unsigned int y, unsigned long &byteindex, unsigned int &bitindex) const
void fill(bool value)
Fill with value.
unsigned int columns() const
unsigned int rows() const