Milena (Olena)  User documentation 2.0a Id
 All Classes Namespaces Functions Variables Typedefs Enumerator Groups Pages
core/image/image2d.hh
1 // Copyright (C) 2007, 2008, 2009, 2011 EPITA Research and Development
2 // 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_IMAGE2D_HH
28 # define MLN_CORE_IMAGE_IMAGE2D_HH
29 
37 
38 # include <mln/core/internal/image_primary.hh>
39 # include <mln/core/internal/fixme.hh>
40 # include <mln/core/alias/box2d.hh>
41 # include <mln/core/routine/init.hh>
42 
43 # include <mln/border/thickness.hh>
44 # include <mln/value/set.hh>
45 # include <mln/fun/i2v/all_to.hh>
46 // # include <mln/core/line_piter.hh> // FIXME
47 
48 
49 
50 // FIXME:
51 
52 // # include <mln/core/pixter2d.hh>
53 // # include <mln/core/dpoints_pixter.hh>
54 
55 
56 
57 
58 namespace mln
59 {
60 
61  // Forward declaration.
62  template <typename T> class image2d;
63 
64 
65  namespace internal
66  {
67 
69  template <typename T>
70  struct data< image2d<T> >
71  {
72  data(const box2d& b, unsigned bdr);
73  ~data();
74 
75  T* buffer_;
76  T** array_;
77 
78  box2d b_; // theoretical box
79  unsigned bdr_;
80  box2d vb_; // virtual box, i.e., box including the virtual border
81 
82  void update_vb_();
83  void allocate_();
84  void deallocate_();
85  void swap_(data< image2d<T> >& other_);
86  void reallocate_(unsigned new_border);
87  };
88 
89  } // end of namespace mln::internal
90 
91 
92  namespace trait
93  {
94 
95  template <typename T>
96  struct image_< image2d<T> > : default_image_< T, image2d<T> >
97  {
98  // misc
99  typedef trait::image::category::primary category;
100  typedef trait::image::speed::fastest speed;
101  typedef trait::image::size::regular size;
102 
103  // value
104  typedef trait::image::vw_io::none vw_io;
105  typedef trait::image::vw_set::none vw_set;
106  typedef trait::image::value_access::direct value_access;
107  typedef trait::image::value_storage::one_block value_storage;
108  typedef trait::image::value_browsing::site_wise_only value_browsing;
109  typedef trait::image::value_alignment::with_grid value_alignment;
110  typedef trait::image::value_io::read_write value_io;
111 
112  // site / domain
113  typedef trait::image::pw_io::read_write pw_io;
114  typedef trait::image::localization::basic_grid localization;
115  typedef trait::image::dimension::two_d dimension;
116 
117  // extended domain
118  typedef trait::image::ext_domain::extendable ext_domain;
119  typedef trait::image::ext_value::multiple ext_value;
120  typedef trait::image::ext_io::read_write ext_io;
121  };
122 
123  } // end of namespace mln::trait
124 
125 
126 
134  //
135  template <typename T>
136  class image2d : public internal::image_primary< T, mln::box2d, image2d<T> >
137  {
138  typedef internal::image_primary< T, mln::box2d, image2d<T> > super_;
139  public:
140 
142  typedef T value;
143 
145  typedef const T& rvalue;
146 
148  typedef T& lvalue;
149 
150 
153 
154 
156  image2d();
157 
160  image2d(int nrows, int ncols, unsigned bdr = border::thickness);
161 
164  image2d(const box2d& b, unsigned bdr = border::thickness);
165 
166 
168  void init_(const box2d& b, unsigned bdr = border::thickness);
169 
170 
172  bool has(const point2d& p) const;
173 
175  const box2d& domain() const;
176 
178  const box2d& bbox() const;
179 
180  // virtual box, i.e., box including the virtual border
181  const box2d& vbbox() const;
182 
184  const T& operator()(const point2d& p) const;
185 
187  T& operator()(const point2d& p);
188 
189 
190  template <typename P>
191  T& alt(const P& p)
192  {
193  typedef def::coord coord_t;
194  mln_precondition(this->has(p));
195 
196 // std::cout << (coord_t*)(&p.p_hook_()) << ' '
197 // << &(p.row()) << ' '
198 // << &(p.get_subject()) << ' '
199 // << &(p.to_site()) << std::endl;
200 
201  // return this->data_->array_[p.to_site().row()][p.to_site().col()];
202  // return this->data_->array_[p.row()][p.col()];
203  // return this->data_->array_[p.get_subject().row()][p.get_subject().col()];
204  // return this->data_->array_ [*(coord_t*)(&p.get_subject())] [*((coord_t*)(&p.get_subject()) + 1)];
205  return this->data_->array_ [*(coord_t*)(&p.p_hook_())] [*((coord_t*)(&p.p_hook_()) + 1)];
206  // return this->data_->array_[0][0];;
207  }
208 
209 
210  // Specific methods:
211  // -----------------
212 
214  const T& at_(mln::def::coord row, mln::def::coord col) const;
215 
217  T& at_(mln::def::coord row, mln::def::coord col);
218 
220  unsigned nrows() const;
221 
223  unsigned ncols() const;
224 
225 
226  // As a fastest image:
227  // -------------------
228 
229  // Give the index of a point.
230  using super_::index_of_point;
231 
233  unsigned border() const;
234 
236  unsigned nelements() const;
237 
239  const T& element(unsigned i) const;
240 
242  T& element(unsigned i);
243 
245  int delta_index(const dpoint2d& dp) const;
246 
248  point2d point_at_index(unsigned i) const;
249 
251  const T* buffer() const;
252 
254  T* buffer();
255 
256 
258  void resize_(unsigned new_border);
259  };
260 
261 
262 
263  // Forward declaration
264 
265  template <typename T>
266  void init_(tag::border_t, unsigned& bdr, const image2d<T>& model);
267 
268  template <typename T, typename J>
269  void init_(tag::image_t, mln::image2d<T>& target, const J& model);
270 
271 
272 
273 # ifndef MLN_INCLUDE_ONLY
274 
275  // init_
276 
277  template <typename T>
278  inline
279  void init_(tag::border_t, unsigned& bdr, const image2d<T>& model)
280  {
281  bdr = model.border();
282  }
283 
284  template <typename T, typename J>
285  inline
286  void init_(tag::image_t, image2d<T>& target, const J& model)
287  {
288  box2d b;
289  init_(tag::bbox, b, model);
290  unsigned bdr;
291  init_(tag::border, bdr, model);
292  target.init_(b, bdr);
293  }
294 
295 
296  // internal::data< image2d<T> >
297 
298  namespace internal
299  {
300  template <typename T>
301  inline
302  data< image2d<T> >::data(const box2d& b, unsigned bdr)
303  : buffer_(0),
304  array_ (0),
305  b_ (b),
306  bdr_ (bdr)
307  {
308  allocate_();
309  }
310 
311  template <typename T>
312  inline
313  data< image2d<T> >::~data()
314  {
315  deallocate_();
316  }
317 
318  template <typename T>
319  inline
320  void
321  data< image2d<T> >::update_vb_()
322  {
323  vb_.pmin() = b_.pmin() - dpoint2d(all_to(bdr_));
324  vb_.pmax() = b_.pmax() + dpoint2d(all_to(bdr_));
325  }
326 
327  template <typename T>
328  inline
329  void
330  data< image2d<T> >::allocate_()
331  {
332  update_vb_();
333  unsigned
334  nr = vb_.len(0),
335  nc = vb_.len(1);
336  buffer_ = new T[nr * nc];
337  array_ = new T*[nr];
338  T* buf = buffer_ - vb_.pmin().col();
339  for (unsigned i = 0; i < nr; ++i)
340  {
341  array_[i] = buf;
342  buf += nc;
343  }
344  array_ -= vb_.pmin().row();
345  mln_postcondition(vb_.len(0) == b_.len(0) + 2 * bdr_);
346  mln_postcondition(vb_.len(1) == b_.len(1) + 2 * bdr_);
347  }
348 
349  template <typename T>
350  inline
351  void
352  data< image2d<T> >::deallocate_()
353  {
354  if (buffer_)
355  {
356  delete[] buffer_;
357  buffer_ = 0;
358  }
359  if (array_)
360  {
361  array_ += vb_.pmin().row();
362  delete[] array_;
363  array_ = 0;
364  }
365  }
366 
367  template <typename T>
368  inline
369  void
370  data< image2d<T> >::swap_(data< image2d<T> >& other_)
371  {
372  data< image2d<T> > self_ = *this;
373  *this = other_;
374  other_ = self_;
375  }
376 
377  template <typename T>
378  inline
379  void
380  data< image2d<T> >::reallocate_(unsigned new_border)
381  {
382  data< image2d<T> >& tmp = *(new data< image2d<T> >(this->b_, new_border));
383  this->swap_(tmp);
384  }
385 
386 
387  } // end of namespace mln::internal
388 
389 
390  // image2d<T>
391 
392  template <typename T>
393  inline
395  {
396  }
397 
398  template <typename T>
399  inline
400  image2d<T>::image2d(int nrows, int ncols, unsigned bdr)
401  {
402  init_(make::box2d(nrows, ncols), bdr);
403  }
404 
405  template <typename T>
406  inline
407  image2d<T>::image2d(const box2d& b, unsigned bdr)
408  {
409  init_(b, bdr);
410  }
411 
412  template <typename T>
413  inline
414  void
415  image2d<T>::init_(const box2d& b, unsigned bdr)
416  {
417  mln_precondition(! this->is_valid());
418  this->data_ = new internal::data< image2d<T> >(b, bdr);
419  }
420 
421  template <typename T>
422  inline
423  const box2d&
425  {
426  mln_precondition(this->is_valid());
427  return this->data_->b_;
428  }
429 
430  template <typename T>
431  inline
432  const box2d&
434  {
435  mln_precondition(this->is_valid());
436  return this->data_->b_;
437  }
438 
439  template <typename T>
440  inline
441  const box2d&
442  image2d<T>::vbbox() const
443  {
444  mln_precondition(this->is_valid());
445  return this->data_->vb_;
446  }
447 
448  template <typename T>
449  inline
450  bool
451  image2d<T>::has(const point2d& p) const
452  {
453  mln_precondition(this->is_valid());
454  return this->data_->vb_.has(p);
455  }
456 
457  template <typename T>
458  inline
459  const T&
461  {
462  mln_precondition(this->has(p));
463  return this->data_->array_[p.row()][p.col()];
464  }
465 
466  template <typename T>
467  inline
468  T&
470  {
471  mln_precondition(this->has(p));
472  return this->data_->array_[p.row()][p.col()];
473  }
474 
475 
476  // Specific methods:
477 
478  template <typename T>
479  inline
480  const T&
482  {
483  mln_precondition(this->has(point2d(row, col)));
484  return this->data_->array_[row][col];
485  }
486 
487  template <typename T>
488  inline
489  T&
490  image2d<T>::at_(mln::def::coord row, mln::def::coord col)
491  {
492  mln_precondition(this->has(point2d(row, col)));
493  return this->data_->array_[row][col];
494  }
495 
496  template <typename T>
497  inline
498  unsigned
500  {
501  mln_precondition(this->is_valid());
502  return this->data_->b_.len(0);
503  }
504 
505  template <typename T>
506  inline
507  unsigned
509  {
510  mln_precondition(this->is_valid());
511  return this->data_->b_.len(1);
512  }
513 
514 
515  // As a fastest image:
516 
517  template <typename T>
518  inline
519  unsigned
521  {
522  mln_precondition(this->is_valid());
523  return this->data_->bdr_;
524  }
525 
526  template <typename T>
527  inline
528  unsigned
530  {
531  mln_precondition(this->is_valid());
532  return this->data_->vb_.nsites();
533  }
534 
535  template <typename T>
536  inline
537  const T&
538  image2d<T>::element(unsigned i) const
539  {
540  mln_precondition(i < nelements());
541  return *(this->data_->buffer_ + i);
542  }
543 
544  template <typename T>
545  inline
546  T&
548  {
549  mln_precondition(i < nelements());
550  return *(this->data_->buffer_ + i);
551  }
552 
553  template <typename T>
554  inline
555  const T*
557  {
558  mln_precondition(this->is_valid());
559  return this->data_->buffer_;
560  }
561 
562  template <typename T>
563  inline
564  T*
566  {
567  mln_precondition(this->is_valid());
568  return this->data_->buffer_;
569  }
570 
571  template <typename T>
572  inline
573  int
575  {
576  mln_precondition(this->is_valid());
577  int o = dp[0] * this->data_->vb_.len(1) + dp[1];
578  return o;
579  }
580 
581  template <typename T>
582  inline
583  point2d
584  image2d<T>::point_at_index(unsigned i) const
585  {
586  mln_precondition(i < nelements());
587  def::coord
588  row = static_cast<def::coord>(i / this->data_->vb_.len(1) + this->data_->vb_.min_row()),
589  col = static_cast<def::coord>(i % this->data_->vb_.len(1) + this->data_->vb_.min_col());
590  point2d p = point2d(row, col);
591  mln_postcondition(& this->operator()(p) == this->data_->buffer_ + i);
592  return p;
593  }
594 
595  // Extra.
596 
597  template <typename T>
598  inline
599  void
600  image2d<T>::resize_(unsigned new_border)
601  {
602  mln_precondition(this->is_valid());
603  this->data_->reallocate_(new_border);
604  }
605 
606 # endif // ! MLN_INCLUDE_ONLY
607 
608 } // end of namespace mln
609 
610 
611 
612 # include <mln/core/trait/pixter.hh>
613 # include <mln/core/dpoints_pixter.hh>
614 # include <mln/core/pixter2d.hh>
615 // # include <mln/core/w_window.hh>
616 
617 
618 namespace mln
619 {
620 
621  namespace trait
622  {
623 
624  // pixter
625 
626  template <typename T>
627  struct fwd_pixter< image2d<T> >
628  {
629  typedef fwd_pixter2d< image2d<T> > ret;
630  };
631 
632  template <typename T>
633  struct fwd_pixter< const image2d<T> >
634  {
635  typedef fwd_pixter2d< const image2d<T> > ret;
636  };
637 
638  template <typename T>
639  struct bkd_pixter< image2d<T> >
640  {
641  typedef bkd_pixter2d< image2d<T> > ret;
642  };
643 
644  template <typename T>
645  struct bkd_pixter< const image2d<T> >
646  {
647  typedef bkd_pixter2d< const image2d<T> > ret;
648  };
649 
650  // qixter
651 
652  template <typename T, typename W>
653  struct fwd_qixter< image2d<T>, W >
654  {
655  typedef dpoints_fwd_pixter< image2d<T> > ret;
656  };
657 
658  template <typename T, typename W>
659  struct fwd_qixter< const image2d<T>, W >
660  {
661  typedef dpoints_fwd_pixter< const image2d<T> > ret;
662  };
663 
664  template <typename T, typename W>
665  struct bkd_qixter< image2d<T>, W >
666  {
667  typedef dpoints_bkd_pixter< image2d<T> > ret;
668  };
669 
670  template <typename T, typename W>
671  struct bkd_qixter< const image2d<T>, W >
672  {
673  typedef dpoints_bkd_pixter< const image2d<T> > ret;
674  };
675 
676  // nixter
677 
678  template <typename T, typename N>
679  struct fwd_nixter< image2d<T>, N >
680  {
681  typedef dpoints_fwd_pixter< image2d<T> > ret;
682  };
683 
684  template <typename T, typename N>
685  struct fwd_nixter< const image2d<T>, N >
686  {
687  typedef dpoints_fwd_pixter< const image2d<T> > ret;
688  };
689 
690  template <typename T, typename N>
691  struct bkd_nixter< image2d<T>, N >
692  {
693  typedef dpoints_bkd_pixter< image2d<T> > ret;
694  };
695 
696  template <typename T, typename N>
697  struct bkd_nixter< const image2d<T>, N >
698  {
699  typedef dpoints_bkd_pixter< const image2d<T> > ret;
700  };
701 
702  } // end of namespace mln::trait
703 
704 } // end of namespace mln
705 
706 
707 # include <mln/make/image.hh>
708 # include <mln/make/image2d.hh>
709 
710 
711 #endif // ! MLN_CORE_IMAGE_IMAGE2D_HH