aimstil  5.0.5
ImageC.h
Go to the documentation of this file.
1 #ifndef TIL_IMAGEC_H
2 #define TIL_IMAGEC_H
3 
4 // Includes from STL
5 #include <cstring>
6 #include <iostream>
7 #include <limits>
8 #include <stdexcept>
9 #include <vector>
10 
11 // Includes from BOOST
12 #include <boost/shared_array.hpp>
13 
14 // Include from TIL library
15 #include "til/image_common.h"
16 #include "til/ImageBase.h"
17 #include "til/imageTools.h"
18 #include "til/numeric_array.h"
19 
20 // Package includes
21 #include "til/imageIterator.h"
26 
27 
28 // Ignore specific warnings
29 #ifdef _MSC_VER
30 #pragma warning (push)
31 #pragma warning (disable:4244)
32 #endif
33 
34 namespace til
35 {
36 
38 
39 template < typename T >
40 class ImageC : public ImageBase
41 {
42 
43 public: // typedefs
44 
45  typedef ImageC<T> Self;
46  typedef T value_type;
47 
48 
49 public: // constructors & destructor
50 
51  ImageC();
53  ImageC(const ImageParameter &param);
55 
57  ImageC(const Self & im)
58  {
59  this->shallowCopy(im);
60  }
61 
62  /*
66  static Self* New() { return new Self(); }
68  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); }
70  static Self* New(const numeric_array<int,3> &dim, const numeric_array<t_voxsize,3> &vDim) {return new Self(dim, vDim); }
72  static Self* New(const ImageParameter &param) { return new Self(param); }
77  static Self* New(value_type *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); }
78  */
79 
81  ~ImageC();
82 
83 
84 public: // initialization
85 
86  // Initialization functions
87  // Basically similar to constructors
88  //void init(int x, int y, int z, t_voxsize vx, t_voxsize vy, t_voxsize vz);
89  //void init(T *data, int x, int y, int z, t_voxsize vx, t_voxsize vy, t_voxsize vz);
90  void init(T * data, const numeric_array<int,3> & dim, const numeric_array<t_voxsize,3> & vdim);
91  void init(const numeric_array<int,3> & dim, const numeric_array<t_voxsize,3> & vdim);
92  void init(const Self &im);
93  void init(const ImageParameter &param);
94 
95 
96 public: // functions
97 
98  // Get value
99 
100  // Access (read-write) the value at point (i,j,k)
101  // Range checking is done
102  //T & operator()(int i, int j, int k) { return *(this->getPointerOf(i,j,k)); }
103  T & operator()(const numeric_array<int,3> & p) { return *(this->getPointerOf(p)); }
104  const T & operator()(const numeric_array<int,3> & p) const { return *(this->getPointerOf(p)); }
105 
106  // Set value
107  //void setValue(const T & v, int i, int j, int k) { *(this->getPointerOf(i,j,k)) = v; }
108  void setValue(const T & v, const numeric_array<int,3> &p) { (*this)(p)=v; }
109 
110  // Get the value at point (i,j,k) for read-only purpose
111  // If point lies outside image, an exception is thrown
112  //INLINE T getValue(int i, int j, int k) const;
113  //T getValue(const numeric_array<int,3> &v) const { return this->getValue(EXPAND_VECTOR(v)); }
114 
115  // Get the value at point (i,j,k) for fast read-only purpose
116  // WARNING: No range checking!
117  //INLINE T getUnsafeValue(int i, int j, int k) const;
118  T getUnsafeValue(const numeric_array<int,3> & p) const { return *(this->getUnsafePointerOf(p)); }
119 
120 
121  // Get pointer to data
122  // Use to quickly port existing code
123  // For any other job, use operator(), getValue, or iterators
124 
125  // For very dirty jobs only
126  T * getPointer() { return m_data.get(); }
127  const T * getPointer() const { return m_data.get(); }
128  // For dirty jobs that do not mess with the data
129  //const value_type* getConstPointer() const { return m_data.get();}
130  // For dirty jobs that want range checking
131  //INLINE const value_type* getConstPointerOf(int i, int j, int k) const;
132 
134  bool isAllocated() const { return (m_data!=0);}
135 
136  // TODO: myreset should become reset, reset should become clear
137  void myreset()
138  {
139  this->init();
140  }
141 
143  void reset();
144 
153  void copy(const Self & im);
154 
155 
159  void shallowCopy(const Self & im)
160  {
161  this->init(param(im));
162  m_data = im.m_data;
163  }
164 
165 public: // operators
166 
167 
169  bool operator!=(const Self & im) const
170  {
171  return m_data != im.m_data;
172  }
174  bool operator==(const Self & im) const
175  {
176  return m_data == im.m_data;
177  }
178 
179 
180 public: // friends
181 
182  friend class ConstVolumetricIterator<Self>;
183  // yields an internal compiler error under MSVC7.1
184  /*
185  template < class TImage>
186  friend typename enable_if_c<is_Image<TImage>::value, bool>::type
187  operator==(const TImage &im1, const TImage &im2);
188  template < class TImage>
189  friend typename enable_if_c<is_Image<TImage>::value, bool>::type
190  operator!=(const TImage &im1, const TImage &im2);
191  */
192 
193 private: // constructors
194 
196  ImageC(const Self *);
197 
198 
199 private: // methods
200 
201  void init();
202 
203  // Unsafe but fast access
204  //T * getUnsafePointerOf(int i, int j, int k) { return this->getPointer() + i + this->dim()[0] * ( j + this->dim()[1]*k); }
205  T * getUnsafePointerOf(const numeric_array<int,3> & p)
206  {
207  return this->getPointer() + p[0] + this->dim()[0] * ( p[1] + this->dim()[1] * p[2]);
208  }
209  const T * getUnsafePointerOf(const numeric_array<int,3> & p) const
210  {
211  return this->getPointer() + p[0] + this->dim()[0] * ( p[1] + this->dim()[1] * p[2]);
212  }
213  T * getUnsafePointerOf(int n) { return this->getPointer() + n;}
214  //const T * getUnsafePointerOf(int i, int j, int k) const { return this->getPointer() + i + this->dim()[0] * ( j + this->dim()[1]*k); }
215  const T * getUnsafePointerOf(int n) const { return this->getPointer() + n;}
216 
217  /*
218  T * getPointerOf(int i, int j, int k)
219  {
220  if (!this->contains(i,j,k))
221  {
222  return 0;
223  }
224  return this->getUnsafePointerOf(i,j,k);
225  }
226  */
227 
228 
229  T * getPointerOf(const numeric_array<int,3> & p)
230  {
231  if (!this->contains(p)) return 0;
232  return this->getUnsafePointerOf(p);
233  }
234 
235  const T * getPointerOf(const numeric_array<int,3> & p) const
236  {
237  if (!this->contains(p)) return 0;
238  return this->getUnsafePointerOf(p);
239  }
240 
241  void setData(T * data)
242  {
243  //if (m_data == data) return;
244  //if (m_data) delete [] m_data;
245  //m_data = data;
246  m_data.reset(data);
247  }
248 
249  // Copy constructor is intentionally left undefined
250  // Non-explicit image copying is unwanted!
251  // use copy instead
252 
253 private: // data
254 
255  // Pointer to data
256  boost::shared_array<T> m_data;
257 };
258 
259 
261 template < typename T >
262 struct Iterator< ImageC<T> >
263 {
268 };
269 
270 
271 
272 // Constructors
273 
274 template < typename T >
275 ImageC<T>::ImageC() : ImageBase(), m_data(0)
276 {
277  this->init();
278 }
279 
280 
281 
282 template < typename T >
283 void ImageC<T>::init()
284 {
285  // Null buffer, zero dimension, zero voxel size
286  this->init(numeric_array<int,3>(0,0,0), numeric_array<t_voxsize,3>(0,0,0));
287 }
288 
289 
290 /*
291 template < typename T >
292 ImageC<T>::ImageC(int x, int y, int z, t_voxsize vx, t_voxsize vy, t_voxsize vz) : ImageBase(), m_data(0)
293 
294 {
295  this->init(x, y, z, vx, vy, vz);
296 }
297 */
298 
299 
300 template < typename T >
301 void ImageC<T>::init
302 (
303  const numeric_array<int,3> & dim,
304  const numeric_array<t_voxsize,3> & vdim
305 )
306 {
307  // NB: no catch(std::bad_alloc& ex) is done here
308  T * data = new T[dim[0]*dim[1]*dim[2]];
309  this->init(data, dim, vdim);
310  this->reset();
311 }
312 
313 
314 template < typename T >
316 {
317  this->init(dim, vDim);
318 }
319 
320 
321 template < typename T >
322 ImageC<T>::ImageC(const ImageParameter &param) : ImageBase(), m_data(0)
323 {
324  this->init(param);
325 }
326 
327 
328 template < typename T >
329 void ImageC<T>::init(const ImageParameter &param)
330 {
331  this->init(param.m_dim, param.m_vDim);
332  //this->setOrigin(param.m_ori);
333 }
334 
335 
336 template < typename T >
337 ImageC<T>::ImageC(T *data, const numeric_array<int,3> & dim, const numeric_array<t_voxsize,3> & vdim) : ImageBase(), m_data(0)
338 {
339  this->init(data, dim, vdim);
340 }
341 
342 
343 
344 template < typename T >
345 void ImageC<T>::init(T *data, const numeric_array<int,3> & dim, const numeric_array<t_voxsize,3> & vdim)
346 {
347  this->set_dim(dim);
348  this->set_vdim(vdim);
349  this->setData(data);
350 }
351 
352 
353 /*
354 template < typename T >
355 ImageC<T>::ImageC(const ImageC<T> & im) : ImageBase(), m_data(0)
356 {
357  this->init(im);
358 }
359 */
360 
361 // I comment this first to see if anybody is using this function.
362 // If not then I can safely change its content to shallowCopy
363 /*
364 template < typename T >
365 void ImageC<T>::init(const ImageC<T> & im)
366 {
367 
368  this->init(param(im));
369  memcpy((void*)this->getPointer(),
370  (void*)im.getPointer(),
371  im.size()*sizeof(T));
372 
373 }
374 */
375 
376 template < typename T >
378 {
379  // NB: deleting a null pointer is also safe
380  // delete[] m_data;
381 }
382 
383 
384 
385 template < typename T >
387 {
388  // use a memset for numeric types only
389  if (std::numeric_limits<T>::is_specialized)
390  {
391  memset((void*)this->getPointer(), 0, this->size()*sizeof(T));
392  }
393  // For other types, just use a regular loop with default constructor
394  else
395  {
396  for (int i = 0; i < this->size(); ++i)
397  {
398  m_data[i] = T();
399  }
400  }
401 }
402 
403 
404 /*
405 template < typename T >
406 INLINE const T* ImageC<T>::getConstPointerOf(int i, int j, int k) const
407 {
408  return this->getPointerOf(i,j,k);
409 }
410 */
411 
412 /*
413 template < typename T >
414 INLINE T ImageC<T>::getValue(int i, int j, int k) const
415 {
416  if (this->contains(i,j,k))
417  {
418  return this->getUnsafeValue(i,j,k);
419  }
420  else
421  {
422  throw std::out_of_range("Position out of image range");
423  }
424 }
425 */
426 
427 /*
428 template < typename T >
429 INLINE T ImageC<T>::getUnsafeValue(int i, int j, int k) const
430 {
431  return *(this->getUnsafePointerOf(i,j,k));
432 }
433 */
434 
435 template < typename T >
436 void ImageC<T>::copy(const ImageC<T> &im)
437 {
438 
439  if (!(this->isAllocated() && til::isAllocated(im)))
440  {
441  throw std::invalid_argument("Unallocated image");
442  }
443 
444  if (!((this->dim()[0] == im.dim()[0]) &&
445  (this->dim()[1] == im.dim()[1]) &&
446  (this->dim()[2] == im.dim()[2]) &&
447  (this->vdim()[0] == im.vdim()[0]) &&
448  (this->vdim()[1] == im.vdim()[1]) &&
449  (this->vdim()[2] == im.vdim()[2])))
450  {
451  throw std::invalid_argument("Incompatible images");
452  }
453 
454  memcpy(
455  (void*)this->getPointer(),
456  (void*)(const_cast<T*>(im.getPointer())),
457  im.size()*sizeof(T));
458 }
459 
460 
461 } // namespace
462 
463 
464 #ifdef _MSC_VER
465 #pragma warning (pop)
466 #endif
467 
468 #endif
469 
A trait class to assign iterators to image types.
bool contains(const numeric_array< int, 3 > &p) const
Definition: ImageBase.h:86
bool isAllocated() const
Check whether data has been allocated or not.
Definition: ImageC.h:134
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
ConstLinearIterator< ImageC< T > > ConstLinear
Definition: ImageC.h:264
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
~ImageC()
Destructor.
Definition: ImageC.h:377
void reset()
Set all values to default value (0 for numerical types)
Definition: ImageC.h:386
Belongs to package Box Do not include directly, include til/Box.h instead.
Definition: Accumulator.h:10
ImageC< T > Self
Definition: ImageC.h:45
Small miscellaneous utility functions for images.
T getUnsafeValue(const numeric_array< int, 3 > &p) const
Definition: ImageC.h:118
numeric_array< t_voxsize, 3 > m_vDim
Voxel size.
Definition: image_common.h:25
void setValue(const T &v, const numeric_array< int, 3 > &p)
Definition: ImageC.h:108
void set_vdim(const numeric_array< t_voxsize, 3 > &vdim)
Set the voxel coordinates.
Definition: ImageBase.h:58
LinearIterator< ImageC< T > > Linear
Definition: ImageC.h:266
bool operator==(const Self &im) const
Check whether images point on the same buffer.
Definition: ImageC.h:174
INLINE bool isAllocated(const TImage &im)
Check whether smart pointer and image are allocated.
Definition: imageTools.h:36
void copy(const Self &im)
Copy an image.
Definition: ImageC.h:436
T value_type
Definition: ImageC.h:46
T * getPointer()
Definition: ImageC.h:126
const T & operator()(const numeric_array< int, 3 > &p) const
Definition: ImageC.h:104
const numeric_array< int, 3 > & dim() const
get image dimension
Definition: ImageBase.h:34
bool operator!=(const Self &im) const
Check whether images point on the same buffer.
Definition: ImageC.h:169
Collects common code accross all image classes.
Definition: ImageBase.h:19
void myreset()
Definition: ImageC.h:137
const T * getPointer() const
Definition: ImageC.h:127
ImageC(const Self &im)
Shallow copy.
Definition: ImageC.h:57
void shallowCopy(const Self &im)
Shallow copy of an image.
Definition: ImageC.h:159
Image class using contiguous memory.
ConstVolumetricIterator< ImageC< T > > ConstVolumetric
Definition: ImageC.h:265
VolumetricIterator< ImageC< T > > Volumetric
Definition: ImageC.h:267
void init(T *data, const numeric_array< int, 3 > &dim, const numeric_array< t_voxsize, 3 > &vdim)
Definition: ImageC.h:345
T & operator()(const numeric_array< int, 3 > &p)
Definition: ImageC.h:103
int size() const
Get total number of elements in image.
Definition: ImageBase.h:38
numeric_array< int, 3 > m_dim
Image dimensions.
Definition: image_common.h:22