$extrastylesheet
Olena  User documentation 2.1
An Image Processing Platform
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
core/image/image3d.hh
1 // Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013 EPITA
2 // Research and Development Laboratory (LRDE)
3 //
4 // This file is part of Olena.
5 //
6 // Olena is free software: you can redistribute it and/or modify it under
7 // the terms of the GNU General Public License as published by the Free
8 // Software Foundation, version 2 of the License.
9 //
10 // Olena is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 // General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with Olena. If not, see <http://www.gnu.org/licenses/>.
17 //
18 // As a special exception, you may use this file as part of a free
19 // software project without restriction. Specifically, if other files
20 // instantiate templates or use macros or inline functions from this
21 // file, or you compile this file and link it with other files to produce
22 // an executable, this file does not by itself cause the resulting
23 // executable to be covered by the GNU General Public License. This
24 // exception does not however invalidate any other reasons why the
25 // executable file might be covered by the GNU General Public License.
26 
27 #ifndef MLN_CORE_IMAGE_IMAGE3D_HH
28 # define MLN_CORE_IMAGE_IMAGE3D_HH
29 
33 
34 # include <mln/core/internal/fixme.hh>
35 # include <mln/core/internal/image_primary.hh>
36 # include <mln/core/alias/box3d.hh>
37 
38 # include <mln/border/thickness.hh>
39 # include <mln/value/set.hh>
40 # include <mln/fun/i2v/all_to.hh>
41 
42 // # include <mln/core/line_piter.hh>
43 
44 // FIXME:
45 
46 // # include <mln/core/pixter3d.hh>
47 // # include <mln/core/dpoints_pixter.hh>
48 
49 
50 namespace mln
51 {
52 
53  // Forward declaration.
54  template <typename T> struct image3d;
55 
56 
57 
58  namespace internal
59  {
60 
65  template <typename T>
66  struct data< image3d<T> >
67  {
68  data(const box3d& b, unsigned bdr);
69  ~data();
70 
71  T* buffer_;
72  T*** array_;
73 
74  box3d b_; // theoretical box
75  unsigned bdr_;
76  box3d vb_; // virtual box, i.e., box including the virtual border
77 
78  void update_vb_();
79  void allocate_();
80  void deallocate_();
81  void swap_ (data< image3d<T> >& other_);
82  void reallocate_(unsigned new_border);
83  };
84 
85  } // end of namespace mln::internal
86 
87 
88 
89  namespace trait
90  {
91 
92  template <typename T>
93  struct image_< image3d<T> > : default_image_< T, image3d<T> >
94  {
95  // misc
96  typedef trait::image::category::primary category;
97  typedef trait::image::speed::fastest speed;
98  typedef trait::image::size::regular size;
99 
100  // value
101  typedef trait::image::vw_io::none vw_io;
102  typedef trait::image::vw_set::none vw_set;
103  typedef trait::image::value_access::direct value_access;
104  typedef trait::image::value_storage::one_block value_storage;
105  typedef trait::image::value_browsing::site_wise_only value_browsing;
106  typedef trait::image::value_alignment::with_grid value_alignment;
107  typedef trait::image::value_io::read_write value_io;
108 
109  // site / domain
110  typedef trait::image::pw_io::read_write pw_io;
111  typedef trait::image::localization::basic_grid localization;
112  typedef trait::image::dimension::three_d dimension;
113 
114  // extended domain
115  typedef trait::image::ext_domain::extendable ext_domain;
116  typedef trait::image::ext_value::multiple ext_value;
117  typedef trait::image::ext_io::read_write ext_io;
118  };
119 
120  } // end of namespace mln::trait
121 
122 
123 
131  //
132  template <typename T>
133  struct image3d : public internal::image_primary< T, box3d, image3d<T> >
134  {
135  // Warning: just to make effective types appear in Doxygen:
136  typedef box3d pset;
137  typedef point3d psite;
138  typedef point3d point;
139  typedef dpoint3d dpoint;
140  typedef mln_fwd_piter(box3d) fwd_piter;
141  typedef mln_bkd_piter(box3d) bkd_piter;
142 // typedef line_piter_<point> line_piter;
143  // End of warning.
144 
145 
147  typedef internal::image_primary< T, box3d, image3d<T> > super_;
148 
150  typedef T value;
151 
153  typedef const T& rvalue;
154 
156  typedef T& lvalue;
157 
158 
160  typedef image3d< tag::value_<T> > skeleton;
161 
163  image3d();
164 
167  image3d(const box3d& b, unsigned bdr = border::thickness);
168 
171  image3d(int nslis, int nrows, int ncols, unsigned bdr = border::thickness);
172 
173 
176  void init_(const box3d& b, unsigned bdr = border::thickness);
178 
179 
181  bool has(const point3d& p) const;
182 
184  const box3d& domain() const;
185 
187  const box3d& bbox() const;
188 
190  const box3d& vbbox() const;
191 
193  unsigned border() const;
194 
196  unsigned nelements() const;
197 
199  const T& operator()(const point3d& p) const;
200 
202  T& operator()(const point3d& p);
203 
205  const T& element(unsigned i) const;
206 
208  T& element(unsigned i);
209 
211 
214  const T& at_(def::coord sli, def::coord row, def::coord col) const;
215 
218  T& at_(def::coord sli, def::coord row, def::coord col);
219 
221 
223  unsigned nslis() const;
224 
226  unsigned nrows() const;
227 
229  unsigned ncols() const;
230 
231 
233 
235  int delta_offset(const dpoint3d& dp) const;
236 
238  point3d point_at_offset(unsigned o) const;
239 
241  const T* buffer() const;
242 
244  T* buffer();
245 
247 
249  using super_::data_;
250 
251 
253  void resize_(unsigned new_border);
254 
256 
257  };
258 
259  template <typename T, typename J>
260  void init_(tag::image_t, mln::image3d<T>& target, const J& model);
261 
262 
263 
264 # ifndef MLN_INCLUDE_ONLY
265 
266  // init_
267 
268  template <typename T>
269  inline
270  void init_(tag::border_t, unsigned& b, const image3d<T>& model)
271  {
272  b = model.border();
273  }
274 
275  template <typename T, typename J>
276  inline
277  void init_(tag::image_t, image3d<T>& target, const J& model)
278  {
279  box3d b;
280  init_(tag::bbox, b, model);
281  unsigned bdr;
282  init_(tag::border, bdr, model);
283  target.init_(b, bdr);
284  }
285 
286 
287  // internal::data< image3d<T> >
288 
289  namespace internal
290  {
291 
292  template <typename T>
293  inline
294  data< image3d<T> >::data(const box3d& b, unsigned bdr)
295  : buffer_(0),
296  array_ (0),
297  b_ (b),
298  bdr_ (bdr)
299  {
300  allocate_();
301  }
302 
303  template <typename T>
304  inline
305  data< image3d<T> >::~data()
306  {
307  deallocate_();
308  }
309 
310  template <typename T>
311  inline
312  void
313  data< image3d<T> >::update_vb_()
314  {
315  vb_.pmin() = b_.pmin() - dpoint3d(all_to(bdr_));
316  vb_.pmax() = b_.pmax() + dpoint3d(all_to(bdr_));
317  }
318 
319  template <typename T>
320  inline
321  void
322  data< image3d<T> >::allocate_()
323  {
324  update_vb_();
325  unsigned
326  ns = vb_.len(0),
327  nr = vb_.len(1),
328  nc = vb_.len(2);
329  buffer_ = new T[nr * nc * ns];
330  array_ = new T**[ns];
331  T* buf = buffer_ - vb_.pmin().col();
332  for (unsigned i = 0; i < ns; ++i)
333  {
334  T** tmp = new T*[nr];
335  array_[i] = tmp;
336  for (unsigned j = 0; j < nr; ++j)
337  {
338  array_[i][j] = buf;
339  buf += nc;
340  }
341  array_[i] -= vb_.pmin().row();
342  }
343  array_ -= vb_.pmin().sli();
344  mln_postcondition(vb_.len(0) == b_.len(0) + 2 * bdr_);
345  }
346 
347  template <typename T>
348  inline
349  void
350  data< image3d<T> >::deallocate_()
351  {
352  if (buffer_)
353  {
354  delete[] buffer_;
355  buffer_ = 0;
356  }
357  for (typename point3d::coord i = vb_.pmin().sli(); i <= vb_.pmax().sli(); ++i)
358  {
359  if (array_[i])
360  {
361  array_[i] += vb_.pmin().row();
362  delete[] array_[i];
363  array_[i] = 0;
364  }
365  }
366  if (array_)
367  {
368  array_ += vb_.pmin().sli();
369  delete[] array_;
370  array_ = 0;
371  }
372  }
373 
374  template <typename T>
375  inline
376  void
377  data< image3d<T> >::swap_(data< image3d<T> >& other_)
378  {
379  data< image3d<T> > self_ = *this;
380  *this = other_;
381  other_ = self_;
382  }
383 
384  template <typename T>
385  inline
386  void
387  data< image3d<T> >::reallocate_(unsigned new_border)
388  {
389  data< image3d<T> >& tmp = *(new data< image3d<T> >(this->b_, new_border));
390  this->swap_(tmp);
391  }
392 
393 
394  } // end of namespace mln::internal
395 
396  // image3d<T>
397 
398  template <typename T>
399  inline
400  image3d<T>::image3d()
401  {
402  }
403 
404  template <typename T>
405  inline
406  image3d<T>::image3d(const box3d& b, unsigned bdr)
407  {
408  init_(b, bdr);
409  }
410 
411  template <typename T>
412  inline
413  image3d<T>::image3d(int nslis, int nrows, int ncols, unsigned bdr)
414  {
415  init_(make::box3d(nslis, nrows, ncols), bdr);
416  }
417 
418  template <typename T>
419  inline
420  void
421  image3d<T>::init_(const box3d& b, unsigned bdr)
422  {
423  mln_precondition(! this->is_valid());
424  this->data_ = new internal::data< image3d<T> >(b, bdr);
425  }
426 
427  template <typename T>
428  inline
429  const box3d&
430  image3d<T>::domain() const
431  {
432  mln_precondition(this->is_valid());
433  return data_->b_;
434  }
435 
436  template <typename T>
437  inline
438  const box3d&
439  image3d<T>::bbox() const
440  {
441  mln_precondition(this->is_valid());
442  return data_->b_;
443  }
444 
445  template <typename T>
446  inline
447  const box3d&
448  image3d<T>::vbbox() const
449  {
450  mln_precondition(this->is_valid());
451  return data_->vb_;
452  }
453 
454  template <typename T>
455  inline
456  unsigned
457  image3d<T>::border() const
458  {
459  mln_precondition(this->is_valid());
460  return data_->bdr_;
461  }
462 
463  template <typename T>
464  inline
465  unsigned
466  image3d<T>::nelements() const
467  {
468  mln_precondition(this->is_valid());
469  return data_->vb_.nsites();
470  }
471 
472  template <typename T>
473  inline
474  bool
475  image3d<T>::has(const point3d& p) const
476  {
477  mln_precondition(this->is_valid());
478  return data_->vb_.has(p);
479  }
480 
481  template <typename T>
482  inline
483  const T&
484  image3d<T>::operator()(const point3d& p) const
485  {
486  mln_precondition(this->has(p));
487  return data_->array_[p.sli()][p.row()][p.col()];
488  }
489 
490  template <typename T>
491  inline
492  T&
493  image3d<T>::operator()(const point3d& p)
494  {
495  mln_precondition(this->has(p));
496  return data_->array_[p.sli()][p.row()][p.col()];
497  }
498 
499  template <typename T>
500  inline
501  const T&
502  image3d<T>::element(unsigned i) const
503  {
504  mln_precondition(i < nelements());
505  return *(data_->buffer_ + i);
506  }
507 
508  template <typename T>
509  inline
510  T&
511  image3d<T>::element(unsigned i)
512  {
513  mln_precondition(i < nelements());
514  return *(data_->buffer_ + i);
515  }
516 
517  template <typename T>
518  inline
519  const T&
520  image3d<T>::at_(def::coord sli, def::coord row, def::coord col) const
521  {
522  mln_precondition(this->has(point3d(sli, row, col)));
523  return data_->array_[sli][row][col];
524  }
525 
526  template <typename T>
527  inline
528  T&
529  image3d<T>::at_(def::coord sli, def::coord row, def::coord col)
530  {
531  mln_precondition(this->has(point3d(sli, row, col)));
532  return data_->array_[sli][row][col];
533  }
534 
535  template <typename T>
536  inline
537  unsigned
538  image3d<T>::nslis() const
539  {
540  mln_precondition(this->is_valid());
541  return this->data_->b_.len(0);
542  }
543 
544  template <typename T>
545  inline
546  unsigned
547  image3d<T>::nrows() const
548  {
549  mln_precondition(this->is_valid());
550  return this->data_->b_.len(1);
551  }
552 
553  template <typename T>
554  inline
555  unsigned
556  image3d<T>::ncols() const
557  {
558  mln_precondition(this->is_valid());
559  return this->data_->b_.len(2);
560  }
561 
562  template <typename T>
563  inline
564  const T*
565  image3d<T>::buffer() const
566  {
567  mln_precondition(this->is_valid());
568  return data_->buffer_;
569  }
570 
571  template <typename T>
572  inline
573  T*
574  image3d<T>::buffer()
575  {
576  mln_precondition(this->is_valid());
577  return data_->buffer_;
578  }
579 
580  template <typename T>
581  inline
582  int
583  image3d<T>::delta_offset(const dpoint3d& dp) const
584  {
585  mln_precondition(this->is_valid());
586  int o = (dp[0] * this->data_->vb_.len(1)
587  + dp[1]) * this->data_->vb_.len(2) + dp[2];
588  return o;
589  }
590 
591  template <typename T>
592  inline
593  point3d
594  image3d<T>::point_at_offset(unsigned o) const
595  {
596  mln_precondition(o < nelements());
597  def::coord
598  sli = static_cast<def::coord>(o / (data_->vb_.len(1) * data_->vb_.len(2)) + data_->vb_.min_sli()),
599  row = static_cast<def::coord>((o % (data_->vb_.len(1) * data_->vb_.len(2))) / data_->vb_.len(2) + data_->vb_.min_row()),
600  col = static_cast<def::coord>(o % data_->vb_.len(2) + data_->vb_.min_col());
601  point3d p = point3d(sli, row, col);
602  mln_postcondition(& this->operator()(p) == this->data_->buffer_ + o);
603  return p;
604  }
605 
606  template <typename T>
607  inline
608  void
609  image3d<T>::resize_(unsigned new_border)
610  {
611  this->data_->reallocate_(new_border);
612  }
613 
614 # endif // ! MLN_INCLUDE_ONLY
615 
616 } // end of namespace mln
617 
618 
619 
620 # include <mln/core/trait/pixter.hh>
621 # include <mln/core/dpoints_pixter.hh>
622 # include <mln/core/pixter3d.hh>
623 # include <mln/core/w_window.hh>
624 
625 
626 namespace mln
627 {
628 
629  namespace trait
630  {
631 
632  // pixter
633 
634  template <typename T>
635  struct fwd_pixter< image3d<T> >
636  {
638  };
639 
640  template <typename T>
641  struct fwd_pixter< const image3d<T> >
642  {
644  };
645 
646  template <typename T>
647  struct bkd_pixter< image3d<T> >
648  {
649  typedef bkd_pixter3d< image3d<T> > ret;
650  };
651 
652  template <typename T>
653  struct bkd_pixter< const image3d<T> >
654  {
656  };
657 
658  // qixter
659 
660  template <typename T, typename W>
661  struct fwd_qixter< image3d<T>, W >
662  {
664  };
665 
666  template <typename T, typename W>
667  struct fwd_qixter< const image3d<T>, W >
668  {
670  };
671 
672  template <typename T, typename W>
673  struct bkd_qixter< image3d<T>, W >
674  {
676  };
677 
678  template <typename T, typename W>
679  struct bkd_qixter< const image3d<T>, W >
680  {
682  };
683 
684  // nixter
685 
686  template <typename T, typename W>
687  struct fwd_nixter< image3d<T>, W >
688  {
690  };
691 
692  template <typename T, typename W>
693  struct fwd_nixter< const image3d<T>, W >
694  {
696  };
697 
698  template <typename T, typename W>
699  struct bkd_nixter< image3d<T>, W >
700  {
702  };
703 
704  template <typename T, typename W>
705  struct bkd_nixter< const image3d<T>, W >
706  {
708  };
709 
710  } // end of namespace mln::trait
711 
712 } // end of namespace mln
713 
714 
715 #endif // ! MLN_CORE_IMAGE_IMAGE3D_HH