Milena (Olena)  User documentation 2.0a Id
 All Classes Namespaces Functions Variables Typedefs Enumerator Groups Pages
pixel_impl.hh
1 // Copyright (C) 2007, 2008, 2009, 2010 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_INTERNAL_PIXEL_IMPL_HH
28 # define MLN_CORE_INTERNAL_PIXEL_IMPL_HH
29 
36 
37 # include <mln/core/concept/image.hh>
38 # include <mln/core/internal/force_exact.hh>
39 # include <mln/util/pix.hh>
40 
41 
42 
43 namespace mln
44 {
45 
46  namespace internal
47  {
48 
49  // We indeed have to handle the couple of cases when I is fastest
50  // or is not. Justification: mln::pixel derives from pixel_impl_
51  // and is a general purpose pixel class; it can be used on any
52  // image whatever it is a fastest one or not.
53 
54  template <bool is_fastest, typename I, typename E>
55  struct pixel_impl_base_;
56 
57 
58  template <typename I, typename E>
59  struct pixel_impl_base_< false, I, E > // I is not fastest.
60  {
61  typedef mlc_if(mlc_is_const(I), const mln_value(I), mln_value(I)) value_ptr_t;
62 
63  pixel_impl_base_(I& image, value_ptr_t* value_ptr)
64  : image_(image),
65  value_ptr_(value_ptr)
66  {
67  }
68 
69  protected:
70 
72  I& image_;
73 
75  value_ptr_t* value_ptr_;
76  };
77 
78 
79  template <typename I, typename E>
80  struct pixel_impl_base_< true, I, E > // I is fastest => extra interface.
81  {
82  typedef mlc_if(mlc_is_const(I), const mln_value(I), mln_value(I)) value_ptr_t;
83  typedef mlc_unconst(I) unconst_image_t;
84 
85  pixel_impl_base_(I& image, value_ptr_t* value_ptr)
86  : image_(image),
87  value_ptr_(value_ptr)
88  {
89  }
90 
91  unsigned offset() const
92  {
93  return value_ptr_ - image_.buffer();
94  }
95 
96  operator util::pix<unconst_image_t>() const
97  {
98  util::pix<unconst_image_t> tmp(image_, image_.point_at_index(offset()));
99  return tmp;
100  }
101 
102  protected:
103 
105  I& image_;
106 
108  value_ptr_t* value_ptr_;
109  };
110 
111 
115  template <typename I, typename E>
116  class pixel_impl_
117 
118  : public pixel_impl_base_< mlc_is(mln_trait_image_speed(I),
119  trait::image::speed::fastest)::value,
120  I, E >
121  {
122  typedef pixel_impl_base_< mlc_is(mln_trait_image_speed(I),
123  trait::image::speed::fastest)::value,
124  I, E > super_;
125 
126  public:
127 
129  typedef I image;
130 
132  typedef mln_value(I) value;
133 
135  typedef mln_lvalue(I) lvalue;
136 
138  typedef mln_rvalue(I) rvalue;
139 
140 
142  lvalue val();
143 
145  rvalue val() const;
146 
147 
149  I& ima() const;
150 
151 
153  value** address_() const;
154 
155  protected:
156 
158  using super_::image_;
159 
161  using super_::value_ptr_;
162 
164  pixel_impl_(I& image);
165 
166  private:
167  bool is_valid_() const;
168  };
169 
170 
174  template <typename I, typename E>
175  class pixel_impl_< const I, E >
176 
177  : public pixel_impl_base_< mlc_is(mln_trait_image_speed(I),
178  trait::image::speed::fastest)::value,
179  const I, E >
180  {
181  typedef pixel_impl_base_< mlc_is(mln_trait_image_speed(I),
182  trait::image::speed::fastest)::value,
183  const I, E > super_;
184 
185  public:
186 
188  typedef const I image;
189 
191  typedef mln_value(I) value;
192 
194  typedef mln_rvalue(I) rvalue;
195 
196 
198  rvalue val() const;
199 
200 
202  const I& ima() const;
203 
204 
206  const value** address_() const;
207 
208 
209  protected:
210 
212  using super_::image_;
213 
215  using super_::value_ptr_;
216 
218  pixel_impl_(const I& image);
219 
220  private:
221  bool is_valid_() const;
222  };
223 
224 
225 #ifndef MLN_INCLUDE_ONLY
226 
227  // pixel_impl_<I, E>
228 
229  template <typename I, typename E>
230  inline
231  bool
232  pixel_impl_<I, E>::is_valid_() const
233  {
234  return this->value_ptr_ != 0 && internal::force_exact<E>(*this).is_valid();
235  }
236 
237  template <typename I, typename E>
238  inline
239  pixel_impl_<I, E>::pixel_impl_(I& image) :
240  super_(image, 0)
241  {
242  }
243 
244  template <typename I, typename E>
245  inline
246  mln_lvalue(I)
247  pixel_impl_<I, E>::val()
248  {
249  mln_precondition(is_valid_());
250  return *this->value_ptr_;
251  }
252 
253  template <typename I, typename E>
254  inline
255  mln_rvalue(I)
256  pixel_impl_<I, E>::val() const
257  {
258  mln_precondition(is_valid_());
259  return *this->value_ptr_;
260  }
261 
262  template <typename I, typename E>
263  inline
264  I&
265  pixel_impl_<I, E>::ima() const
266  {
267  // a const pixel, yet a mutable image
268  return const_cast<I&>(this->image_);
269  }
270 
271  template <typename I, typename E>
272  inline
273  mln_value(I) **
274  pixel_impl_<I, E>::address_() const
275  {
276  return (value**)(& this->value_ptr_);
277  }
278 
279 
280  // pixel_impl_<const I, E>
281 
282  template <typename I, typename E>
283  inline
284  bool
285  pixel_impl_<const I, E>::is_valid_() const
286  {
287  return this->value_ptr_ != 0 && internal::force_exact<E>(*this).is_valid();
288  }
289 
290  template <typename I, typename E>
291  inline
292  pixel_impl_<const I, E>::pixel_impl_(const I& image) :
293  super_(image, 0)
294  {
295  }
296 
297  template <typename I, typename E>
298  inline
299  mln_rvalue(I)
300  pixel_impl_<const I, E>::val() const
301  {
302  mln_precondition(is_valid_());
303  return *this->value_ptr_;
304  }
305 
306  template <typename I, typename E>
307  inline
308  const I&
309  pixel_impl_<const I, E>::ima() const
310  {
311  return this->image_;
312  }
313 
314  template <typename I, typename E>
315  inline
316  const mln_value(I) **
317  pixel_impl_<const I, E>::address_() const
318  {
319  return (const value**)(& this->value_ptr_);
320  }
321 
322 #endif // ! MLN_INCLUDE_ONLY
323 
324  } // end of namespace internal
325 
326 } // end of namespace mln
327 
328 
329 #endif // ! MLN_CORE_INTERNAL_PIXEL_IMPL_HH