Milena (Olena)  User documentation 2.0a Id
 All Classes Namespaces Functions Variables Typedefs Enumerator Groups Pages
p2p_image.hh
1 // Copyright (C) 2008, 2009 EPITA Research and Development Laboratory (LRDE)
2 //
3 // This file is part of Olena.
4 //
5 // Olena is free software: you can redistribute it and/or modify it under
6 // the terms of the GNU General Public License as published by the Free
7 // Software Foundation, version 2 of the License.
8 //
9 // Olena is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with Olena. If not, see <http://www.gnu.org/licenses/>.
16 //
17 // As a special exception, you may use this file as part of a free
18 // software project without restriction. Specifically, if other files
19 // instantiate templates or use macros or inline functions from this
20 // file, or you compile this file and link it with other files to produce
21 // an executable, this file does not by itself cause the resulting
22 // executable to be covered by the GNU General Public License. This
23 // exception does not however invalidate any other reasons why the
24 // executable file might be covered by the GNU General Public License.
25 
26 #ifndef MLN_CORE_IMAGE_DMORPH_P2P_IMAGE_HH
27 # define MLN_CORE_IMAGE_DMORPH_P2P_IMAGE_HH
28 
32 
33 # include <mln/core/internal/image_domain_morpher.hh>
34 # include <mln/core/concept/function.hh>
35 # include <mln/accu/shape/bbox.hh>
36 
37 
38 namespace mln
39 {
40 
41  // Forward declaration.
42  template <typename I, typename F> struct p2p_image;
43 
44 
45  namespace internal
46  {
47 
49  template <typename I, typename F>
50  struct data< p2p_image<I,F> >
51  {
52  data(I& ima, const F& f);
53 
54  I ima_;
55  F f_;
56  mln_domain(I) b_;
57  };
58 
59  } // end of namespace mln::internal
60 
61 
62  namespace trait
63  {
64 
65  template <typename I, typename F>
66  struct image_< p2p_image<I,F> > : default_image_morpher< I,
67  mln_value(I),
68  p2p_image<I,F> >
69  {
70  typedef trait::image::category::domain_morpher category;
71 
72  typedef trait::image::ext_domain::none ext_domain; // No extension of domain.
73  typedef trait::image::ext_value::irrelevant ext_value;
74  typedef trait::image::ext_io::irrelevant ext_io;
75 
76  typedef trait::image::vw_io::none vw_io;
77  typedef trait::image::vw_set::none vw_set;
78  typedef trait::image::value_alignment::not_aligned value_alignment;
79  typedef trait::image::value_storage::disrupted value_storage;
80  };
81 
82  } // end of namespace mln::trait
83 
84 
85 
89  template <typename I, typename F>
90  struct p2p_image : public internal::image_domain_morpher< I,
91  mln_domain(I),
92  p2p_image<I, F> >
93  {
95  typedef p2p_image< tag::image_<I>, tag::function_<F> > skeleton;
96 
98  p2p_image();
99 
101  p2p_image(I& ima, const F& f);
102 
103  void init_(I& ima, const F& f);
104 
106  const mln_domain(I)& domain() const;
107 
109  const F& fun() const;
110 
112  mln_rvalue(I) operator()(const mln_psite(I)& p) const;
113 
115  mln_morpher_lvalue(I) operator()(const mln_psite(I)& p);
116  };
117 
118 
119 
121  template <typename I, typename F>
122  p2p_image<I,F>
123  apply_p2p(Image<I>& ima, const Function_v2v<F>& f);
124 
126  template <typename I, typename F>
127  p2p_image<const I,F>
128  apply_p2p(const Image<I>& ima, const Function_v2v<F>& f);
129 
130 
131 
132 # ifndef MLN_INCLUDE_ONLY
133 
134  // init_.
135 
136  template <typename I, typename F>
137  void init_(tag::function_t, F& f, const p2p_image<I,F>& model)
138  {
139  f = model.fun();
140  }
141 
142  template <typename I, typename F, typename J>
143  void init_(tag::image_t, p2p_image<I,F>& target, const J& model)
144  {
145  I ima;
146  init_(tag::image, ima, exact(model));
147  F f;
148  init_(tag::function, f, exact(model));
149  target.init_(ima, f);
150  }
151 
152  // internal::data< p2p_image<I,F> >
153 
154  namespace internal
155  {
156 
157  template <typename I, typename F>
158  inline
159  data< p2p_image<I,F> >::data(I& ima, const F& f)
160  : ima_(ima),
161  f_(f)
162  {
163  accu::shape::bbox<mln_site(I)> a;
164  mln_domain(I) b = ima.domain();
165  a.take(f(b.pmin()));
166  a.take(f(b.pmax()));
167  b_ = a.to_result();
168  mln_invariant(b_.nsites() == b.nsites());
169  }
170 
171  }
172 
173 
174  // p2p_image<I,F>
175 
176  template <typename I, typename F>
177  inline
179  {
180  }
181 
182  template <typename I, typename F>
183  inline
184  p2p_image<I,F>::p2p_image(I& ima, const F& f)
185  {
186  init_(ima, f);
187  }
188 
189  template <typename I, typename F>
190  inline
191  void
192  p2p_image<I,F>::init_(I& ima, const F& f)
193  {
194  mln_precondition(! this->is_valid());
195  this->data_ = new internal::data< p2p_image<I,F> >(ima, f);
196  }
197 
198  template <typename I, typename F>
199  inline
200  const mln_domain(I)&
202  {
203  mln_precondition(this->is_valid());
204  return this->data_->b_;
205  }
206 
207  template <typename I, typename F>
208  inline
209  const F&
211  {
212  mln_precondition(this->is_valid());
213  return this->data_->f_;
214  }
215 
216  template <typename I, typename F>
217  inline
218  mln_rvalue(I)
219  p2p_image<I,F>::operator()(const mln_psite(I)& p) const
220  {
221  mln_precondition(this->has(p));
222  mln_invariant(this->data_->ima_.has(this->data_->f_.inverse(p)));
223  return this->data_->ima_(this->data_->f_.inverse(p));
224  }
225 
226  template <typename I, typename F>
227  inline
228  mln_morpher_lvalue(I)
229  p2p_image<I,F>::operator()(const mln_psite(I)& p)
230  {
231  mln_precondition(this->has(p));
232  mln_invariant(this->data_->ima_.has(this->data_->f_.inverse(p)));
233  return this->data_->ima_(this->data_->f_.inverse(p));
234  }
235 
236 
237  // Routines.
238 
239  template <typename I, typename F>
240  inline
243  {
244  mlc_is_a(mln_domain(I), Box)::check();
245 
246  I& ima = exact(ima_);
247  mln_precondition(ima.is_valid());
248 
249  p2p_image<I,F> tmp(ima, exact(f));
250  return tmp;
251  }
252 
253  template <typename I, typename F>
254  inline
255  p2p_image<const I, F>
256  apply_p2p(const Image<I>& ima_, const Function_v2v<F>& f)
257  {
258  mlc_is_a(mln_domain(I), Box)::check();
259 
260  const I& ima = exact(ima_);
261  mln_precondition(ima.is_valid());
262 
263  p2p_image<const I, F> tmp(ima, exact(f));
264  return tmp;
265  }
266 
267 
268 # endif // ! MLN_INCLUDE_ONLY
269 
270 } // end of namespace mln
271 
272 
273 
274 #endif // ! MLN_CORE_IMAGE_DMORPH_P2P_IMAGE_HH