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

value_and_compute.hh

00001 // Copyright (C) 2010 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_LABELING_VALUE_AND_COMPUTE_HH
00027 # define MLN_LABELING_VALUE_AND_COMPUTE_HH
00028 
00032 
00033 # include <mln/core/concept/image.hh>
00034 # include <mln/core/concept/neighborhood.hh>
00035 # include <mln/canvas/labeling/video.hh>
00036 # include <mln/data/fill.hh>
00037 
00038 
00039 
00040 namespace mln
00041 {
00042 
00043   namespace labeling
00044   {
00045 
00054     //
00055     template <typename I, typename N, typename L, typename A>
00056     util::couple<mln_ch_value(I,L),
00057                  util::couple<util::array<mln_result(A)>,
00058                               util::array<A> > >
00059     value_and_compute(const Image<I>& input, const mln_value(I)& val,
00060                       const Neighborhood<N>& nbh, L& nlabels,
00061                       const Accumulator<A>& accu);
00062 
00063 
00064 # ifndef MLN_INCLUDE_ONLY
00065 
00066 
00067     // Tests.
00068 
00069     namespace internal
00070     {
00071 
00072       template <typename I, typename N, typename L, typename A>
00073       void
00074       value_and_compute_tests(const Image<I>& input, const mln_value(I)& val,
00075                               const Neighborhood<N>& nbh, L& nlabels,
00076                               const Accumulator<A>& accu)
00077       {
00078         mln_precondition(exact(input).is_valid());
00079         mln_precondition(exact(nbh).is_valid());
00080 
00081         (void) accu;
00082         (void) input;
00083         (void) val;
00084         (void) nbh;
00085         (void) nlabels;
00086       }
00087 
00088     } // end of namespace mln::labeling::internal
00089 
00090 
00091 
00092     namespace impl
00093     {
00094 
00095       // Generic functor.
00096 
00097       template <typename I, typename L, typename A>
00098       struct value_and_compute_functor
00099       {
00100         typedef mln_psite(I) P;
00101 
00102         util::array<mln_result(A)> result_;
00103         util::array<A> accus_;
00104 
00105         const I& input;
00106         const mln_value(I)& val;
00107 
00108         typedef mln_result(A) accu_result;
00109         typedef mln_argument(A) accu_argument;
00110         typedef util::couple<util::array<accu_result>,
00111                              util::array<A> > result;
00112 
00113 
00114         // Requirements from mln::canvas::labeling.
00115 
00116         typedef mln_domain(I) S;
00117 
00118         // Generic implementation
00119 
00120         void init()                               {}
00121         bool handles(const P& p) const            { return input(p) == val; }
00122         bool equiv(const P& n, const P&) const    { return input(n) == val; }
00123         bool labels(const P&) const               { return true; }
00124         void do_no_union(const P&, const P&)      {}
00125         void init_attr(const P&)                  {}
00126         void merge_attr(const P&, const P&)       {}
00127         void set_new_label(const P& p, const L& l)
00128         {
00129           accus_.append(A());
00130           process__(accu_argument(), p, l);
00131         }
00132         void set_label(const P& p, const L& l)    { process__(accu_argument(), p, l); };
00133         void finalize() { convert::from_to(accus_, result_); }
00134 
00135 
00136 
00137         // Fastest implementation
00138 
00139         void init_()                              { accus_.append(A()); }
00140         bool handles_(unsigned p) const           { return input.element(p) == val; }
00141         bool equiv_(unsigned n, unsigned) const   { return input.element(n) == val; }
00142         bool labels_(unsigned) const              { return true; }
00143         void do_no_union_(unsigned, unsigned)     {}
00144         void init_attr_(unsigned)                 {}
00145         void merge_attr_(unsigned, unsigned)      {}
00146         void set_new_label_(unsigned p, const L& l)
00147         {
00148           accus_.append(A());
00149           process__(accu_argument(), p, l);
00150         };
00151         void set_label_(unsigned p, const L& l)   { process__(accu_argument(), p, l); };
00152         void finalize_() { convert::from_to(accus_, result_); }
00153 
00154         // end of Requirements.
00155 
00156 
00157 
00158         value_and_compute_functor(const Image<I>& input_, const mln_value(I)& val)
00159           : input(exact(input_)),
00160             val(val)
00161         {
00162         }
00163 
00164 
00165       private:
00166         inline
00167         void process__(const unsigned&, unsigned p, const L& l)
00168         {
00169           accus_[l].take(p);
00170         }
00171 
00172         inline
00173         void process__(const mln_psite(I)&, unsigned p, const L& l)
00174         {
00175           accus_[l].take(input.point_at_index(p));
00176         }
00177 
00178 
00179         inline
00180         void process__(const mln_psite(I)&, const mln_site(I)& p, const L& l)
00181         {
00182           accus_[l].take(p);
00183         }
00184 
00185         inline
00186         void process__(const mln_value(I)&, const mln_site(I)&, const L& l)
00187         {
00188           accus_[l].take(l);
00189         }
00190 
00191         template <typename V>
00192         inline
00193         void process__(const V&, const mln_site(I)&, const L& l)
00194         {
00195           mlc_abort(V)::check();
00196         }
00197 
00198 
00199       };
00200 
00201     } // end of namespace mln::labeling::impl
00202 
00203 
00204 
00205 
00206     // Facade.
00207 
00208     template <typename I, typename N, typename L, typename A>
00209     util::couple<mln_ch_value(I,L),
00210                  util::couple<util::array<mln_result(A)>,
00211                               util::array<A> > >
00212     value_and_compute(const Image<I>& input, const mln_value(I)& val,
00213                       const Neighborhood<N>& nbh, L& nlabels,
00214                       const Accumulator<A>& accu)
00215     {
00216       trace::entering("labeling::value_and_compute");
00217 
00218       internal::value_and_compute_tests(input, val, nbh, nlabels, accu);
00219 
00220       typedef mln_ch_value(I,L) out_t;
00221       typedef impl::value_and_compute_functor<I, L, A> func_t;
00222       func_t f(input, val);
00223       out_t output = canvas::labeling::video(input, nbh, nlabels, f);
00224 
00225       util::couple<out_t, typename func_t::result>
00226         result = make::couple(output,
00227                               make::couple(f.result_, f.accus_));
00228 
00229 
00230       trace::exiting("labeling::value_and_compute");
00231       return result;
00232     }
00233 
00234 # endif // ! MLN_INCLUDE_ONLY
00235 
00236   } // end of namespace mln::labeling
00237 
00238 } // end of namespace mln
00239 
00240 
00241 #endif // ! MLN_LABELING_VALUE_AND_COMPUTE_HH

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