Milena (Olena)  User documentation 2.0a Id
 All Classes Namespaces Functions Variables Typedefs Enumerator Groups Pages
core/image/image3d.hh
1 // Copyright (C) 2007, 2008, 2009, 2010, 2011 EPITA Research and
2 // 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 
62  template <typename T>
63  struct data< image3d<T> >
64  {
65  data(const box3d& b, unsigned bdr);
66  ~data();
67 
68  T* buffer_;
69  T*** array_;
70 
71  box3d b_; // theoretical box
72  unsigned bdr_;
73  box3d vb_; // virtual box, i.e., box including the virtual border
74 
75  void update_vb_();
76  void allocate_();
77  void deallocate_();
78  void swap_ (data< image3d<T> >& other_);
79  void reallocate_(unsigned new_border);
80  };
81 
82  } // end of namespace mln::internal
83 
84 
85 
86  namespace trait
87  {
88 
89  template <typename T>
90  struct image_< image3d<T> > : default_image_< T, image3d<T> >
91  {
92  // misc
93  typedef trait::image::category::primary category;
94  typedef trait::image::speed::fastest speed;
95  typedef trait::image::size::regular size;
96 
97  // value
98  typedef trait::image::vw_io::none vw_io;
99  typedef trait::image::vw_set::none vw_set;
100  typedef trait::image::value_access::direct value_access;
101  typedef trait::image::value_storage::one_block value_storage;
102  typedef trait::image::value_browsing::site_wise_only value_browsing;
103  typedef trait::image::value_alignment::with_grid value_alignment;
104  typedef trait::image::value_io::read_write value_io;
105 
106  // site / domain
107  typedef trait::image::pw_io::read_write pw_io;
108  typedef trait::image::localization::basic_grid localization;
109  typedef trait::image::dimension::three_d dimension;
110 
111  // extended domain
112  typedef trait::image::ext_domain::extendable ext_domain;
113  typedef trait::image::ext_value::multiple ext_value;
114  typedef trait::image::ext_io::read_write ext_io;
115  };
116 
117  } // end of namespace mln::trait
118 
119 
120 
128  //
129  template <typename T>
130  struct image3d : public internal::image_primary< T, box3d, image3d<T> >
131  {
132  // Warning: just to make effective types appear in Doxygen:
133  typedef box3d pset;
134  typedef point3d psite;
135  typedef point3d point;
136  typedef dpoint3d dpoint;
137  typedef mln_fwd_piter(box3d) fwd_piter;
138  typedef mln_bkd_piter(box3d) bkd_piter;
139 // typedef line_piter_<point> line_piter;
140  // End of warning.
141 
142 
144  typedef internal::image_primary< T, box3d, image3d<T> > super_;
145 
147  typedef T value;
148 
150  typedef const T& rvalue;
151 
153  typedef T& lvalue;
154 
155 
158 
160  image3d();
161 
164  image3d(const box3d& b, unsigned bdr = border::thickness);
165 
168  image3d(int nslis, int nrows, int ncols, unsigned bdr = border::thickness);
169 
170 
172  void init_(const box3d& b, unsigned bdr = border::thickness);
173 
174 
176  bool has(const point3d& p) const;
177 
179  const box3d& domain() const;
180 
182  const box3d& bbox() const;
183 
185  const box3d& vbbox() const;
186 
188  unsigned border() const;
189 
191  unsigned nelements() const;
192 
194  const T& operator()(const point3d& p) const;
195 
197  T& operator()(const point3d& p);
198 
200  const T& element(unsigned i) const;
201 
203  T& element(unsigned i);
204 
207  const T& at_(def::coord sli, def::coord row, def::coord col) const;
208 
211  T& at_(def::coord sli, def::coord row, def::coord col);
212 
213 
215  unsigned nslis() const;
216 
218  unsigned nrows() const;
219 
221  unsigned ncols() const;
222 
223 
225 
227  int delta_index(const dpoint3d& dp) const;
228 
230  point3d point_at_index(unsigned o) const;
231 
233  const T* buffer() const;
234 
236  T* buffer();
237 
239  using super_::data_;
240 
241 
242 
244  void resize_(unsigned new_border);
245 
246  };
247 
248  template <typename T, typename J>
249  void init_(tag::image_t, mln::image3d<T>& target, const J& model);
250 
251 
252 
253 # ifndef MLN_INCLUDE_ONLY
254 
255  // init_
256 
257  template <typename T>
258  inline
259  void init_(tag::border_t, unsigned& b, const image3d<T>& model)
260  {
261  b = model.border();
262  }
263 
264  template <typename T, typename J>
265  inline
266  void init_(tag::image_t, image3d<T>& target, const J& model)
267  {
268  box3d b;
269  init_(tag::bbox, b, model);
270  unsigned bdr;
271  init_(tag::border, bdr, model);
272  target.init_(b, bdr);
273  }
274 
275 
276  // internal::data< image3d<T> >
277 
278  namespace internal
279  {
280 
281  template <typename T>
282  inline
283  data< image3d<T> >::data(const box3d& b, unsigned bdr)
284  : buffer_(0),
285  array_ (0),
286  b_ (b),
287  bdr_ (bdr)
288  {
289  allocate_();
290  }
291 
292  template <typename T>
293  inline
294  data< image3d<T> >::~data()
295  {
296  deallocate_();
297  }
298 
299  template <typename T>
300  inline
301  void
302  data< image3d<T> >::update_vb_()
303  {
304  vb_.pmin() = b_.pmin() - dpoint3d(all_to(bdr_));
305  vb_.pmax() = b_.pmax() + dpoint3d(all_to(bdr_));
306  }
307 
308  template <typename T>
309  inline
310  void
311  data< image3d<T> >::allocate_()
312  {
313  update_vb_();
314  unsigned
315  ns = vb_.len(0),
316  nr = vb_.len(1),
317  nc = vb_.len(2);
318  buffer_ = new T[nr * nc * ns];
319  array_ = new T**[ns];
320  T* buf = buffer_ - vb_.pmin().col();
321  for (unsigned i = 0; i < ns; ++i)
322  {
323  T** tmp = new T*[nr];
324  array_[i] = tmp;
325  for (unsigned j = 0; j < nr; ++j)
326  {
327  array_[i][j] = buf;
328  buf += nc;
329  }
330  array_[i] -= vb_.pmin().row();
331  }
332  array_ -= vb_.pmin().sli();
333  mln_postcondition(vb_.len(0) == b_.len(0) + 2 * bdr_);
334  }
335 
336  template <typename T>
337  inline
338  void
339  data< image3d<T> >::deallocate_()
340  {
341  if (buffer_)
342  {
343  delete[] buffer_;
344  buffer_ = 0;
345  }
346  for (typename point3d::coord i = vb_.pmin().sli(); i <= vb_.pmax().sli(); ++i)
347  {
348  if (array_[i])
349  {
350  array_[i] += vb_.pmin().row();
351  delete[] array_[i];
352  array_[i] = 0;
353  }
354  }
355  if (array_)
356  {
357  array_ += vb_.pmin().sli();
358  delete[] array_;
359  array_ = 0;
360  }
361  }
362 
363  template <typename T>
364  inline
365  void
366  data< image3d<T> >::swap_(data< image3d<T> >& other_)
367  {
368  data< image3d<T> > self_ = *this;
369  *this = other_;
370  other_ = self_;
371  }
372 
373  template <typename T>
374  inline
375  void
376  data< image3d<T> >::reallocate_(unsigned new_border)
377  {
378  data< image3d<T> >& tmp = *(new data< image3d<T> >(this->b_, new_border));
379  this->swap_(tmp);
380  }
381 
382 
383  } // end of namespace mln::internal
384 
385  // image3d<T>
386 
387  template <typename T>
388  inline
390  {
391  }
392 
393  template <typename T>
394  inline
395  image3d<T>::image3d(const box3d& b, unsigned bdr)
396  {
397  init_(b, bdr);
398  }
399 
400  template <typename T>
401  inline
402  image3d<T>::image3d(int nslis, int nrows, int ncols, unsigned bdr)
403  {
404  init_(make::box3d(nslis, nrows, ncols), bdr);
405  }
406 
407  template <typename T>
408  inline
409  void
410  image3d<T>::init_(const box3d& b, unsigned bdr)
411  {
412  mln_precondition(! this->is_valid());
413  this->data_ = new internal::data< image3d<T> >(b, bdr);
414  }
415 
416  template <typename T>
417  inline
418  const box3d&
420  {
421  mln_precondition(this->is_valid());
422  return data_->b_;
423  }
424 
425  template <typename T>
426  inline
427  const box3d&
429  {
430  mln_precondition(this->is_valid());
431  return data_->b_;
432  }
433 
434  template <typename T>
435  inline
436  const box3d&
438  {
439  mln_precondition(this->is_valid());
440  return data_->vb_;
441  }
442 
443  template <typename T>
444  inline
445  unsigned
447  {
448  mln_precondition(this->is_valid());
449  return data_->bdr_;
450  }
451 
452  template <typename T>
453  inline
454  unsigned
456  {
457  mln_precondition(this->is_valid());
458  return data_->vb_.nsites();
459  }
460 
461  template <typename T>
462  inline
463  bool
464  image3d<T>::has(const point3d& p) const
465  {
466  mln_precondition(this->is_valid());
467  return data_->vb_.has(p);
468  }
469 
470  template <typename T>
471  inline
472  const T&
474  {
475  mln_precondition(this->has(p));
476  return data_->array_[p.sli()][p.row()][p.col()];
477  }
478 
479  template <typename T>
480  inline
481  T&
483  {
484  mln_precondition(this->has(p));
485  return data_->array_[p.sli()][p.row()][p.col()];
486  }
487 
488  template <typename T>
489  inline
490  const T&
491  image3d<T>::element(unsigned i) const
492  {
493  mln_precondition(i < nelements());
494  return *(data_->buffer_ + i);
495  }
496 
497  template <typename T>
498  inline
499  T&
501  {
502  mln_precondition(i < nelements());
503  return *(data_->buffer_ + i);
504  }
505 
506  template <typename T>
507  inline
508  const T&
509  image3d<T>::at_(def::coord sli, def::coord row, def::coord col) const
510  {
511  mln_precondition(this->has(point3d(sli, row, col)));
512  return data_->array_[sli][row][col];
513  }
514 
515  template <typename T>
516  inline
517  T&
518  image3d<T>::at_(def::coord sli, def::coord row, def::coord col)
519  {
520  mln_precondition(this->has(point3d(sli, row, col)));
521  return data_->array_[sli][row][col];
522  }
523 
524  template <typename T>
525  inline
526  unsigned
528  {
529  mln_precondition(this->is_valid());
530  return this->data_->b_.len(0);
531  }
532 
533  template <typename T>
534  inline
535  unsigned
537  {
538  mln_precondition(this->is_valid());
539  return this->data_->b_.len(1);
540  }
541 
542  template <typename T>
543  inline
544  unsigned
546  {
547  mln_precondition(this->is_valid());
548  return this->data_->b_.len(2);
549  }
550 
551  template <typename T>
552  inline
553  const T*
555  {
556  mln_precondition(this->is_valid());
557  return data_->buffer_;
558  }
559 
560  template <typename T>
561  inline
562  T*
564  {
565  mln_precondition(this->is_valid());
566  return data_->buffer_;
567  }
568 
569  template <typename T>
570  inline
571  int
573  {
574  mln_precondition(this->is_valid());
575  int o = (dp[0] * this->data_->vb_.len(1)
576  + dp[1]) * this->data_->vb_.len(2) + dp[2];
577  return o;
578  }
579 
580  template <typename T>
581  inline
582  point3d
583  image3d<T>::point_at_index(unsigned o) const
584  {
585  mln_precondition(o < nelements());
586  def::coord
587  sli = static_cast<def::coord>(o / (data_->vb_.len(1) * data_->vb_.len(2)) + data_->vb_.min_sli()),
588  row = static_cast<def::coord>((o % (data_->vb_.len(1) * data_->vb_.len(2))) / data_->vb_.len(2) + data_->vb_.min_row()),
589  col = static_cast<def::coord>(o % data_->vb_.len(2) + data_->vb_.min_col());
590  point3d p = point3d(sli, row, col);
591  mln_postcondition(& this->operator()(p) == this->data_->buffer_ + o);
592  return p;
593  }
594 
595  template <typename T>
596  inline
597  void
598  image3d<T>::resize_(unsigned new_border)
599  {
600  this->data_->reallocate_(new_border);
601  }
602 
603 # endif // ! MLN_INCLUDE_ONLY
604 
605 } // end of namespace mln
606 
607 
608 
609 # include <mln/core/trait/pixter.hh>
610 # include <mln/core/dpoints_pixter.hh>
611 # include <mln/core/pixter3d.hh>
612 # include <mln/core/w_window.hh>
613 
614 
615 namespace mln
616 {
617 
618  namespace trait
619  {
620 
621  // pixter
622 
623  template <typename T>
624  struct fwd_pixter< image3d<T> >
625  {
626  typedef fwd_pixter3d< image3d<T> > ret;
627  };
628 
629  template <typename T>
630  struct fwd_pixter< const image3d<T> >
631  {
632  typedef fwd_pixter3d< const image3d<T> > ret;
633  };
634 
635  template <typename T>
636  struct bkd_pixter< image3d<T> >
637  {
638  typedef bkd_pixter3d< image3d<T> > ret;
639  };
640 
641  template <typename T>
642  struct bkd_pixter< const image3d<T> >
643  {
644  typedef bkd_pixter3d< const image3d<T> > ret;
645  };
646 
647  // qixter
648 
649  template <typename T, typename W>
650  struct fwd_qixter< image3d<T>, W >
651  {
652  typedef dpoints_fwd_pixter< image3d<T> > ret;
653  };
654 
655  template <typename T, typename W>
656  struct fwd_qixter< const image3d<T>, W >
657  {
658  typedef dpoints_fwd_pixter< const image3d<T> > ret;
659  };
660 
661  template <typename T, typename W>
662  struct bkd_qixter< image3d<T>, W >
663  {
664  typedef dpoints_bkd_pixter< image3d<T> > ret;
665  };
666 
667  template <typename T, typename W>
668  struct bkd_qixter< const image3d<T>, W >
669  {
670  typedef dpoints_bkd_pixter< const image3d<T> > ret;
671  };
672 
673  // nixter
674 
675  template <typename T, typename W>
676  struct fwd_nixter< image3d<T>, W >
677  {
678  typedef dpoints_fwd_pixter< image3d<T> > ret;
679  };
680 
681  template <typename T, typename W>
682  struct fwd_nixter< const image3d<T>, W >
683  {
684  typedef dpoints_fwd_pixter< const image3d<T> > ret;
685  };
686 
687  template <typename T, typename W>
688  struct bkd_nixter< image3d<T>, W >
689  {
690  typedef dpoints_bkd_pixter< image3d<T> > ret;
691  };
692 
693  template <typename T, typename W>
694  struct bkd_nixter< const image3d<T>, W >
695  {
696  typedef dpoints_bkd_pixter< const image3d<T> > ret;
697  };
698 
699  } // end of namespace mln::trait
700 
701 } // end of namespace mln
702 
703 
704 #endif // ! MLN_CORE_IMAGE_IMAGE3D_HH