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

transform_directional.hh

00001 // Copyright (C) 2008, 2009 EPITA Research and Development Laboratory
00002 // (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_ACCU_TRANSFORM_DIRECTIONAL_HH
00028 # define MLN_ACCU_TRANSFORM_DIRECTIONAL_HH
00029 
00037 
00038 
00039 # include <mln/core/concept/image.hh>
00040 # include <mln/core/concept/meta_accumulator.hh>
00041 # include <mln/core/alias/window2d.hh>
00042 # include <mln/win/diff.hh>
00043 # include <mln/win/shift.hh>
00044 # include <mln/geom/delta.hh>
00045 # include <mln/literal/zero.hh>
00046 # include <mln/extension/adjust.hh>
00047 # include <mln/canvas/browsing/directional.hh>
00048 
00049 
00050 
00051 namespace mln
00052 {
00053 
00054   namespace accu
00055   {
00056 
00057 
00058     template <typename A, typename I, typename W>
00059     mln_ch_value(I, mln_result(A))
00060     transform_directional(const Accumulator<A>& a,
00061                           const Image<I>& input, const Window<W>& win,
00062                           unsigned dir);
00063 
00064 
00065     template <typename A, typename I, typename W>
00066     mln_ch_value(I, mln_meta_accu_result(A, mln_value(I)))
00067     transform_directional(const Meta_Accumulator<A>& a,
00068                           const Image<I>& input, const Window<W>& win,
00069                           unsigned dir);
00070 
00071 
00072 
00073 # ifndef MLN_INCLUDE_ONLY
00074 
00075     namespace internal
00076     {
00077 
00078 
00079       // Tests.
00080 
00081 
00082       template <typename I, typename W>
00083       void transform_directional_tests(const Image<I>& input_, const Window<W>& win_)
00084       {
00085         const I& input = exact(input_);
00086         const W& win   = exact(win_);
00087 
00088         mln_precondition(input.is_valid());
00089         mln_precondition(win.is_valid());
00090         mln_precondition(! win.is_empty());
00091 
00092         (void) input;
00093         (void) win;
00094       }
00095 
00096 
00097 
00098       // Utility.
00099 
00100 
00101       template <typename Dp>
00102       Dp dp_directional(int dir)
00103       {
00104         Dp dp = literal::zero;
00105         dp[dir] = 1;
00106         return dp;
00107       }
00108 
00109 
00110 
00111       // Functor.
00112 
00113 
00114       template <typename I_, typename W, typename A>
00115       struct directional_functor
00116       {
00117         typedef I_ I;
00118         typedef mln_deduce(I, psite, delta) dpsite;
00119 
00120         const I& input;
00121         const W& win;
00122         mln_ch_value(I, mln_result(A)) output;
00123         A accu;
00124 
00125         typedef mln_site(I) S; // Help g++-2.95.
00126         enum { dim = S::dim };
00127 
00128         mln_psite(I) p;
00129         unsigned dir;
00130 
00131         window2d
00132         win_left,
00133           win_right;
00134 
00135         mln_qiter(window2d)
00136         q_l,
00137           q_r;
00138 
00139         directional_functor(const I& input, const W& win, const A& a, int dir)
00140           : input(input),
00141             win(win),
00142             accu(a),
00143             dir(dir),
00144             win_left(win::shift(win, -dp_directional<dpsite>(dir)) - win),
00145             win_right(win - win::shift(win, -dp_directional<dpsite>(dir))),
00146             q_l(win_left, p),
00147             q_r(win_right, p)
00148         {
00149 
00150         }
00151 
00152         void init()
00153         {
00154           initialize(output, input);
00155         }
00156 
00157         void init_run()
00158         {
00159           accu.init();
00160           p[dir]--;
00161           mln_qiter(W) q(win, p);
00162           for_all(q) if (input.has(q))
00163             accu.take(input(q));
00164           p[dir]++;
00165         }
00166 
00167         void next()
00168         {
00169           for_all(q_l) if (input.has(q_l))
00170             accu.untake(input(q_l));
00171           for_all(q_r) if (input.has(q_r))
00172             accu.take(input(q_r));
00173           output(p) = accu;
00174         }
00175 
00176         void final()
00177         {
00178         }
00179 
00180       };
00181 
00182 
00183 
00184       // Functor (fastest version).
00185 
00186 
00187       template <typename I_, typename W, typename A>
00188       struct directional_fastest_functor
00189       {
00190         typedef I_ I;
00191         typedef mln_deduce(I, psite, delta) dpsite;
00192 
00193         const I& input;
00194         const W& win;
00195         mln_ch_value(I, mln_result(A)) output;
00196         A accu;
00197 
00198         mln_psite(I) p;
00199         typedef mln_site(I) S;
00200         enum { dim = S::dim };
00201         unsigned dir;
00202 
00203         window2d win_left, win_right;
00204 
00205         mln_qixter(const I, window2d) q_l, q_r;
00206 
00207         directional_fastest_functor(const I& input, const W& win, const A& a, unsigned dir)
00208           : input(input),
00209             win(win),
00210             accu(a),
00211             dir(dir),
00212             win_left(win::shift(win, -dp_directional<dpsite>(dir)) - win),
00213             win_right(win - win::shift(win, -dp_directional<dpsite>(dir))),
00214             q_l(input, win_left, p),
00215             q_r(input, win_right, p)
00216         {
00217         }
00218 
00219         void init()
00220         {
00221           initialize(output, input);
00222         }
00223 
00224         void next()
00225         {
00226           for_all(q_l)
00227             accu.untake(q_l.val());
00228           for_all(q_r)
00229             accu.take(q_r.val());
00230           output(p) = accu;
00231         }
00232 
00233 
00234         void init_run()
00235         {
00236           accu.init();
00237           p[dir]--;
00238           mln_qixter(const I, W) q(input, win, p);
00239           for_all(q)
00240             accu.take(q.val());
00241           p[dir]++;
00242         }
00243 
00244         void final()
00245         {
00246         }
00247 
00248       };
00249 
00250 
00251 
00252 
00253       // Both dispatch and implementation (hum...)
00254 
00255       template <typename A, typename I, typename W>
00256       inline
00257       mln_ch_value(I, mln_result(A))
00258       transform_directional_dispatch(metal::false_,
00259                                      const Accumulator<A>& a,
00260                                      const Image<I>& input, const Window<W>& win,
00261                                      unsigned dir)
00262       {
00263         typedef directional_functor<I, W, A> F;
00264         F f(exact(input), exact(win), exact(a), dir);
00265         canvas::browsing::directional(f);
00266         return f.output;
00267       }
00268 
00269       template <typename A, typename I, typename W>
00270       inline
00271       mln_ch_value(I, mln_result(A))
00272       transform_directional_dispatch(metal::true_,
00273                                      const Accumulator<A>& a,
00274                                      const Image<I>& input, const Window<W>& win,
00275                                      unsigned dir)
00276       {
00277         typedef directional_fastest_functor<I, W, A> F;
00278         F f(exact(input), exact(win), exact(a), dir);
00279         canvas::browsing::directional(f);
00280         return f.output;
00281       }
00282 
00283       template <typename A, typename I, typename W>
00284       inline
00285       mln_ch_value(I, mln_result(A))
00286       transform_directional_dispatch(const Accumulator<A>& a,
00287                                      const Image<I>& input, const Window<W>& win,
00288                                      unsigned dir)
00289       {
00290         return transform_directional_dispatch(mln_is_fastest_IW(I, W)(),
00291                                               a, input, win, dir);
00292       }
00293 
00294     } // end of namespace mln::accu::internal
00295 
00296 
00297 
00298 
00299     template <typename A, typename I, typename W>
00300     inline
00301     mln_ch_value(I, mln_result(A))
00302     transform_directional(const Accumulator<A>& a,
00303                           const Image<I>& input, const Window<W>& win,
00304                           unsigned dir)
00305     {
00306       trace::entering("accu::transform_directional");
00307 
00308       internal::transform_directional_tests(input, win);
00309 
00310       extension::adjust(input, geom::delta(win) + 1);
00311       mln_ch_value(I, mln_result(A)) output;
00312       output = internal::transform_directional_dispatch(a, input, win, dir);
00313 
00314       trace::exiting("accu::transform_directional");
00315       return output;
00316     }
00317 
00318 
00319     template <typename A, typename I, typename W>
00320     inline
00321     mln_ch_value(I, mln_meta_accu_result(A, mln_value(I)))
00322     transform_directional(const Meta_Accumulator<A>& a,
00323                           const Image<I>& input, const Window<W>& win,
00324                           unsigned dir)
00325     {
00326       trace::entering("accu::transform_directional");
00327 
00328       internal::transform_directional_tests(input, win);
00329 
00330       typedef mln_accu_with(A, mln_value(I)) A_;
00331       A_ a_ = accu::unmeta(exact(a), mln_value(I)());
00332 
00333       extension::adjust(input, geom::delta(win) + 1);
00334       mln_ch_value(I, mln_result(A_)) output;
00335       output = internal::transform_directional_dispatch(a_, input, win, dir);
00336 
00337       trace::exiting("accu::transform_directional");
00338       return output;
00339     }
00340 
00341 
00342 # endif // ! MLN_INCLUDE_ONLY
00343 
00344   } // end of namespace mln::accu
00345 
00346 } // end of namespace mln
00347 
00348 
00349 #endif // ! MLN_ACCU_TRANSFORM_DIRECTIONAL_HH

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