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

transform_diagonal.hh

00001 // Copyright (C) 2008, 2009 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_ACCU_TRANSFORM_DIAGONAL_HH
00027 # define MLN_ACCU_TRANSFORM_DIAGONAL_HH
00028 
00036 
00037 
00038 #include <mln/core/concept/image.hh>
00039 #include <mln/core/concept/meta_accumulator.hh>
00040 #include <mln/core/alias/window2d.hh>
00041 #include <mln/win/diff.hh>
00042 #include <mln/win/shift.hh>
00043 #include <mln/geom/delta.hh>
00044 #include <mln/extension/adjust.hh>
00045 
00046 #include <mln/win/diag2d.hh>
00047 #include <mln/canvas/browsing/diagonal2d.hh>
00048 
00049 #include <mln/win/backdiag2d.hh>
00050 #include <mln/canvas/browsing/backdiagonal2d.hh>
00051 
00052 
00053 
00054 namespace mln
00055 {
00056 
00057   namespace accu
00058   {
00059 
00060 
00061     template <typename A, typename I, typename W>
00062     mln_ch_value(I, mln_result(A))
00063     transform_diagonal(const Accumulator<A>& a,
00064                        const Image<I>& input, const Window<W>& win);
00065 
00066 
00067     template <typename A, typename I, typename W>
00068     mln_ch_value(I, mln_meta_accu_result(A, mln_value(I)))
00069     transform_diagonal(const Meta_Accumulator<A>& a,
00070                        const Image<I>& input, const Window<W>& win);
00071 
00072 
00073 
00074 # ifndef MLN_INCLUDE_ONLY
00075 
00076     namespace internal
00077     {
00078 
00079 
00080       // Tests.
00081 
00082 
00083       template <typename I, typename W>
00084       void transform_diagonal_tests(const Image<I>& input_, const Window<W>& win_)
00085       {
00086         const I& input = exact(input_);
00087         const W& win   = exact(win_);
00088 
00089         mln_precondition(input.is_valid());
00090         mln_precondition(win.is_valid());
00091         mln_precondition(! win.is_empty());
00092 
00093         (void) input;
00094         (void) win;
00095       }
00096 
00097 
00098 
00099       // Functors.
00100 
00101 
00102       template <typename I_, typename W, typename A>
00103       struct diagonal_functor
00104       {
00105         typedef I_ I;
00106         typedef mln_deduce(I, psite, delta) dpsite;
00107 
00108         const I& input;
00109         const W& win;
00110         mln_ch_value(I, mln_result(A)) output;
00111         A accu;
00112 
00113         mln_psite(I) p;
00114         typedef mln_site(I) S; // Help g++-2.95.
00115         enum { dim = S::dim };
00116 
00117         window2d win_left, win_right;
00118 
00119         mln_qiter(window2d) q_l, q_r;
00120 
00121         diagonal_functor(const I& input, const W& win, const A& a)
00122           : input(input),
00123             win(win),
00124             accu(a),
00125             win_left(win::shift(win, dpsite(1, -1)) - win),
00126             win_right(win - win::shift(win, dpsite(1, -1))),
00127             q_l(win_left, p),
00128             q_r(win_right, p)
00129         {
00130         }
00131 
00132         void init()
00133         {
00134           initialize(output, input);
00135         }
00136 
00137         void next()
00138         {
00139           for_all(q_l)
00140             accu.untake(input(q_l));
00141           for_all(q_r)
00142             accu.take(input(q_r));
00143           output(p) = accu;
00144         }
00145 
00146 
00147         void init_diag()
00148         {
00149           accu.init();
00150           p = p - dpsite(-1, 1);
00151           mln_qiter(W) q(win, p);
00152           for_all(q)
00153             accu.take(input(q));
00154           p = p + dpsite(-1, 1);
00155         }
00156 
00157         void final()
00158         {
00159         }
00160 
00161       };
00162 
00163 
00164 
00165       template <typename I_, typename W, typename A>
00166       struct backdiagonal_functor
00167       {
00168         typedef I_ I;
00169         typedef mln_deduce(I, psite, delta) dpsite;
00170 
00171         const I& input;
00172         const W& win;
00173         mln_ch_value(I, mln_result(A)) output;
00174         A accu;
00175 
00176         mln_psite(I) p;
00177         typedef mln_site(I) S;
00178         enum { dim = S::dim };
00179 
00180         window2d win_left, win_right;
00181 
00182         mln_qiter(window2d) q_l, q_r;
00183 
00184         backdiagonal_functor(const I& input, const W& win, const A& a)
00185           : input(input),
00186             win(win),
00187             accu(a),
00188             win_left(win::shift(win, dpsite(-1, -1)) - win),
00189             win_right(win - win::shift(win, dpsite(-1, -1))),
00190             q_l(win_left, p),
00191             q_r(win_right, p)
00192         {
00193         }
00194 
00195         void init()
00196         {
00197           initialize(output, input);
00198         }
00199 
00200         void next()
00201         {
00202           for_all(q_l)
00203             accu.untake(input(q_l));
00204           for_all(q_r)
00205             accu.take(input(q_r));
00206           output(p) = accu;
00207         }
00208 
00209 
00210         void init_diag()
00211         {
00212           accu.init();
00213           p = p - dpsite(1, 1);
00214           mln_qiter(W) q(win, p);
00215           for_all(q)
00216             accu.take(input(q));
00217           p = p + dpsite(1, 1);
00218         }
00219 
00220         void final()
00221         {
00222         }
00223 
00224       };
00225 
00226 
00227 
00228       // Functors (fastest versions).
00229 
00230 
00231       template <typename I_, typename W, typename A>
00232       struct diagonal_fastest_functor
00233       {
00234         typedef I_ I;
00235         typedef mln_deduce(I, psite, delta) dpsite;
00236 
00237         const I& input;
00238         const W& win;
00239         mln_ch_value(I, mln_result(A)) output;
00240         A accu;
00241 
00242         mln_psite(I) p;
00243         typedef mln_site(I) S;
00244         enum { dim = S::dim };
00245 
00246         window2d win_left, win_right;
00247 
00248         mln_qixter(const I, window2d) q_l, q_r;
00249 
00250         diagonal_fastest_functor(const I& input, const W& win, const A& a)
00251           : input(input),
00252             win(win),
00253             accu(a),
00254             win_left(win::shift(win, dpsite(1, -1)) - win),
00255             win_right(win - win::shift(win, dpsite(1, -1))),
00256             q_l(input, win_left, p),
00257             q_r(input, win_right, p)
00258         {
00259         }
00260 
00261         void init()
00262         {
00263           initialize(output, input);
00264         }
00265 
00266         void next()
00267         {
00268           for_all(q_l)
00269             accu.untake(q_l.val());
00270           for_all(q_r)
00271             accu.take(q_r.val());
00272           output(p) = accu;
00273         }
00274 
00275 
00276         void init_diag()
00277         {
00278           accu.init();
00279           p = p - dpsite(-1, 1);
00280           mln_qixter(const I, W) q(input, win, p);
00281           for_all(q)
00282             accu.take(q.val());
00283           p = p + dpsite(-1, 1);
00284         }
00285 
00286         void final()
00287         {
00288         }
00289 
00290       };
00291 
00292 
00293       template <typename I_, typename W, typename A>
00294       struct backdiagonal_fastest_functor
00295       {
00296         typedef I_ I;
00297         typedef mln_deduce(I, psite, delta) dpsite;
00298 
00299         const I& input;
00300         const W& win;
00301         mln_ch_value(I, mln_result(A)) output;
00302         A accu;
00303 
00304         mln_psite(I) p;
00305         typedef mln_site(I) S;
00306         enum { dim = S::dim };
00307 
00308         window2d win_left, win_right;
00309 
00310         mln_qixter(const I, window2d) q_l, q_r;
00311 
00312         backdiagonal_fastest_functor(const I& input, const W& win, const A& a)
00313           : input(input),
00314             win(win),
00315             accu(a),
00316             win_left(win::shift(win, dpsite(-1, -1)) - win),
00317             win_right(win - win::shift(win, dpsite(-1, -1))),
00318             q_l(input, win_left, p),
00319             q_r(input, win_right, p)
00320         {
00321         }
00322 
00323         void init()
00324         {
00325           initialize(output, input);
00326         }
00327 
00328         void next()
00329         {
00330           for_all(q_l)
00331             accu.untake(q_l.val());
00332           for_all(q_r)
00333             accu.take(q_r.val());
00334           output(p) = accu;
00335         }
00336 
00337 
00338         void init_diag()
00339         {
00340           accu.init();
00341           p = p - dpsite(1, 1);
00342           mln_qixter(const I, W) q(input, win, p);
00343           for_all(q)
00344             accu.take(q.val());
00345           p = p + dpsite(1, 1);
00346         }
00347 
00348         void final()
00349         {
00350         }
00351 
00352       };
00353 
00354 
00355 
00356 
00357       // Both dispatch and implementation (hum...)
00358 
00359       template <typename A, typename I>
00360       inline
00361       mln_ch_value(I, mln_result(A))
00362       transform_diagonal_dispatch(metal::false_,
00363                                   const Accumulator<A>& a,
00364                                   const Image<I>& input, const win::diag2d& win)
00365       {
00366         typedef diagonal_functor<I, win::diag2d, A> F;
00367         F f(exact(input), win, exact(a));
00368         canvas::browsing::diagonal2d(f);
00369         return f.output;
00370       }
00371 
00372       template <typename B, typename A, typename I>
00373       inline
00374       mln_ch_value(I, mln_result(A))
00375       transform_diagonal_dispatch(metal::false_,
00376                                   const Accumulator<A>& a,
00377                                   const Image<I>& input, const win::backdiag2d& win)
00378       {
00379         typedef backdiagonal_functor<I, win::backdiag2d, A> F;
00380         F f(exact(input), win, exact(a));
00381         canvas::browsing::backdiagonal2d(f);
00382         return f.output;
00383       }
00384 
00385       template <typename A, typename I>
00386       inline
00387       mln_ch_value(I, mln_result(A))
00388       transform_diagonal_dispatch(metal::true_,
00389                                   const Accumulator<A>& a,
00390                                   const Image<I>& input, const win::diag2d& win)
00391       {
00392         typedef diagonal_fastest_functor<I, win::diag2d, A> F;
00393         F f(exact(input), win, exact(a));
00394         canvas::browsing::diagonal2d(f);
00395         return f.output;
00396       }
00397 
00398       template <typename A, typename I>
00399       inline
00400       mln_ch_value(I, mln_result(A))
00401       transform_diagonal_dispatch(metal::true_,
00402                                   const Accumulator<A>& a,
00403                                   const Image<I>& input, const win::backdiag2d& win)
00404       {
00405         typedef backdiagonal_fastest_functor<I, win::backdiag2d, A> F;
00406         F f(exact(input), win, exact(a));
00407         canvas::browsing::backdiagonal2d(f);
00408         return f.output;
00409       }
00410 
00411       template <typename A, typename I, typename W>
00412       inline
00413       mln_ch_value(I, mln_result(A))
00414       transform_diagonal_dispatch(const Accumulator<A>& a,
00415                                   const Image<I>& input, const Window<W>& win)
00416       {
00417         return transform_diagonal_dispatch(mln_is_fastest_IW(I, W)(),
00418                                            a, input, exact(win));
00419       }
00420 
00421     } // end of namespace mln::accu::internal
00422 
00423 
00424 
00425 
00426     template <typename A, typename I, typename W>
00427     inline
00428     mln_ch_value(I, mln_result(A))
00429     transform_diagonal(const Accumulator<A>& a,
00430                        const Image<I>& input, const Window<W>& win)
00431     {
00432       trace::entering("accu::transform_diagonal");
00433 
00434       internal::transform_diagonal_tests(input, win);
00435 
00436       extension::adjust(input, geom::delta(win) + 1);
00437       mln_ch_value(I, mln_result(A)) output;
00438       output = internal::transform_diagonal_dispatch(a, input, win);
00439 
00440       trace::exiting("accu::transform_diagonal");
00441       return output;
00442     }
00443 
00444 
00445     template <typename A, typename I, typename W>
00446     inline
00447     mln_ch_value(I, mln_meta_accu_result(A, mln_value(I)))
00448     transform_diagonal(const Meta_Accumulator<A>& a,
00449                        const Image<I>& input, const Window<W>& win)
00450     {
00451       trace::entering("accu::transform_diagonal");
00452 
00453       internal::transform_diagonal_tests(input, win);
00454 
00455       typedef mln_accu_with(A, mln_value(I)) A_;
00456       A_ a_ = accu::unmeta(exact(a), mln_value(I)());
00457 
00458       extension::adjust(input, geom::delta(win) + 1);
00459       mln_ch_value(I, mln_result(A_)) output;
00460       output = internal::transform_diagonal_dispatch(a_, input, win);
00461 
00462       trace::exiting("accu::transform_diagonal");
00463       return output;
00464     }
00465 
00466 
00467 # endif // ! MLN_INCLUDE_ONLY
00468 
00469   } // end of namespace mln::accu
00470 
00471 } // end of namespace mln
00472 
00473 
00474 #endif // ! MLN_ACCU_TRANSFORM_DIAGONAL_HH

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