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_GENERAL_HH
00027 # define MLN_MORPHO_GENERAL_HH
00028 
00035 
00036 # include <mln/core/concept/image.hh>
00037 # include <mln/core/concept/window.hh>
00038 # include <mln/core/concept/neighborhood.hh>
00039 
00040 # include <mln/extension/adjust_fill.hh>
00041 # include <mln/accu/transform.hh>
00042 
00043 
00044 # include <mln/morpho/general.spe.hh>
00045 
00046 
00047 # define mln_morpho_select_accu(I, S, F)                                \
00048 typename mln::metal::if_< mln::metal::is< mln_trait_image_kind(I),      \
00049                                           trait::image::kind::binary >, \
00050                           mln::accu::meta::S,                           \
00051                           mln::accu::meta::F >::ret
00052 
00053 
00054 namespace mln
00055 {
00056 
00057   namespace morpho
00058   {
00059 
00061     template <typename Op, typename I, typename W>
00062     mln_concrete(I)
00063     general(const Op& op, const Image<I>& input, const Window<W>& win);
00064 
00065 
00066 # ifndef MLN_INCLUDE_ONLY
00067 
00068 
00069     namespace internal
00070     {
00071 
00072       template <typename Op, typename I, typename W>
00073       inline
00074       void
00075       general_tests(const Op& op, const Image<I>& input_, const Window<W>& win_)
00076       {
00077         const I& input = exact(input_);
00078         const W& win   = exact(win_);
00079 
00080         mln_precondition(input.is_valid());
00081         mln_precondition(! win.is_empty());
00082         mln_precondition(win.is_valid());
00083 
00084         (void) op;
00085         (void) input;
00086         (void) win;
00087       }
00088 
00089 
00090       
00091       template <typename I, bool is_binary> 
00092       struct neutral_impl
00093       {
00094         static mln_value(I) infimum()  { return false; }
00095         static mln_value(I) supremum() { return true;  }
00096       };
00097       template <typename I>
00098       struct neutral_impl< I, false >
00099       {
00100         static mln_value(I) infimum()  { return mln_min(mln_value(I)); }
00101         static mln_value(I) supremum() { return mln_max(mln_value(I)); }
00102       };
00103       template <typename I>
00104       struct neutral : neutral_impl< I, mlc_is(mln_trait_image_kind(I),
00105                                                trait::image::kind::binary)::value >
00106       {
00107       };
00108 
00109     } 
00110 
00111 
00112     namespace impl
00113     {
00114 
00115       namespace generic
00116       {
00117 
00118 
00119         
00120 
00121         template <typename Op, typename I, typename W>
00122         inline
00123         mln_concrete(I)
00124         general_on_function(const Op& op, const Image<I>& input, const Window<W>& win)
00125         {
00126           trace::entering("morpho::impl::generic::general_on_function");
00127 
00128           internal::general_tests(op, input, win);
00129 
00130           extension::adjust_fill(input, win, op.neutral(input));
00131           mln_concrete(I) output;
00132           output = accu::transform(input, op.accu(input), win);
00133 
00134           trace::exiting("morpho::impl::generic::general_on_function");
00135           return output;
00136         }
00137 
00138         
00139 
00140         template <typename Op, typename I, typename W>
00141         inline
00142         mln_concrete(I)
00143         general_on_set(const Op& op, const Image<I>& input, const Window<W>& win)
00144         {
00145           trace::entering("morpho::impl::generic::general_on_set");
00146 
00147           internal::general_tests(op, input, win);
00148 
00149           extension::adjust_fill(input, win, op.neutral(input));
00150           mln_concrete(I) output;
00151           output = accu::transform_stop(input, op.accu(input), win);
00152 
00153           trace::exiting("morpho::impl::generic::general_on_set");
00154           return output;
00155         }
00156 
00157       } 
00158 
00159     } 
00160 
00161 
00162 
00163     
00164 
00165     template <typename Op, typename I, typename W>
00166     inline
00167     mln_concrete(I)
00168     general(const Op& op, const Image<I>& input, const Window<W>& win)
00169     {
00170       trace::entering("morpho::general");
00171       mln_precondition(exact(input).is_valid());
00172       mln_precondition(! exact(win).is_empty());
00173 
00174       internal::general_tests(op, input, win);
00175       mln_concrete(I) output = internal::general_dispatch(op, input, win);
00176 
00177       trace::exiting("morpho::general");
00178       return output;
00179     }
00180 
00181 # endif // ! MLN_INCLUDE_ONLY
00182 
00183   } 
00184 
00185 } 
00186 
00187 
00188 #endif // ! MLN_MORPHO_GENERAL_HH