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

pixel_impl.hh

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

Generated on Tue Oct 4 2011 15:24:19 for Milena (Olena) by  doxygen 1.7.1