vbl_bit_array_3d.cxx
Go to the documentation of this file.
1 // This is core/vbl/vbl_bit_array_3d.cxx
2 //:
3 // \file
4 // \author
5 // Author: Geoffrey Cross, Oxford RRG
6 // Created: 17 Jul 99
7 //
8 //-----------------------------------------------------------------------------
9 
10 #include <cstring>
11 #include <iostream>
12 #include "vbl_bit_array_3d.h"
13 
14 #include <cassert>
15 #ifdef _MSC_VER
16 # include <vcl_msvc_warnings.h>
17 #endif
18 #include <climits>
19 
20 void vbl_bit_array_3d::put(unsigned int i1, unsigned int i2, unsigned int i3, bool v)
21 {
22  unsigned long byteindex;
23  unsigned char bitindex;
24 
25  index(i1, i2, i3, byteindex, bitindex);
26 
27  auto mask = (unsigned char)(v?(1<<bitindex):0);
28  auto nmask = (unsigned char)(~(1<<bitindex));
29 
30  data_[byteindex] = mask|(nmask & data_[byteindex]);
31 }
32 
33 void vbl_bit_array_3d::flip(unsigned int i1, unsigned int i2, unsigned int i3)
34 {
35  unsigned long byteindex;
36  unsigned char bitindex;
37 
38  index(i1, i2, i3, byteindex, bitindex);
39 
40  auto mask = (unsigned char)((data_[byteindex] & (1<<bitindex)) ? 0 : (1<<bitindex));
41  auto nmask = (unsigned char)(~(1<<bitindex));
42 
43  data_[byteindex] = mask|(nmask & data_[byteindex]);
44 }
45 
46 void vbl_bit_array_3d::fill(bool v)
47 {
48  unsigned char temp = v ? ~(unsigned char)0 : 0;
49  std::memset(data_, temp, this->size());
50 }
51 
52 bool vbl_bit_array_3d::operator() (unsigned int i1, unsigned int i2, unsigned int i3) const
53 {
54  unsigned long byteindex;
55  unsigned char bitindex;
56 
57  index(i1, i2, i3, byteindex, bitindex);
58  auto mask = (unsigned char)(1<<bitindex);
59 
60  return (data_[byteindex] & mask) != 0;
61 }
62 
63 void vbl_bit_array_3d::index(unsigned x, unsigned y, unsigned z,
64  unsigned long & byteindex,
65  unsigned char & bitindex) const
66 {
67  assert(x<row1_count_ && y<row2_count_ && z<row3_count_);
68  unsigned long i = (z*row2_count()+y)*row1_count()+x;
69 
70  byteindex = i/CHAR_BIT;
71  bitindex = (unsigned char)(i%CHAR_BIT);
72 }
73 
74 
75 ////////////////////////////////////////////////////////////////////////
76 
77 std::ostream &operator<<(std::ostream& os, vbl_bit_array_3d const& bitarray)
78 {
79  for (unsigned int i=0; i< bitarray.row3_count(); ++i)
80  {
81  for (unsigned int j=0; j< bitarray.row2_count(); ++j)
82  {
83  for (unsigned int k=0; k< bitarray.row1_count(); ++k)
84  os << (bitarray(k,j,i) ? 'x' : '.');
85  os << std::endl;
86  }
87  os << std::endl;
88  }
89  return os;
90 }
91 
92 void vbl_bit_array_3d::construct(unsigned int m, unsigned int n, unsigned int p)
93 {
94  // quick return if possible
95  if (m==0 || n==0 || p==0) { row1_count_=row2_count_=row3_count_=0; data_ = nullptr; return; }
96  row1_count_ = m; row2_count_ = n; row3_count_ = p;
97  data_ = new unsigned char [this->size()];
98  data_[this->size()-1]=0; // avoids uninitialized data problems in operator==()
99 }
100 
101 //: Copy constructor
103  : row1_count_(0), row2_count_(0), row3_count_(0), data_(nullptr)
104 {
105  if ( that.data_)
106  {
107  construct(that.row1_count_, that.row2_count_, that.row3_count_);
108  std::memcpy(data_, that.data_, this->size());
109  }
110 }
112 vbl_bit_array_3d::vbl_bit_array_3d(unsigned int m, unsigned int n, unsigned int p, bool v[])
113 {
114  construct(m,n,p);
115  for (unsigned int x=0; x<m; ++x)
116  for (unsigned int y=0; y<n; ++y)
117  for (unsigned int z=0; z<p; ++z)
118  set(x,y,z, v[(n*z+y)*m+x]);
119 }
120 
121 //: Assignment operator
123 {
124  if (row1_count_ != that.row1_count() ||
125  row2_count_ != that.row2_count() ||
126  row3_count_ != that.row3_count())
127  resize(that.row1_count_, that.row2_count_, that.row3_count_);
128 
129  std::memcpy(data_, that.data_, this->size());
130  return *this;
131 }
134 {
135  if (row1_count_ != a.row1_count() ||
136  row2_count_ != a.row2_count() ||
137  row3_count_ != a.row3_count())
138  return false;
139  return 0 == std::memcmp(data_, a.data_, this->size());
140 }
142 unsigned long vbl_bit_array_3d::size() const
143 {
144  return (row1_count_*row2_count_*row3_count_+CHAR_BIT-1)/CHAR_BIT;
145 }
void flip(unsigned int i1, unsigned int i2, unsigned int i3)
Change the value of a cell.
unsigned int row2_count_
void index(unsigned int x, unsigned int y, unsigned int z, unsigned long &byteindex, unsigned char &bitindex) const
vbl_bit_array_3d & operator=(vbl_bit_array_3d const &)
Assignment operator.
bool operator==(vbl_bit_array_3d const &a) const
Comparison.
void resize(unsigned int m, unsigned int n, unsigned int p)
Delete contents and resize to m rows x n cols x p layers.
void set(unsigned int i1, unsigned int i2, unsigned int i3, bool v=true)
Set the value of a cell; default is to set the value on.
vbl_bit_array_3d(unsigned int sizex, unsigned int sizey, unsigned int sizez)
Create a bitarray of the specified size, without initialising elements.
unsigned int row1_count_
contains classes vbl_bit_array_3d_base and vbl_bit_array_3d
void put(unsigned int i1, unsigned int i2, unsigned int i3, bool v)
Set the value of a cell.
unsigned int row1_count() const
unsigned int row3_count() const
void fill(bool v)
Set all cell values to v.
void construct(unsigned int m, unsigned int n, unsigned int p)
bool operator()(unsigned int i1, unsigned int i2, unsigned int i3) const
Return the value of a cell.
unsigned int row2_count() const
unsigned int row3_count_
unsigned char * data_
std::ostream & operator<<(std::ostream &os, vbl_bit_array_3d const &bitarray)
unsigned long size() const
Number of bytes allocated by the data.