$extrastylesheet
Olena  User documentation 2.1
An Image Processing Platform
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
pixel_impl.hh
1 // Copyright (C) 2007, 2008, 2009, 2010, 2012 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_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_offset(offset()));
99  return tmp;
100  }
101 
102  protected:
103 
105  I& image_;
106 
108  value_ptr_t* value_ptr_;
109  };
110 
111 
117  template <typename I, typename E>
119 
120  : public pixel_impl_base_< mlc_is(mln_trait_image_speed(I),
121  trait::image::speed::fastest)::value,
122  I, E >
123  {
124  typedef pixel_impl_base_< mlc_is(mln_trait_image_speed(I),
125  trait::image::speed::fastest)::value,
126  I, E > super_;
127 
128  public:
129 
131  typedef I image;
132 
134  typedef mln_value(I) value;
135 
137  typedef mln_lvalue(I) lvalue;
138 
140  typedef mln_rvalue(I) rvalue;
141 
142 
144  lvalue val();
145 
147  rvalue val() const;
148 
149 
151  I& ima() const;
152 
153 
155  value** address_() const;
156 
157  protected:
158 
160  using super_::image_;
161 
163  using super_::value_ptr_;
164 
166  pixel_impl_(I& image);
167 
168  private:
169  bool is_valid_() const;
170  };
171 
172 
178  template <typename I, typename E>
179  class pixel_impl_< const I, E >
180 
181  : public pixel_impl_base_< mlc_is(mln_trait_image_speed(I),
182  trait::image::speed::fastest)::value,
183  const I, E >
184  {
185  typedef pixel_impl_base_< mlc_is(mln_trait_image_speed(I),
186  trait::image::speed::fastest)::value,
187  const I, E > super_;
188 
189  public:
190 
192  typedef const I image;
193 
195  typedef mln_value(I) value;
196 
198  typedef mln_rvalue(I) rvalue;
199 
200 
202  rvalue val() const;
203 
204 
206  const I& ima() const;
207 
208 
210  const value** address_() const;
211 
212 
213  protected:
214 
216  using super_::image_;
217 
219  using super_::value_ptr_;
220 
222  pixel_impl_(const I& image);
223 
224  private:
225  bool is_valid_() const;
226  };
227 
228 
229 #ifndef MLN_INCLUDE_ONLY
230 
231  // pixel_impl_<I, E>
232 
233  template <typename I, typename E>
234  inline
235  bool
237  {
238  return this->value_ptr_ != 0 && internal::force_exact<E>(*this).is_valid();
239  }
240 
241  template <typename I, typename E>
242  inline
244  super_(image, 0)
245  {
246  }
247 
248  template <typename I, typename E>
249  inline
250  mln_lvalue(I)
251  pixel_impl_<I, E>::val()
252  {
253  mln_precondition(is_valid_());
254  return *this->value_ptr_;
255  }
256 
257  template <typename I, typename E>
258  inline
259  mln_rvalue(I)
260  pixel_impl_<I, E>::val() const
261  {
262  mln_precondition(is_valid_());
263  return *this->value_ptr_;
264  }
265 
266  template <typename I, typename E>
267  inline
268  I&
269  pixel_impl_<I, E>::ima() const
270  {
271  // a const pixel, yet a mutable image
272  return const_cast<I&>(this->image_);
273  }
274 
275  template <typename I, typename E>
276  inline
277  mln_value(I) **
279  {
280  return (value**)(& this->value_ptr_);
281  }
282 
283 
284  // pixel_impl_<const I, E>
285 
286  template <typename I, typename E>
287  inline
288  bool
289  pixel_impl_<const I, E>::is_valid_() const
290  {
291  return this->value_ptr_ != 0 && internal::force_exact<E>(*this).is_valid();
292  }
293 
294  template <typename I, typename E>
295  inline
296  pixel_impl_<const I, E>::pixel_impl_(const I& image) :
297  super_(image, 0)
298  {
299  }
300 
301  template <typename I, typename E>
302  inline
303  mln_rvalue(I)
304  pixel_impl_<const I, E>::val() const
305  {
306  mln_precondition(is_valid_());
307  return *this->value_ptr_;
308  }
309 
310  template <typename I, typename E>
311  inline
312  const I&
314  {
315  return this->image_;
316  }
317 
318  template <typename I, typename E>
319  inline
320  const mln_value(I) **
322  {
323  return (const value**)(& this->value_ptr_);
324  }
325 
326 #endif // ! MLN_INCLUDE_ONLY
327 
328  } // end of namespace internal
329 
330 } // end of namespace mln
331 
332 
333 #endif // ! MLN_CORE_INTERNAL_PIXEL_IMPL_HH