Milena (Olena)  User documentation 2.0a Id
dpoints_pixter.hh
00001 // Copyright (C) 2007, 2008, 2009, 2011 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_DPOINTS_PIXTER_HH
00028 # define MLN_CORE_DPOINTS_PIXTER_HH
00029 
00036 
00037 # include <cassert>
00038 # include <vector>
00039 
00040 # include <mln/core/concept/proxy.hh>
00041 # include <mln/core/concept/pixel_iterator.hh>
00042 # include <mln/core/internal/pixel_impl.hh>
00043 # include <mln/metal/converts_to.hh>
00044 
00045 
00046 namespace mln
00047 {
00048 
00049   /*------------------------.
00050   | dpoints_fwd_pixter<I>.  |
00051   `------------------------*/
00052 
00057   template <typename I>
00058   class dpoints_fwd_pixter
00059     : public Pixel_Iterator< dpoints_fwd_pixter<I> >,
00060       public internal::pixel_impl_< I, dpoints_fwd_pixter<I> >
00061   {
00062     typedef typename internal::pixel_impl_< I, dpoints_fwd_pixter<I> > super_;
00063 
00064   public:
00072     template <typename Dps, typename Pref>
00073     dpoints_fwd_pixter(I& image,
00074                        const Dps& dps,
00075                        const Pref& p_ref);
00076 
00082     template <typename Dps, typename Pref>
00083     dpoints_fwd_pixter(const Generalized_Pixel<Pref>& pxl_ref,
00084                        const Dps& dps);
00085 
00089     void start();
00091     void next_();
00092 
00094     void invalidate();
00096     bool is_valid() const;
00097 
00100     void update();
00102 
00104     const mln_value(I)& center_val() const;
00105 
00106   private:
00107     template <typename Dps>
00108     void init_(const Dps& dps);
00109 
00110   private:
00116     std::vector<int> offset_;
00118     typename std::vector<int>::const_iterator i_;
00119 
00125     mln_qlf_value(I)** value_ref_;
00127     const mln_psite(I)* p_ref_;
00129   };
00130 
00131 
00132   /*------------------------.
00133   | dpoints_bkd_pixter<I>.  |
00134   `------------------------*/
00135 
00140   template <typename I>
00141   class dpoints_bkd_pixter
00142     : public Pixel_Iterator< dpoints_bkd_pixter<I> >,
00143       public internal::pixel_impl_< I, dpoints_bkd_pixter<I> >
00144   {
00145     typedef typename internal::pixel_impl_< I, dpoints_bkd_pixter<I> > super_;
00146 
00147   public:
00155     template <typename Dps, typename Pref>
00156     dpoints_bkd_pixter(I& image,
00157                        const Dps& dps,
00158                        const Pref& p_ref);
00159 
00165     template <typename Dps, typename Pref>
00166     dpoints_bkd_pixter(const Generalized_Pixel<Pref>& pxl_ref,
00167                        const Dps& dps);
00168 
00172     void start();
00174     void next_();
00175 
00177     void invalidate();
00179     bool is_valid() const;
00180 
00183     void update();
00185 
00187     const mln_value(I)& center_val() const;
00188 
00189   private:
00190     template <typename Dps>
00191     void init_(const Dps& dps);
00192 
00193   private:
00199     std::vector<int> offset_;
00201     typename std::vector<int>::const_reverse_iterator i_;
00202 
00208     mln_qlf_value(I)** value_ref_;
00210     const mln_psite(I)* p_ref_;
00212   };
00213 
00214 
00215 
00216 #ifndef MLN_INCLUDE_ONLY
00217 
00218   /*------------------------.
00219   | dpoints_fwd_pixter<I>.  |
00220   `------------------------*/
00221 
00222   template <typename I>
00223   template <typename Dps, typename Pref>
00224   inline
00225   dpoints_fwd_pixter<I>::dpoints_fwd_pixter(I& image,
00226                                             const Dps& dps,
00227                                             const Pref& p_ref)
00228     : super_(image)
00229   {
00230     mln_precondition(image.is_valid());
00231 
00232     mlc_converts_to(Pref, const mln_psite(I)&)::check();
00233     p_ref_ = & static_cast< const mln_psite(I)& >(p_ref);
00234 
00235     value_ref_ = 0;
00236     init_(dps);
00237   }
00238 
00239   template <typename I>
00240   template <typename Dps, typename Pref>
00241   inline
00242   dpoints_fwd_pixter<I>::dpoints_fwd_pixter(const Generalized_Pixel<Pref>& pxl_ref_,
00243                                             const Dps& dps)
00244     : super_(internal::force_exact<Pref>(pxl_ref_).ima())
00245   {
00246     const Pref& pxl_ref = internal::force_exact<Pref>(pxl_ref_);
00247     mln_precondition(pxl_ref.ima().is_valid());
00248     p_ref_ = 0;
00249     // Potential promotion from (T**) to (const T**) shall be forced.
00250     value_ref_ = const_cast<mln_qlf_value(I)**>(pxl_ref.address_());
00251     init_(dps);
00252   }
00253 
00254   template <typename I>
00255   inline
00256   const mln_value(I)&
00257   dpoints_fwd_pixter<I>::center_val() const
00258   {
00259     mln_invariant(value_ref_ != 0 || p_ref_ != 0);
00260     if (p_ref_)
00261       return this->image_(*p_ref_);
00262     else
00263       return **value_ref_;
00264   }
00265 
00266   template <typename I>
00267   template <typename Dps>
00268   inline
00269   void
00270   dpoints_fwd_pixter<I>::init_(const Dps& dps)
00271   {
00272     for (unsigned i = 0; i < dps.size(); ++i)
00273       offset_.push_back(this->image_.delta_index(dps.dp(i)));
00274     // offset_[0] is absolute
00275     // other offsets are relative:
00276     if (dps.size() > 1)
00277       for (unsigned i = dps.size() - 1; i > 0; --i)
00278         offset_[i] -= offset_[i - 1];
00279     invalidate();
00280   }
00281 
00282   template <typename I>
00283   inline
00284   void
00285   dpoints_fwd_pixter<I>::update()
00286   {
00287     if (is_valid())
00288       {
00289         if (p_ref_)
00290           this->value_ptr_ = & this->image_(*p_ref_) + *i_;
00291         else
00292           this->value_ptr_ = * value_ref_ + *i_;
00293       }
00294   }
00295 
00296   template <typename I>
00297   inline
00298   void
00299   dpoints_fwd_pixter<I>::start()
00300   {
00301     i_ = offset_.begin();
00302     update();
00303   }
00304 
00305   template <typename I>
00306   inline
00307   void
00308   dpoints_fwd_pixter<I>::next_()
00309   {
00310     ++i_;
00311     if (is_valid())
00312       this->value_ptr_ += *i_;
00313   }
00314 
00315   template <typename I>
00316   inline
00317   bool
00318   dpoints_fwd_pixter<I>::is_valid() const
00319   {
00320     return i_ != offset_.end();
00321   }
00322 
00323   template <typename I>
00324   inline
00325   void
00326   dpoints_fwd_pixter<I>::invalidate()
00327   {
00328     i_ = offset_.end();
00329   }
00330 
00331 
00332   /*------------------------.
00333   | dpoints_bkd_pixter<I>.  |
00334   `------------------------*/
00335 
00336   template <typename I>
00337   template <typename Dps, typename Pref>
00338   inline
00339   dpoints_bkd_pixter<I>::dpoints_bkd_pixter(I& image,
00340                                             const Dps& dps,
00341                                             const Pref& p_ref)
00342     : super_(image)
00343   {
00344     mln_precondition(image.is_valid());
00345     internal::get_adr(p_ref_, p_ref);
00346     value_ref_ = 0;
00347     init_(dps);
00348   }
00349 
00350   template <typename I>
00351   template <typename Dps, typename Pref>
00352   inline
00353   dpoints_bkd_pixter<I>::dpoints_bkd_pixter(const Generalized_Pixel<Pref>& pxl_ref_,
00354                                             const Dps& dps)
00355     : super_(internal::force_exact<Pref>(pxl_ref_).ima())
00356   {
00357     const Pref& pxl_ref = internal::force_exact<Pref>(pxl_ref_);
00358     mln_precondition(pxl_ref.ima().is_valid());
00359     p_ref_ = 0;
00360     // Potential promotion from (T**) to (const T**) shall be forced.
00361     value_ref_ = const_cast<mln_qlf_value(I)**>(pxl_ref.address_());
00362     init_(dps);
00363   }
00364 
00365   template <typename I>
00366   inline
00367   const mln_value(I)&
00368   dpoints_bkd_pixter<I>::center_val() const
00369   {
00370     mln_invariant(value_ref_ != 0 || p_ref_ != 0);
00371     if (p_ref_)
00372       return this->image_(*p_ref_);
00373     else
00374       return **value_ref_;
00375   }
00376 
00377   template <typename I>
00378   template <typename Dps>
00379   inline
00380   void
00381   dpoints_bkd_pixter<I>::init_(const Dps& dps)
00382   {
00383     for (unsigned i = 0; i < dps.size(); ++i)
00384       offset_.push_back(this->image_.delta_index(dps.dp(i)));
00385     // offset_[size() - 1] is absolute
00386     // other offsets are relative:
00387     if (dps.size() > 1)
00388       for (unsigned i = 0; i < dps.size() - 1; ++i)
00389         offset_[i] -= offset_[i + 1];
00390     invalidate();
00391   }
00392 
00393   template <typename I>
00394   inline
00395   void
00396   dpoints_bkd_pixter<I>::update()
00397   {
00398     if (is_valid())
00399       {
00400         if (p_ref_)
00401           this->value_ptr_ = & this->image_(*p_ref_) + *i_;
00402         else
00403           this->value_ptr_ = * value_ref_ + *i_;
00404       }
00405   }
00406 
00407   template <typename I>
00408   inline
00409   void
00410   dpoints_bkd_pixter<I>::start()
00411   {
00412     i_ = offset_.rbegin();
00413     update();
00414   }
00415 
00416   template <typename I>
00417   inline
00418   void
00419   dpoints_bkd_pixter<I>::next_()
00420   {
00421     ++i_;
00422     if (is_valid())
00423       this->value_ptr_ += *i_;
00424   }
00425 
00426   template <typename I>
00427   inline
00428   bool
00429   dpoints_bkd_pixter<I>::is_valid() const
00430   {
00431     return i_ != offset_.rend();
00432   }
00433 
00434   template <typename I>
00435   inline
00436   void
00437   dpoints_bkd_pixter<I>::invalidate()
00438   {
00439     i_ = offset_.rend();
00440   }
00441 
00442 #endif // ! MLN_INCLUDE_ONLY
00443 
00444 } // end of namespace mln
00445 
00446 
00447 #endif // ! MLN_CORE_DPOINTS_PIXTER_HH
 All Classes Namespaces Functions Variables Typedefs Enumerator