Milena (Olena)  User documentation 2.0a Id
 All Classes Namespaces Functions Variables Typedefs Enumerator Groups Pages
image1d.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_IMAGE1D_HH
28 # define MLN_CORE_IMAGE_IMAGE1D_HH
29 
35 
36 # include <mln/core/internal/fixme.hh>
37 # include <mln/core/internal/image_primary.hh>
38 # include <mln/core/alias/box1d.hh>
39 
40 # include <mln/border/thickness.hh>
41 # include <mln/value/set.hh>
42 # include <mln/fun/i2v/all_to.hh>
43 
44 
45 // FIXME:
46 
47 // # include <mln/core/pixter1d.hh>
48 // # include <mln/core/dpoints_pixter.hh>
49 
50 
51 namespace mln
52 {
53 
54  // Forward declaration.
55  template <typename T> struct image1d;
56 
57 
58  namespace internal
59  {
60 
62  template <typename T>
63  struct data< image1d<T> >
64  {
65  data(const box1d& b, unsigned bdr);
66  ~data();
67 
68  T* buffer_;
69  T* array_;
70 
71  box1d b_; // theoretical box
72  unsigned bdr_;
73  box1d 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< image1d<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_< image1d<T> > : default_image_< T, image1d<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::one_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 
121  // Forward declaration.
122  template <typename T> struct image1d;
123 
124 
125 
126  namespace convert
127  {
128 
129  namespace over_load
130  {
131 
132  // histo::array -> image1d.
133  template <typename V, typename T>
134  void from_to_(const histo::array<V>& from, image1d<T>& to);
135 
136  // util::array -> image1d.
137  template <typename V, typename T>
138  void from_to_(const util::array<V>& from, image1d<T>& to);
139 
140  } // end of namespace mln::convert::over_load
141 
142  } // end of namespace mln::convert
143 
144 
145 
153  //
154  template <typename T>
155  struct image1d :
156  public internal::image_primary< T, box1d, image1d<T> >
157  {
158  typedef internal::image_primary< T, mln::box1d, image1d<T> > super_;
159 
161  typedef T value;
162 
164  typedef const T& rvalue;
165 
167  typedef T& lvalue;
168 
171 
172 
174  image1d();
175 
178  image1d(unsigned ninds, unsigned bdr = border::thickness);
179 
181  image1d(const box1d& b, unsigned bdr = border::thickness);
182 
183 
185  void init_(const box1d& b, unsigned bdr = border::thickness);
186 
187 
189  bool has(const point1d& p) const;
190 
192  const box1d& domain() const;
193 
195  const box1d& bbox() const;
196 
198  const box1d& vbbox() const;
199 
201  unsigned border() const;
202 
204  const T& operator()(const point1d& p) const;
205 
207  T& operator()(const point1d& p);
208 
209 
210  // Specific methods:
211  // -----------------
212 
214  const T& at_(def::coord index) const;
215 
217  T& at_(def::coord index);
218 
220  unsigned ninds() const;
221 
222 
223 
225 
226  // Give the index of a point.
227  using super_::index_of_point;
228 
230  int delta_index(const dpoint1d& dp) const;
231 
233  point1d point_at_index(unsigned i) const;
234 
236  const T* buffer() const;
237 
239  T* buffer();
240 
243  const T& element(unsigned i) const;
244 
247  T& element(unsigned i);
248 
250  unsigned nelements() const;
251 
252 
253 
255  void resize_(unsigned new_border);
256 
257  };
258 
259  template <typename T, typename J>
260  void init_(tag::image_t, mln::image1d<T>& target, const J& model);
261 
262 # ifndef MLN_INCLUDE_ONLY
263 
264  // init_
265  template <typename T>
266  inline
267  void init_(tag::border_t, unsigned& b, const image1d<T>& model)
268  {
269  b = model.border();
270  }
271 
272  template <typename T, typename J>
273  inline
274  void init_(tag::image_t, image1d<T>& target, const J& model)
275  {
276  box1d b;
277  init_(tag::bbox, b, model);
278  unsigned bdr;
279  init_(tag::border, bdr, model);
280  target.init_(b, bdr);
281  }
282 
283  // internal::data< image1d<T> >
284 
285  namespace internal
286  {
287 
288  template <typename T>
289  inline
290  data< image1d<T> >::data(const box1d& b, unsigned bdr)
291  : buffer_(0),
292  array_ (0),
293  b_ (b),
294  bdr_ (bdr)
295  {
296  allocate_();
297  }
298 
299  template <typename T>
300  inline
301  data< image1d<T> >::~data()
302  {
303  deallocate_();
304  }
305 
306  template <typename T>
307  inline
308  void
309  data< image1d<T> >::update_vb_()
310  {
311  dpoint1d dp(all_to(bdr_));
312 
313  vb_.pmin() = b_.pmin() - dp;
314  vb_.pmax() = b_.pmax() + dp;
315  }
316 
317  template <typename T>
318  inline
319  void
320  data< image1d<T> >::allocate_()
321  {
322  update_vb_();
323  unsigned
324  ni = vb_.len(0);
325  buffer_ = new T[ni];
326  array_ = buffer_ - vb_.pmin().ind();
327  mln_postcondition(vb_.len(0) == b_.len(0) + 2 * bdr_);
328  }
329 
330  template <typename T>
331  inline
332  void
333  data< image1d<T> >::deallocate_()
334  {
335  if (buffer_)
336  {
337  delete[] buffer_;
338  buffer_ = 0;
339  }
340  }
341 
342 
343  template <typename T>
344  inline
345  void
346  data< image1d<T> >::swap_(data< image1d<T> >& other_)
347  {
348 
349  data< image1d<T> > self_ = *this;
350  *this = other_;
351  other_ = self_;
352 
353  }
354 
355  template <typename T>
356  inline
357  void
358  data< image1d<T> >::reallocate_(unsigned new_border)
359  {
360  data< image1d<T> >& tmp = *(new data< image1d<T> >(this->b_, new_border));
361  this->swap_(tmp);
362  }
363 
364  } // end of namespace mln::internal
365 
366 
367  // image1d<T>
368 
369  template <typename T>
370  inline
372  {
373  }
374 
375  template <typename T>
376  inline
377  image1d<T>::image1d(const box1d& b, unsigned bdr)
378  {
379  init_(b, bdr);
380  }
381 
382  template <typename T>
383  inline
384  image1d<T>::image1d(unsigned ninds, unsigned bdr)
385  {
386  mln_precondition(ninds != 0);
387  init_(make::box1d(ninds), bdr);
388  }
389 
390  template <typename T>
391  inline
392  void
393  image1d<T>::init_(const box1d& b, unsigned bdr)
394  {
395  mln_precondition(! this->is_valid());
396  this->data_ = new internal::data< image1d<T> >(b, bdr);
397  }
398 
399  template <typename T>
400  inline
401  const box1d&
403  {
404  mln_precondition(this->is_valid());
405  return this->data_->b_;
406  }
407 
408  template <typename T>
409  inline
410  const box1d&
412  {
413  mln_precondition(this->is_valid());
414  return this->data_->b_;
415  }
416 
417  template <typename T>
418  inline
419  const box1d&
421  {
422  mln_precondition(this->is_valid());
423  return this->data_->vb_;
424  }
425 
426  template <typename T>
427  inline
428  unsigned
430  {
431  mln_precondition(this->is_valid());
432  return this->data_->bdr_;
433  }
434 
435  template <typename T>
436  inline
437  unsigned
439  {
440  mln_precondition(this->is_valid());
441  return this->data_->vb_.nsites();
442  }
443 
444  template <typename T>
445  inline
446  bool
447  image1d<T>::has(const point1d& p) const
448  {
449  mln_precondition(this->is_valid());
450  return this->data_->vb_.has(p);
451  }
452 
453  template <typename T>
454  inline
455  const T&
457  {
458  mln_precondition(this->has(p));
459  return this->data_->array_[p.ind()];
460  }
461 
462  template <typename T>
463  inline
464  T&
466  {
467  mln_precondition(this->has(p));
468  return this->data_->array_[p.ind()];
469  }
470 
471  template <typename T>
472  inline
473  const T&
474  image1d<T>::at_(def::coord index) const
475  {
476  mln_precondition(this->has(point1d(index)));
477  return this->data_->array_[index];
478  }
479 
480  template <typename T>
481  inline
482  unsigned
484  {
485  mln_precondition(this->is_valid());
486  return this->data_->b_.len(0);
487  }
488 
489  template <typename T>
490  inline
491  T&
493  {
494  mln_precondition(this->has(point1d(index)));
495  return this->data_->array_[index];
496  }
497 
498 
499  template <typename T>
500  inline
501  const T&
502  image1d<T>::element(unsigned i) const
503  {
504  mln_precondition(i < nelements());
505  return this->data_->buffer_[i];
506  }
507 
508  template <typename T>
509  inline
510  T&
512  {
513  mln_precondition(i < nelements());
514  return this->data_->buffer_[i];
515  }
516 
517  template <typename T>
518  inline
519  const T*
521  {
522  mln_precondition(this->is_valid());
523  return this->data_->buffer_;
524  }
525 
526  template <typename T>
527  inline
528  T*
530  {
531  mln_precondition(this->is_valid());
532  return this->data_->buffer_;
533  }
534 
535  template <typename T>
536  inline
537  int
539  {
540  mln_precondition(this->is_valid());
541  int o = dp[0];
542  return o;
543  }
544 
545  template <typename T>
546  inline
547  point1d
548  image1d<T>::point_at_index(unsigned i) const
549  {
550  mln_precondition(i < nelements());
551  def::coord ind = static_cast<def::coord>(i + this->data_->vb_.min_ind());
552  point1d p = point1d(ind);
553  mln_postcondition(& this->operator()(p) == this->data_->buffer_ + i);
554  return p;
555  }
556 
557  template <typename T>
558  inline
559  void
560  image1d<T>::resize_(unsigned new_border)
561  {
562  this->data_->reallocate_(new_border);
563  }
564 
565 # endif // ! MLN_INCLUDE_ONLY
566 
567 } // end of namespace mln
568 
569 
570 
571 # include <mln/core/trait/pixter.hh>
572 # include <mln/core/dpoints_pixter.hh>
573 # include <mln/core/pixter1d.hh>
574 # include <mln/core/w_window.hh>
575 
576 
577 
578 namespace mln
579 {
580 
581 
582  namespace convert
583  {
584 
585  namespace over_load
586  {
587 
588  // histo::array -> image1d.
589  template <typename V, typename T>
590  inline
591  void
592  from_to_(const histo::array<V>& from, image1d<T>& to)
593  {
594  // FIXME: The code should looks like:
595 
596 // box1d b(point1d(mln_min(V)), point1d(mln_max(V)));
597 // ima.init_(b, 0);
598 // for_all(v)
599 // from_to(h(v), ima.at_( index_of(v) ));
600  to.init_(make::box1d(from.nvalues()));
601  for (unsigned i = 0; i < from.nvalues(); ++i)
602  from_to(from[i], to(point1d(i)));
603  }
604 
605  // util::array -> image1d.
606  template <typename V, typename T>
607  inline
608  void
609  from_to_(const util::array<V>& from, image1d<T>& to)
610  {
611  to.init_(make::box1d(from.nelements()));
612  for (unsigned i = 0; i < from.nelements(); ++i)
613  from_to(from[i], to(point1d(i)));
614  }
615 
616  } // end of namespace mln::convert::over_load
617 
618  } // end of namespace mln::convert
619 
620 
621  namespace trait
622  {
623 
624  // pixter
625 
626  template <typename T>
627  struct fwd_pixter< image1d<T> >
628  {
629  typedef fwd_pixter1d< image1d<T> > ret;
630  };
631 
632  template <typename T>
633  struct fwd_pixter< const image1d<T> >
634  {
635  typedef fwd_pixter1d< const image1d<T> > ret;
636  };
637 
638  template <typename T>
639  struct bkd_pixter< image1d<T> >
640  {
641  typedef bkd_pixter1d< image1d<T> > ret;
642  };
643 
644  template <typename T>
645  struct bkd_pixter< const image1d<T> >
646  {
647  typedef bkd_pixter1d< const image1d<T> > ret;
648  };
649 
650  // qixter
651 
652  template <typename T, typename W>
653  struct fwd_qixter< image1d<T>, W >
654  {
655  typedef dpoints_fwd_pixter< image1d<T> > ret;
656  };
657 
658  template <typename T, typename W>
659  struct fwd_qixter< const image1d<T>, W >
660  {
661  typedef dpoints_fwd_pixter< const image1d<T> > ret;
662  };
663 
664  template <typename T, typename W>
665  struct bkd_qixter< image1d<T>, W >
666  {
667  typedef dpoints_bkd_pixter< image1d<T> > ret;
668  };
669 
670  template <typename T, typename W>
671  struct bkd_qixter< const image1d<T>, W >
672  {
673  typedef dpoints_bkd_pixter< const image1d<T> > ret;
674  };
675 
676  // nixter
677 
678  template <typename T, typename W>
679  struct fwd_nixter< image1d<T>, W >
680  {
681  typedef dpoints_fwd_pixter< image1d<T> > ret;
682  };
683 
684  template <typename T, typename W>
685  struct fwd_nixter< const image1d<T>, W >
686  {
687  typedef dpoints_fwd_pixter< const image1d<T> > ret;
688  };
689 
690  template <typename T, typename W>
691  struct bkd_nixter< image1d<T>, W >
692  {
693  typedef dpoints_bkd_pixter< image1d<T> > ret;
694  };
695 
696  template <typename T, typename W>
697  struct bkd_nixter< const image1d<T>, W >
698  {
699  typedef dpoints_bkd_pixter< const image1d<T> > ret;
700  };
701 
702  } // end of namespace mln::trait
703 
704 } // end of namespace mln
705 
706 # include <mln/make/image.hh>
707 
708 #endif // ! MLN_CORE_IMAGE_IMAGE1D_HH