• Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Classes
  • Files
  • File List

pixel_impl.hh

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

Generated on Thu Sep 8 2011 18:32:20 for Milena (Olena) by  doxygen 1.7.1