Milena (Olena)
User documentation 2.0a Id
|
00001 // Copyright (C) 2007, 2008, 2009, 2010 EPITA Research and Development 00002 // Laboratory (LRDE) 00003 // 00004 // This file is part of Olena. 00005 // 00006 // Olena is free software: you can redistribute it and/or modify it under 00007 // the terms of the GNU General Public License as published by the Free 00008 // Software Foundation, version 2 of the License. 00009 // 00010 // Olena is distributed in the hope that it will be useful, 00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 // General Public License for more details. 00014 // 00015 // You should have received a copy of the GNU General Public License 00016 // along with Olena. If not, see <http://www.gnu.org/licenses/>. 00017 // 00018 // As a special exception, you may use this file as part of a free 00019 // software project without restriction. Specifically, if other files 00020 // instantiate templates or use macros or inline functions from this 00021 // file, or you compile this file and link it with other files to produce 00022 // an executable, this file does not by itself cause the resulting 00023 // executable to be covered by the GNU General Public License. This 00024 // exception does not however invalidate any other reasons why the 00025 // executable file might be covered by the GNU General Public License. 00026 00027 #ifndef MLN_CORE_INTERNAL_PIXEL_IMPL_HH 00028 # define MLN_CORE_INTERNAL_PIXEL_IMPL_HH 00029 00036 00037 # include <mln/core/concept/image.hh> 00038 # include <mln/core/internal/force_exact.hh> 00039 # include <mln/util/pix.hh> 00040 00041 00042 00043 namespace mln 00044 { 00045 00046 namespace internal 00047 { 00048 00049 // We indeed have to handle the couple of cases when I is fastest 00050 // or is not. Justification: mln::pixel derives from pixel_impl_ 00051 // and is a general purpose pixel class; it can be used on any 00052 // image whatever it is a fastest one or not. 00053 00054 template <bool is_fastest, typename I, typename E> 00055 struct pixel_impl_base_; 00056 00057 00058 template <typename I, typename E> 00059 struct pixel_impl_base_< false, I, E > // I is not fastest. 00060 { 00061 typedef mlc_if(mlc_is_const(I), const mln_value(I), mln_value(I)) value_ptr_t; 00062 00063 pixel_impl_base_(I& image, value_ptr_t* value_ptr) 00064 : image_(image), 00065 value_ptr_(value_ptr) 00066 { 00067 } 00068 00069 protected: 00070 00072 I& image_; 00073 00075 value_ptr_t* value_ptr_; 00076 }; 00077 00078 00079 template <typename I, typename E> 00080 struct pixel_impl_base_< true, I, E > // I is fastest => extra interface. 00081 { 00082 typedef mlc_if(mlc_is_const(I), const mln_value(I), mln_value(I)) value_ptr_t; 00083 typedef mlc_unconst(I) unconst_image_t; 00084 00085 pixel_impl_base_(I& image, value_ptr_t* value_ptr) 00086 : image_(image), 00087 value_ptr_(value_ptr) 00088 { 00089 } 00090 00091 unsigned offset() const 00092 { 00093 return value_ptr_ - image_.buffer(); 00094 } 00095 00096 operator util::pix<unconst_image_t>() const 00097 { 00098 util::pix<unconst_image_t> tmp(image_, image_.point_at_index(offset())); 00099 return tmp; 00100 } 00101 00102 protected: 00103 00105 I& image_; 00106 00108 value_ptr_t* value_ptr_; 00109 }; 00110 00111 00115 template <typename I, typename E> 00116 class pixel_impl_ 00117 00118 : public pixel_impl_base_< mlc_is(mln_trait_image_speed(I), 00119 trait::image::speed::fastest)::value, 00120 I, E > 00121 { 00122 typedef pixel_impl_base_< mlc_is(mln_trait_image_speed(I), 00123 trait::image::speed::fastest)::value, 00124 I, E > super_; 00125 00126 public: 00127 00129 typedef I image; 00130 00132 typedef mln_value(I) value; 00133 00135 typedef mln_lvalue(I) lvalue; 00136 00138 typedef mln_rvalue(I) rvalue; 00139 00140 00142 lvalue val(); 00143 00145 rvalue val() const; 00146 00147 00149 I& ima() const; 00150 00151 00153 value** address_() const; 00154 00155 protected: 00156 00158 using super_::image_; 00159 00161 using super_::value_ptr_; 00162 00164 pixel_impl_(I& image); 00165 00166 private: 00167 bool is_valid_() const; 00168 }; 00169 00170 00174 template <typename I, typename E> 00175 class pixel_impl_< const I, E > 00176 00177 : public pixel_impl_base_< mlc_is(mln_trait_image_speed(I), 00178 trait::image::speed::fastest)::value, 00179 const I, E > 00180 { 00181 typedef pixel_impl_base_< mlc_is(mln_trait_image_speed(I), 00182 trait::image::speed::fastest)::value, 00183 const I, E > super_; 00184 00185 public: 00186 00188 typedef const I image; 00189 00191 typedef mln_value(I) value; 00192 00194 typedef mln_rvalue(I) rvalue; 00195 00196 00198 rvalue val() const; 00199 00200 00202 const I& ima() const; 00203 00204 00206 const value** address_() const; 00207 00208 00209 protected: 00210 00212 using super_::image_; 00213 00215 using super_::value_ptr_; 00216 00218 pixel_impl_(const I& image); 00219 00220 private: 00221 bool is_valid_() const; 00222 }; 00223 00224 00225 #ifndef MLN_INCLUDE_ONLY 00226 00227 // pixel_impl_<I, E> 00228 00229 template <typename I, typename E> 00230 inline 00231 bool 00232 pixel_impl_<I, E>::is_valid_() const 00233 { 00234 return this->value_ptr_ != 0 && internal::force_exact<E>(*this).is_valid(); 00235 } 00236 00237 template <typename I, typename E> 00238 inline 00239 pixel_impl_<I, E>::pixel_impl_(I& image) : 00240 super_(image, 0) 00241 { 00242 } 00243 00244 template <typename I, typename E> 00245 inline 00246 mln_lvalue(I) 00247 pixel_impl_<I, E>::val() 00248 { 00249 mln_precondition(is_valid_()); 00250 return *this->value_ptr_; 00251 } 00252 00253 template <typename I, typename E> 00254 inline 00255 mln_rvalue(I) 00256 pixel_impl_<I, E>::val() const 00257 { 00258 mln_precondition(is_valid_()); 00259 return *this->value_ptr_; 00260 } 00261 00262 template <typename I, typename E> 00263 inline 00264 I& 00265 pixel_impl_<I, E>::ima() const 00266 { 00267 // a const pixel, yet a mutable image 00268 return const_cast<I&>(this->image_); 00269 } 00270 00271 template <typename I, typename E> 00272 inline 00273 mln_value(I) ** 00274 pixel_impl_<I, E>::address_() const 00275 { 00276 return (value**)(& this->value_ptr_); 00277 } 00278 00279 00280 // pixel_impl_<const I, E> 00281 00282 template <typename I, typename E> 00283 inline 00284 bool 00285 pixel_impl_<const I, E>::is_valid_() const 00286 { 00287 return this->value_ptr_ != 0 && internal::force_exact<E>(*this).is_valid(); 00288 } 00289 00290 template <typename I, typename E> 00291 inline 00292 pixel_impl_<const I, E>::pixel_impl_(const I& image) : 00293 super_(image, 0) 00294 { 00295 } 00296 00297 template <typename I, typename E> 00298 inline 00299 mln_rvalue(I) 00300 pixel_impl_<const I, E>::val() const 00301 { 00302 mln_precondition(is_valid_()); 00303 return *this->value_ptr_; 00304 } 00305 00306 template <typename I, typename E> 00307 inline 00308 const I& 00309 pixel_impl_<const I, E>::ima() const 00310 { 00311 return this->image_; 00312 } 00313 00314 template <typename I, typename E> 00315 inline 00316 const mln_value(I) ** 00317 pixel_impl_<const I, E>::address_() const 00318 { 00319 return (const value**)(& this->value_ptr_); 00320 } 00321 00322 #endif // ! MLN_INCLUDE_ONLY 00323 00324 } // end of namespace internal 00325 00326 } // end of namespace mln 00327 00328 00329 #endif // ! MLN_CORE_INTERNAL_PIXEL_IMPL_HH