00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 #ifndef MLN_MORPHO_ELEMENTARY_LIKE_ERO_FUN_HH
00027 # define MLN_MORPHO_ELEMENTARY_LIKE_ERO_FUN_HH
00028 
00032 
00033 
00034 # include <mln/morpho/includes.hh>
00035 
00036 
00037 namespace mln
00038 {
00039 
00040   namespace morpho
00041   {
00042 
00043     namespace elementary
00044     {
00045 
00046       template <typename A, typename F,
00047                 typename I, typename N>
00048       mln_concrete(I)
00049       like_ero_fun(const Meta_Accumulator<A>& a, const F& f,
00050                    const Image<I>& input, const Neighborhood<N>& nbh);
00051 
00052 
00053 
00054 # ifndef MLN_INCLUDE_ONLY
00055 
00056       namespace internal
00057       {
00058 
00059         struct f_accu
00060         {
00061           template <typename V, typename A>
00062           V operator()(const V& , const A& a) const
00063           {
00064             return a.to_result();
00065           }
00066         };
00067 
00068       } 
00069 
00070 
00071       namespace impl
00072       {
00073 
00074         namespace generic
00075         {
00076 
00077           template <typename A, typename F,
00078                     typename I, typename N>
00079           mln_concrete(I)
00080           like_ero_fun(const Meta_Accumulator<A>& a_, const F& f,
00081                        const Image<I>& input_, const Neighborhood<N>& nbh_)
00082           {
00083             trace::entering("morpho::elementary::impl::generic::like_ero_fun");
00084 
00085             const I& input = exact(input_);
00086             const N& nbh   = exact(nbh_);
00087 
00088             mln_accu_with(A, mln_value(I)) a = accu::unmeta(exact(a_), mln_value(I)());
00089             extension::adjust_fill(input, nbh, a);
00090 
00091             mln_concrete(I) output;
00092             initialize(output, input);
00093 
00094             mln_piter(I) p(input.domain());
00095             mln_niter(N) n(nbh, p);
00096             for_all(p)
00097               {
00098                 a.take_as_init(input(p));
00099                 for_all(n) if (input.has(n))
00100                   a.take(input(n));
00101                 output(p) = f(input(p), a);
00102               }
00103 
00104             trace::exiting("morpho::elementary::impl::generic::like_ero_fun");
00105             return output;
00106           }
00107 
00108         } 
00109 
00110 
00111         template <typename A, typename F,
00112                   typename I, typename N>
00113         mln_concrete(I)
00114         like_ero_fun_fastest(const Meta_Accumulator<A>& a_, const F& f,
00115                              const Image<I>& input_, const Neighborhood<N>& nbh_)
00116         {
00117           trace::entering("morpho::elementary::impl::like_ero_fun_fastest");
00118 
00119           const I& input = exact(input_);
00120           const N& nbh   = exact(nbh_);
00121 
00122           mln_accu_with(A, mln_value(I)) a = accu::unmeta(exact(a_), mln_value(I)());
00123           extension::adjust_fill(input, nbh, a);
00124 
00125           mln_concrete(I) output;
00126           initialize(output, input);
00127 
00128           mln_pixter(const I) p_in(input);
00129           mln_pixter(I) p_out(output);
00130           mln_nixter(const I, N) n(p_in, nbh);
00131           for_all_2(p_in, p_out)
00132             {
00133               a.take_as_init(p_in.val());
00134               for_all(n)
00135                 a.take(n.val());
00136               p_out.val() = f(p_in.val(), a);
00137             }
00138 
00139           trace::exiting("morpho::elementary::impl::like_ero_fun_fastest");
00140           return output;
00141         }
00142 
00143       } 
00144 
00145 
00146       namespace internal
00147       {
00148 
00149         template <typename A, typename F,
00150                   typename I, typename N>
00151         mln_concrete(I)
00152         like_ero_fun_dispatch(metal::false_,
00153                               const A& a, const F& f,
00154                               const I& input, const N& nbh)
00155         {
00156           return impl::generic::like_ero_fun(a, f, input, nbh);
00157         }
00158 
00159         template <typename A, typename F,
00160                   typename I, typename N>
00161         mln_concrete(I)
00162         like_ero_fun_dispatch(metal::true_,
00163                               const A& a, const F& f,
00164                               const I& input, const N& nbh)
00165         {
00166           return impl::like_ero_fun_fastest(a, f, input, nbh);
00167         }
00168 
00169         template <typename A, typename F,
00170                   typename I, typename N>
00171         mln_concrete(I)
00172         like_ero_fun_dispatch(const A& a, const F& f,
00173                               const I& input, const N& nbh)
00174         {
00175           typedef mlc_equal(mln_trait_image_speed(I),
00176                             trait::image::speed::fastest) I_fastest;
00177           typedef mln_window(N) W;
00178           typedef mln_is_simple_window(W) N_simple;
00179 
00180           return like_ero_fun_dispatch(mlc_and(I_fastest, N_simple)(),
00181                                        a, f, input, nbh);
00182         }
00183 
00184       } 
00185 
00186 
00187       
00188 
00189       template <typename A, typename F,
00190                 typename I, typename N>
00191       mln_concrete(I)
00192       like_ero_fun(const Meta_Accumulator<A>& a, const F& f,
00193                    const Image<I>& input, const Neighborhood<N>& nbh)
00194       {
00195         return internal::like_ero_fun_dispatch(a, f,
00196                                                exact(input), exact(nbh));
00197       }
00198 
00199 # endif // ! MLN_INCLUDE_ONLY
00200 
00201     } 
00202 
00203   } 
00204 
00205 } 
00206 
00207 
00208 #endif // ! MLN_MORPHO_ELEMENTARY_LIKE_ERO_FUN_HH