aimstil  5.0.5
ImageBP.h
Go to the documentation of this file.
1 #ifndef TIL_IMAGEBP_H
2 #define TIL_IMAGEBP_H
3 
4 #pragma warning(disable:4244)
5 
6 
7 // Standard library includes
8 
9 #include <iostream>
10 #include <limits>
11 #include <stdexcept>
12 #include <vector>
13 
14 
15 // Local includes
16 
17 #include "til_common.h"
18 
19 #include "Box.h"
20 #include "image_common.h"
21 #include "Ptr.h"
22 #include "SmartObject.h"
23 
24 
25 #include "ConstImageBPLinearIterator.h"
26 #include "ImageBPLinearIterator.h"
27 #include "ConstImageBPVolumetricIterator.h"
28 #include "ImageBPVolumetricIterator.h"
29 
30 
31 // Namespace
32 
33 namespace til {
34 
35 
36 typedef uchar t_value;
37 
38 
39 
40 template < int N >
41 class ImageBP : public SmartObject
42 {
43 
44 public: // constructors & destructor
45 
46 
47  // Default constructor
48  // Buffer is not allocated
49  // Every other internal variables are set to zero
50  ImageBP();
51 
52 
53  // Allocate an image of dimension (x, y, z) with voxel size (vx, vy, vz)
54  ImageBP(int x, int y, int z, t_voxsize vx, t_voxsize vy, t_voxsize vz);
55 
56 
57  // Same as above, using vectors
58  ImageBP(const numeric_array<int,3> &dim, const numeric_array<t_voxsize,3> &vDim);
59 
60 
61  // Create an image of dimension (x, y, z) with voxel size (vx, vy, vz)
62  // with data 'data'
63  // NB: the data is not copied, Image is just a wrapper around
64  // the contiguous buffer (hence it is passed as t_value*, not const t_value*).
65  ImageBP(t_value *data, int x, int y, int z, t_voxsize vx, t_voxsize vy, t_voxsize vz);
66 
67 
68  // Copy pointed image
69  ImageBP(const ImageBP<N> *);
70 
71 
72  // Copy constructor is intentionally left undefined
73  // Non-explicit image copying is unwanted!
74  // use ::copy instead
75  //Image(const Image<N> &);
76 
77 
78  // Destructor
79  virtual ~ImageBP();
80 
81 
82 
83 public: // initialization
84 
85  // Initialization functions
86  // Basically similar to constructors for situations where
87  // the image already exists
88 
89  void init(int x, int y, int z, t_voxsize vx, t_voxsize vy, t_voxsize vz);
90  void init(uchar *data, int x, int y, int z, t_voxsize vx, t_voxsize vy, t_voxsize vz);
91  void init(const numeric_array<int,3> & dim, const numeric_array<t_voxsize,3> & vDim);
92  void init(const ImageBP<N> *);
93 
94 
95 public: // set & get
96 
97  // Get image size
98 
99  int getDimX() const { return m_dim.getX();}
100  int getDimY() const { return m_dim.getY();}
101  int getDimZ() const { return m_dim.getZ();}
102  int getDim(int i) const { return m_dim.get(i); }
103  const numeric_array<int,3> & getDim() const { return m_dim; }
104 
105 
106  // Get total number of elements
107 
108  int getSize() const { return this->getDimX()*this->getDimY()*this->getDimZ(); }
109 
110 
111  // Get voxel size
112 
113  t_voxsize getVx() const { return m_vDim.getX(); }
114  t_voxsize getVy() const { return m_vDim.getY(); }
115  t_voxsize getVz() const { return m_vDim.getZ(); }
116  t_voxsize getVDim(int i) const { return m_vDim.get(i); }
117  const numeric_array<t_voxsize,3> & getVDim() const { return m_vDim; }
118 
119 
120 
121 public: // functions
122 
123  // Get value
124 
125  // Access (read-write) the value at point (i,j,k)
126  // Range checking is done
127 
128  t_value& operator()(int i, int j, int k) { return *(this->getPointerOf(i,j,k)); }
129  t_value& operator()(const numeric_array<int,3> &v) { return this->operator()(EXPAND_VECTOR(v)); }
130 
131 
132  // Get the value at point (i,j,k) for read-only purpose
133  // If point lies outside image, an exception is thrown
134 
135  INLINE const t_value getValue(int i, int j, int k) const;
136  const t_value getValue(const numeric_array<int,3> &v) const { return this->getValue(EXPAND_VECTOR(v)); }
137 
138 
139  // Get the value at point (i,j,k) for fast read-only purpose
140  // WARNING: No range checking!
141 
142  INLINE const t_value getUnsafeValue(int i, int j, int k) const;
143  const t_value getUnsafeValue(const numeric_array<int,3> &v) const { return this->getUnsafeValue(EXPAND_VECTOR(v)); }
144 
145 
146  // Get pointer to data
147  // Use to quickly port existing code
148  // For any other job, use operator(), getValue, or iterators
149 
150  // For very dirty jobs only
151  t_value* getPointer() { return m_data;}
152  // For dirty jobs that do not mess with the data
153  const t_value* getConstPointer() const { return m_data;}
154  // For dirty jobs that want range checking
155  inline const t_value* getConstPointerOf(int i, int j, int k) const;
156 
157 
158  // Check whether data has been allocated or not
159 
160  bool isAllocated() const { return (m_data!=0);}
161 
162 
163  // Set all values to zero
164 
165  void reset();
166 
167  // Copy an image
168  // NB: it is put here, rather than in a separate function, for
169  // optimization reasons, that cannot be templated.
170  // using memcopy is (supposedly) much faster than any iterator.
171  // but of course the use of memcopy depends on the implementation
172  // of the class
173  // Also, there is intentionally no copy constructor or operator=
174  // in order that copy is always explicit.
175 
176  void copy(const ConstPtr<ImageBP<N> > &im);
177 
178 
179 public: // friends
180 
181  friend class ConstImageBPVolumetricIterator<N>;
182 
183 
184 public: // typedefs
185 
186  typedef t_value TPixel;
187  typedef ConstImageBPLinearIterator<N> ConstLinearIterator;
188  typedef ImageBPLinearIterator<N> LinearIterator;
189  typedef ConstImageBPVolumetricIterator<N> ConstVolumetricIterator;
190  typedef ImageBPVolumetricIterator<N> VolumetricIterator;
191 
192 
193 private: // methods
194 
195  void init();
196 
197  // Unsafe but fast access
198 
199  t_value* getUnsafePointerOf(int i, int j, int k) const { return m_data + i + m_dim.getX() * ( j + m_dim.getY()*k); }
200  t_value* getUnsafePointerOf(const numeric_array<int,3> &v) const { return this->getUnsafePointerOf(EXPAND_VECTOR(v)); }
201  t_value* getUnsafePointerOf(int n) const { return m_data + n;}
202 
203  t_value* getPointerOf(int i, int j, int k) const
204  {
205  if (!this->contains(i,j,k))
206  {
207  return 0;
208  }
209  return this->getUnsafePointerOf(i,j,k);
210  }
211  t_value* getPointerOf(const numeric_array<int,3> &v) const { return this->getPointerOf(EXPAND_VECTOR(v)); }
212 
213  void setDim(int x, int y, int z)
214  {
215  if ((x<0)||(y<0)||(z<0))
216  {
217  throw std::invalid_argument("Image size < 0");
218  }
219  m_dim.set(x, y, z);
220  }
221 
222  void setVDim(t_voxsize vx, t_voxsize vy, t_voxsize vz)
223  {
224  if ((vx<0)||(vy<0)||(vz<0))
225  {
226  throw std::invalid_argument("Voxel size < 0");
227  }
228  m_vDim.set(vx, vy, vz);
229  }
230 
231  void setData(t_value* data)
232  {
233  if (m_data == data) return;
234  if (m_data) delete [] m_data;
235  m_data = data;
236  }
237 
238 
239  // Test whether these coordinates fall into image range
240 
241  bool contains(int i, int j, int k) const
242  {
243  return (i >= 0 && j >= 0 && k >= 0 &&
244  i < m_dim.getX() &&
245  j < m_dim.getY() &&
246  k < m_dim.getZ());
247  }
248 
249 
250 private: // data
251 
252 
253  // Image dimensions
254  numeric_array<int,3> m_dim;
255 
256  // Voxel size
257  numeric_array<t_voxsize,3> m_vDim;
258 
259  // Origin
260  numeric_array<t_voxsize,3> m_ori;
261 
262  // Pointer to data
263  t_value* m_data;
264 };
265 
266 
267 
268 
269 
270 
271 
272 
273 
274 
275 
276 
277 
278 
279 
280 
281 
282 
283 
284 
285 
286 
287 
288 
289 
290 
291 
292 
293 
294 
295 
296 
298 //
299 // CODE
300 //
302 
303 
304 // Constructors
305 
306 template < int N >
307 ImageBP<N>::ImageBP() : SmartObject(), m_data(0)
308 {
309  this->init();
310 }
311 
312 
313 
314 template < int N >
315 void ImageBP<N>::init()
316 {
317  m_data = 0;
318 }
319 
320 
321 
322 template < int N >
323 ImageBP<N>::ImageBP(int x, int y, int z, t_voxsize vx, t_voxsize vy, t_voxsize vz) : SmartObject(), m_data(0)
324 {
325  this->init(x, y, z, vx, vy, vz);
326 }
327 
328 
329 
330 template < int N >
331 void ImageBP<N>::init(int x, int y, int z, t_voxsize vx, t_voxsize vy, t_voxsize vz)
332 {
333  t_value * data = new t_value[x*y*z];
334  this->init(data, x, y, z, vx, vy, vz);
335  this->reset();
336 }
337 
338 
339 
340 template < int N >
341 ImageBP<N>::ImageBP(const numeric_array<int,3> &dim, const numeric_array<t_voxsize,3> &vDim) : SmartObject(), m_data(0)
342 {
343  this->init(dim, vDim);
344 }
345 
346 
347 
348 template < int N >
349 void ImageBP<N>::init(const numeric_array<int,3> &dim, const numeric_array<t_voxsize,3> &vDim)
350 {
351  this->init(EXPAND_VECTOR(dim), EXPAND_VECTOR(vDim));
352 }
353 
354 
355 
356 template < int N >
357 ImageBP<N>::ImageBP(t_value *data, int x, int y, int z, t_voxsize vx, t_voxsize vy, t_voxsize vz) : SmartObject(), m_data(0)
358 {
359  this->init(data, x, y, z, vx, vy, vz);
360 }
361 
362 
363 
364 template < int N >
365 void ImageBP<N>::init(t_value *data, int x, int y, int z, t_voxsize vx, t_voxsize vy, t_voxsize vz)
366 {
367  this->setDim(x, y, z);
368  this->setVDim(vx, vy, vz);
369  this->setData(data);
370 }
371 
372 
373 
374 template < int N >
375 ImageBP<N>::ImageBP(const ImageBP<N> *pIm) : SmartObject(), m_data(0)
376 {
377  this->init(pIm);
378 }
379 
380 
381 
382 template < int N >
383 void ImageBP<N>::init(const ImageBP<N> *pIm)
384 {
385  this->init(param(pIm));
386  memcpy(
387  (void*)this->getPointer(),
388  (void*)pIm->getConstPointer(),
389  pIm->getSize()*sizeof(t_value));
390 }
391 
392 
393 
394 template < int N >
395 ImageBP<N>::~ImageBP()
396 {
397  // NB: deleting a null pointer is also safe
398  delete[] m_data;
399 }
400 
401 
402 
403 template < int N >
404 void ImageBP<N>::reset()
405 {
406  memset((void*)m_data, 0, this->getSize()*sizeof(t_value));
407 }
408 
409 
410 
411 template < int N >
412 INLINE const t_value* ImageBP<N>::getConstPointerOf(int i, int j, int k) const
413 {
414  return this->getPointerOf(i,j,k);
415 }
416 
417 
418 
419 template < int N >
420 INLINE const t_value ImageBP<N>::getValue(int i, int j, int k) const
421 {
422  if (this->contains(i,j,k))
423  {
424  return this->getUnsafeValue(i,j,k);
425  }
426  else
427  {
428  throw std::out_of_range("Position out of image range");
429  }
430 }
431 
432 
433 
434 template < int N >
435 INLINE const t_value ImageBP<N>::getUnsafeValue(int i, int j, int k) const
436 {
437  return *(this->getUnsafePointerOf(i,j,k));
438 }
439 
440 template < int N >
441 void ImageBP<N>::copy(const ConstPtr<ImageBP<N> > &im)
442 {
443 
444  if (!(this->isAllocated() && til::isAllocated(im)))
445  {
446  throw std::invalid_argument("Unallocated image");
447  }
448 
449  if (!((this->getDimX() == im->getDimX()) &&
450  (this->getDimY() == im->getDimY()) &&
451  (this->getDimZ() == im->getDimZ()) &&
452  (this->getVx() == im->getVx()) &&
453  (this->getVy() == im->getVy()) &&
454  (this->getVz() == im->getVz())))
455  {
456  throw std::invalid_argument("Incompatible images");
457  }
458 
459  memcpy(
460  (void*)this->getPointer(),
461  (void*)(const_cast<t_value*>(im->getConstPointer())),
462  im->getSize()*sizeof(t_value));
463 }
464 
465 
466 ) // namespace
467 
468 #endif
469 
470 
#define EXPAND_VECTOR(v)
Definition: til_common.h:54
ImageParameter param(const TImage &im)
Create an ImageParameter structure out of an Image.
Definition: image_common.h:34
Belongs to package Box Do not include directly, include til/Box.h instead.
Definition: Accumulator.h:10
General macros, definitions and functions.
#define INLINE
Definition: til_common.h:26
void copy(const TImage &in, TImage &out)
Copy one image to another.
Definition: imageTools.h:133
INLINE bool isAllocated(const TImage &im)
Check whether smart pointer and image are allocated.
Definition: imageTools.h:36
boost::enable_if< is_numeric_container< TStorage >, bool >::type contains(const Box< T, D > &box, const TStorage &v)
Check whether a point lies within box.
Definition: boxTools.h:15
float t_voxsize
type of voxel size
Definition: ImageBase.h:13
unsigned char uchar
Definition: til_common.h:75