aimstil  5.0.5
ImageNC.h
Go to the documentation of this file.
1 #ifndef TIL_IMAGENC_H
2 #define TIL_IMAGENC_H
3 
4 
5 // Includes from STL
6 #include <float.h>
7 #include <limits.h>
8 #include <string.h>
9 #include <vector>
10 #include <iostream>
11 
12 
13 // Includes from TIL library
14 #include "til/til_common.h"
15 #include "til/Box.h"
16 #include "til/ImageBase.h"
17 #include "til/image_common.h"
18 
23 
24 
25 // Namespace
26 
27 namespace til {
28 
29 
31 
32 template < typename T >
33 class ImageNC : public ImageBase
34 {
35 private: // typedefs
36 
37  typedef T** Buffer;
38 
39 public: // typedefs
40 
41  typedef ImageNC<T> Self;
42  typedef T value_type;
43 
44 
45 public: // constructors & destructor
46 
47  ImageNC();
48  ImageNC(int x, int y, int z, t_voxsize vx, t_voxsize vy, t_voxsize vz);
50  ImageNC(T *data, int x, int y, int z, t_voxsize vx, t_voxsize vy, t_voxsize vz);
51  ImageNC(T **data, int x, int y, int z, t_voxsize vx, t_voxsize vy, t_voxsize vz);
52  ImageNC(const std::vector<T*> & slices, int x, int y, t_voxsize vx, t_voxsize vy, t_voxsize vz);
53  ImageNC(const ImageParameter & param);
54  ImageNC(const ImageNC<T> *);
55 
56  /*
59  static Self* New() { return new Self(); }
61  static Self* New(int x, int y, int z, t_voxsize vx, t_voxsize vy, t_voxsize vz) { return new Self(x,y,z,vx,vy,vz); }
63  static Self* New(const Vector<int,3> &dim, const Vector<t_voxsize,3> &vDim) { return new Self(dim,vDim); }
68  static Self* New(T *data, int x, int y, int z, t_voxsize vx, t_voxsize vy, t_voxsize vz) { return new Self(data,x,y,z,vx,vy,vz); }
69  static Self* New(T **data, int x, int y, int z, t_voxsize vx, t_voxsize vy, t_voxsize vz) {return new Self(data,x,y,z,vx,vy,vz); }
72  static Self* New(const std::vector<T*> & slices, int x, int y, t_voxsize vx, t_voxsize vy, t_voxsize vz) { return new Self(slices,x,y,vx,vy,vz); }
74  static Self* New(const ImageParameter & param) { return new Self(param); }
75  */
76 
78  ~ImageNC();
79 
80 
81 public: // initialization
82 
83  // Initialization functions
84  // Basically similar to constructors
85  void init();
86  void init(int x, int y, int z, t_voxsize vx, t_voxsize vy, t_voxsize vz);
87  void init(T *data, int x, int y, int z, t_voxsize vx, t_voxsize vy, t_voxsize vz);
88  void init(T **data, int x, int y, int z, t_voxsize vx, t_voxsize vy, t_voxsize vz);
89  void init(const numeric_array<int,3> &dim, const numeric_array<t_voxsize,3> &vDim);
90  void init(const std::vector<T*> & slices, int x, int y, t_voxsize vx, t_voxsize vy, t_voxsize vz);
91  void init(const ImageNC<T> *);
92  void init(const ImageParameter &param);
93 
94 public: // functions
95 
96  void setValue(const T & value, int i, int j, int k)
97  {
98  *(this->getUnsafePointerOf(i,j,k)) = value;
99  }
100  void setValue(const T & value, const numeric_array<int,3> & p)
101  {
102  *(this->getUnsafePointerOf(p)) = value;
103  }
104 
105  // Get value
106 
107  // Access (read-write) the value at point (i,j,k)
108  // Range checking is done
109  INLINE T& operator()(int i, int j, int k);
110  T& operator()(const numeric_array<int,3> &v) { return this->operator()(EXPAND_VECTOR(v)); }
111 
112  // Get the value at point (i,j,k) for read-only purpose
113  // If point lies outside image, an exception is thrown
114  INLINE const T getValue(int i, int j, int k) const;
115  const T getValue(const numeric_array<int,3> &v) const { return this->getValue(EXPAND_VECTOR(v)); }
116 
117  // Get the value at point (i,j,k) for fast read-only purpose
118  // WARNING: No range checking!
119  INLINE const T getUnsafeValue(int i, int j, int k) const;
120  const T getUnsafeValue(const numeric_array<int,3> &v) const { return this->getUnsafeValue(EXPAND_VECTOR(v)); }
121 
122 
123 public: // functions
124 
125  // Check whether data has been allocated or not
126  bool isAllocated() const { return (m_data!=0);}
127 
128  // Set all values to zero
129  void reset();
130 
131  void copy(const Self &im)
132  {
133  if (!((this->dim()[0] == im.dim()[0]) &&
134  (this->dim()[1] == im.dim()[1]) &&
135  (this->dim()[2] == im.dim()[2]) &&
136  (this->vdim()[0] == im.vdim()[0]) &&
137  (this->vdim()[1] == im.vdim()[1]) &&
138  (this->vdim()[2] == im.vdim()[2])))
139  {
140  throw std::invalid_argument("Incompatible images");
141  }
142 
143  // TODO: Replace this by iterators
144  for (int i = 0; i < this->dim()[2]; ++i)
145  {
146  memcpy(
147  (void*)this->getUnsafeSlicePointer(i),
148  (void*)(const_cast<T*>(im.getUnsafeSlicePointer(i))),
149  im.getSliceSize()*sizeof(T));
150  }
151  }
152 
153 public: // operators
154 
156  bool operator!=(const Self & im) const
157  {
158  return m_data != im.m_data;
159  }
161  bool operator==(const Self & im) const
162  {
163  return m_data == im.m_data;
164  }
165 
166 
167 public: // friends
168 
169  friend class ConstVolumetricIterator<Self>;
170  friend class ConstLinearIterator<Self>;
171 
172 
173 private: // methods
174 
175  // Get pointer to data
176  // Use to quickly port existing code
177  // For any other job, use operator(), getValue, or iterators
178 
179  // For very dirty jobs only
180  //T** getPointer() { return m_data;}
181  // For dirty jobs that do not mess with the data
182  //const T* const * getConstPointer() const { return m_data;}
183  // For dirty jobs that want range checking
184  //const T* getConstPointerOf(int i, int j, int k) const;
185 
186  const T* getUnsafeSlicePointer(int i) const { return m_data[i]; }
187  T* getUnsafeSlicePointer(int i) { return m_data[i]; }
188 
189  const T* getSlicePointer(int i) const
190  {
191  if (i < 0 || i >= this->dim()[2])
192  {
193  throw std::out_of_range("Slice number out of range");
194  }
195  return this->getUnsafeSlicePointer(i);
196  }
197 
198  //TODO: find a way to optimize those duplicate const/non-const get functions
199  T* getSlicePointer(int i)
200  {
201  if (i < 0 || i >= this->dim()[2])
202  {
203  throw std::out_of_range("Slice number out of range");
204  }
205  return this->getUnsafeSlicePointer(i);
206  }
207 
208 
209  // Unsafe but fast access
210  T* getUnsafePointerOf(int i, int j, int k) const { return m_data[k] + i + this->dim()[0] * j; }
211  T* getUnsafePointerOf(const numeric_array<int,3> &v) const { return this->getUnsafePointerOf(EXPAND_VECTOR(v)); }
212 
213  T* getPointerOf(int i, int j, int k) const
214  {
215  if (!this->contains(numeric_array<int,3>(i,j,k)))
216  {
217  return 0;
218  }
219  return this->getUnsafePointerOf(i,j,k);
220  }
221  T* getPointerOf(const numeric_array<int,3> &v) const { return this->getPointerOf(EXPAND_VECTOR(v)); }
222 
223  void setData(T** data)
224  {
225  if (m_data == data) return;
226  if (m_data) this->deallocateData();
227  m_data = data;
228  }
229 
230  void setData(const std::vector<T*> & slices)
231  {
232  if (m_data) this->deallocateData();
233  m_data = new T*[slices.size()];
234 
235  for (int i=0; i < slices.size(); ++i)
236  {
237  m_data[i] = slices[i];
238  }
239  }
240 
241  void allocateData()
242  {
243  if ( this->dim()[0]<0 || this->dim()[1]<0 || this->dim()[2]<0)
244  {
245  throw std::invalid_argument("Image size < 0");
246  }
247  m_data = new T*[this->dim()[2]];
248  for (int i = 0; i < this->dim()[2]; ++i)
249  {
250  m_data[i] = new T[this->getSliceSize()];
251  }
252  }
253 
254  void deallocateData()
255  {
256  for (int i=0; i < this->dim()[2]; ++i)
257  {
258  delete [] m_data[i];
259  }
260  delete [] m_data;
261  m_data = 0;
262  }
263 
264  // Common operations done in init methods
265  void _init(int x, int y, int z, t_voxsize vx, t_voxsize vy, t_voxsize vz);
266 
267  // Get number of element in a slice
268  int getSliceSize() const { return this->dim()[0] * this->dim()[1]; }
269 
270  // Copy constructor is intentionally left undefined
271  // Non-explicit image copying is unwanted!
272  // use copy instead
273  ImageNC(const ImageNC<T> &);
274 
275 private: // data
276 
277  // Double pointer to data
278  Buffer m_data;
279 };
280 
281 
283 template < typename T >
284 struct Iterator<ImageNC<T> >
285 {
290 };
291 
292 
293 
294 
295 
296 
297 
298 
299 
300 
301 
302 
303 
304 
305 
306 
307 
308 
309 
310 
311 
312 
313 
314 
315 
316 
317 
318 
319 
320 
321 
323 //
324 // CODE
325 //
327 
328 
329 // Constructors
330 
331 template < typename T >
333 {
334  this->init();
335 }
336 
337 
338 
339 template < typename T >
341 {
342  m_data = 0;
343 }
344 
345 
346 
347 template < typename T >
348 ImageNC<T>::ImageNC(int x, int y, int z, t_voxsize vx, t_voxsize vy, t_voxsize vz) : ImageBase(), m_data(0)
349 {
350  this->init(x, y, z, vx, vy, vz);
351 }
352 
353 
354 
355 template < typename T >
356 void ImageNC<T>::init(int x, int y, int z, t_voxsize vx, t_voxsize vy, t_voxsize vz)
357 {
358  this->_init(x, y, z, vx, vy, vz);
359  this->allocateData();
360  this->reset();
361 }
362 
363 
364 
365 template < typename T >
367 {
368  this->init(dim, vDim);
369 }
370 
371 
372 
373 template < typename T >
375 {
376  this->init(EXPAND_VECTOR(dim), EXPAND_VECTOR(vDim));
377 }
378 
379 
380 template < typename T >
382 {
383  this->init(param);
384 }
385 
386 
387 template < typename T >
389 {
390  this->init(param.m_dim, param.m_vDim);
391  //this->setOrigin(param.m_ori);
392 }
393 
394 template < typename T >
395 ImageNC<T>::ImageNC(T *data, int x, int y, int z, t_voxsize vx, t_voxsize vy, t_voxsize vz) : ImageBase(), m_data(0)
396 {
397  this->init(data, x, y, z, vx, vy, vz);
398 }
399 
400 
401 template < typename T >
402 void ImageNC<T>::_init(int x, int y, int z, t_voxsize vx, t_voxsize vy, t_voxsize vz)
403 {
404  this->set_dim(til::numeric_array<int,3>(x, y, z));
405  this->set_vdim(til::numeric_array<float,3>(vx, vy, vz));
406 }
407 
408 
409 template < typename T >
410 void ImageNC<T>::init(T *data, int x, int y, int z, t_voxsize vx, t_voxsize vy, t_voxsize vz)
411 {
412  this->_init(x, y, z, vx, vy, vz);
413  T** data2 = simple2DoublePointer(data, x, y, z);
414  this->setData(data2);
415 }
416 
417 template < typename T >
418 ImageNC<T>::ImageNC(T **data, int x, int y, int z, t_voxsize vx, t_voxsize vy, t_voxsize vz) : ImageBase(), m_data(0)
419 {
420  this->init(data, x, y, z, vx, vy, vz);
421 }
422 
423 template < typename T >
424 void ImageNC<T>::init(T **data, int x, int y, int z, t_voxsize vx, t_voxsize vy, t_voxsize vz)
425 {
426  this->_init(x, y, z, vx, vy, vz);
427  this->setData(data);
428 }
429 
430 template < typename T >
431 ImageNC<T>::ImageNC(const std::vector<T*> & slices, int x, int y, t_voxsize vx, t_voxsize vy, t_voxsize vz) : ImageBase(), m_data(0)
432 {
433  this->init(slices, x, y, vx, vy, vz);
434 }
435 
436 template < typename T >
437 void ImageNC<T>::init(const std::vector<T*> & slices, int x, int y, t_voxsize vx, t_voxsize vy, t_voxsize vz)
438 {
439  this->_init(x, y, slices.size(), vx, vy, vz);
440  this->setData(slices);
441 }
442 
443 template < typename T >
444 ImageNC<T>::ImageNC(const ImageNC<T> *pIm) : ImageBase(), m_data(0)
445 {
446  this->init(pIm);
447 }
448 
449 template < typename T >
450 void ImageNC<T>::init(const ImageNC<T> *pIm)
451 {
452  this->init(param(pIm));
453 
454  for (int i = 0; i < this->getZ(); ++i)
455  {
456  memcpy(
457  (void*)this->getUnsafeSlicePointer(i),
458  (void*)pIm.getUnsafeConstSlicePointer(i),
459  pIm.getSliceSize()*sizeof(T));
460  }
461 }
462 
463 
464 template < typename T >
466 {
467  this->deallocateData();
468 }
469 
470 
471 template < typename T >
473 {
474  for (int i=0; i<this->dim()[2]; ++i)
475  {
476  memset((void*)this->getUnsafeSlicePointer(i), 0, this->getSliceSize()*sizeof(T));
477  }
478 }
479 
480 
481 
482 template < typename T >
483 INLINE T& ImageNC<T>::operator()(int i, int j, int k)
484 {
485  return *(this->getPointerOf(i,j,k));
486 }
487 
488 
489 
490 //template < typename T >
491 //const T* ImageNC<T>::getConstPointerOf(int i, int j, int k) const
492 //{
493 // return this->getPointerOf(i,j,k);
494 //}
495 
496 
497 
498 template < typename T >
499 INLINE const T ImageNC<T>::getValue(int i, int j, int k) const
500 {
501  if (this->contains(numeric_array<int,3>(i,j,k)))
502  {
503  return this->getUnsafeValue(i,j,k);
504  }
505  else
506  {
507  throw std::out_of_range("Position out of image range");
508  }
509 }
510 
511 
512 template < typename T >
513 INLINE const T ImageNC<T>::getUnsafeValue(int i, int j, int k) const
514 {
515  return *(this->getUnsafePointerOf(i,j,k));
516 }
517 
518 
519 } // namespace
520 
521 #endif
522 
A trait class to assign iterators to image types.
const T getUnsafeValue(const numeric_array< int, 3 > &v) const
Definition: ImageNC.h:120
INLINE const T getValue(int i, int j, int k) const
Definition: ImageNC.h:499
void setValue(const T &value, int i, int j, int k)
Definition: ImageNC.h:96
bool contains(const numeric_array< int, 3 > &p) const
Definition: ImageBase.h:86
void set_dim(const numeric_array< int, 3 > &dim)
Definition: ImageBase.h:66
const numeric_array< t_voxsize, 3 > & vdim() const
get voxel size
Definition: ImageBase.h:49
#define EXPAND_VECTOR(v)
Definition: til_common.h:54
INLINE T & operator()(int i, int j, int k)
Definition: ImageNC.h:483
ImageParameter param(const TImage &im)
Create an ImageParameter structure out of an Image.
Definition: image_common.h:34
Collects image information to create similar images.
Definition: image_common.h:19
LinearIterator< ImageNC< T > > Linear
Definition: ImageNC.h:288
VolumetricIterator< ImageNC< T > > Volumetric
Definition: ImageNC.h:289
Belongs to package Box Do not include directly, include til/Box.h instead.
Definition: Accumulator.h:10
T value_type
Definition: ImageNC.h:42
General macros, definitions and functions.
bool operator!=(const Self &im) const
Check whether images point on the same buffer.
Definition: ImageNC.h:156
void reset()
Definition: ImageNC.h:472
numeric_array< t_voxsize, 3 > m_vDim
Voxel size.
Definition: image_common.h:25
INLINE const T getUnsafeValue(int i, int j, int k) const
Definition: ImageNC.h:513
void setValue(const T &value, const numeric_array< int, 3 > &p)
Definition: ImageNC.h:100
void set_vdim(const numeric_array< t_voxsize, 3 > &vdim)
Set the voxel coordinates.
Definition: ImageBase.h:58
#define INLINE
Definition: til_common.h:26
ConstLinearIterator< ImageNC< T > > ConstLinear
Definition: ImageNC.h:286
Image class storing data slice-by-slice.
bool operator==(const Self &im) const
Check whether images point on the same buffer.
Definition: ImageNC.h:161
ImageNC< T > Self
Definition: ImageNC.h:41
~ImageNC()
Destructor.
Definition: ImageNC.h:465
ConstVolumetricIterator< ImageNC< T > > ConstVolumetric
Definition: ImageNC.h:287
const numeric_array< int, 3 > & dim() const
get image dimension
Definition: ImageBase.h:34
bool isAllocated() const
Definition: ImageNC.h:126
Collects common code accross all image classes.
Definition: ImageBase.h:19
T ** simple2DoublePointer(T *data, int x, int y, int z)
Converts a contiguous memory buffer into a per-slice buffer.
Definition: imageTools.h:514
T & operator()(const numeric_array< int, 3 > &v)
Definition: ImageNC.h:110
void copy(const Self &im)
Definition: ImageNC.h:131
float t_voxsize
type of voxel size
Definition: ImageBase.h:13
numeric_array< int, 3 > m_dim
Image dimensions.
Definition: image_common.h:22
const T getValue(const numeric_array< int, 3 > &v) const
Definition: ImageNC.h:115
void init()
Definition: ImageNC.h:340