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