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

transform_line.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_LINE_HH
00028 # define MLN_ACCU_TRANSFORM_LINE_HH
00029 
00038 
00039 # include <mln/core/concept/image.hh>
00040 # include <mln/core/concept/meta_accumulator.hh>
00041 # include <mln/extension/adjust.hh>
00042 
00043 
00044 
00045 namespace mln
00046 {
00047 
00048   namespace accu
00049   {
00050 
00051 
00052     template <typename A, typename I>
00053     mln_ch_value(I, mln_result(A))
00054     transform_line(const Accumulator<A>& a,
00055                    const Image<I>& input,
00056                    unsigned length, unsigned dir);
00057 
00058     template <typename A, typename I>
00059     mln_ch_value(I, mln_meta_accu_result(A, mln_value(I)))
00060     transform_line(const Meta_Accumulator<A>& a,
00061                    const Image<I>& input,
00062                    unsigned length, unsigned dir);
00063 
00064 
00065 
00066 # ifndef MLN_INCLUDE_ONLY
00067 
00068 
00069     // Tests.
00070 
00071 
00072     namespace internal
00073     {
00074 
00075       template <typename A, typename I>
00076       void transform_line_tests(const Accumulator<A>& a_, const Image<I>& input_)
00077       {
00078         A a = exact(a_);
00079         const I& input = exact(input_);
00080 
00081         mln_precondition(input.is_valid());
00082         mln_psite(I)* p;
00083         mln_precondition(sizeof(a.take(input(*p)), 0) == sizeof(int));
00084 
00085         (void) p;
00086         (void) a;
00087         (void) input;
00088       }
00089 
00090     } // end of namespace mln::accu::internal
00091 
00092 
00093 
00094     // Implementations.
00095 
00096 
00097     namespace impl
00098     {
00099 
00100       namespace generic
00101       {
00102 
00103         template <typename A, typename I>
00104         inline
00105         mln_ch_value(I, mln_result(A))
00106         transform_line(const Accumulator<A>& a_,
00107                        const Image<I>& input_,
00108                        unsigned length, unsigned dir)
00109         {
00110           trace::entering("accu::impl::transform_line");
00111 
00112           const I& input = exact(input_);
00113           A a = exact(a_);
00114 
00115           internal::transform_line_tests(a, input);
00116 
00117           mln_ch_value(I, mln_result(A)) output;
00118           initialize(output, input);
00119 
00120           typedef mln_psite(I) P;
00121           const P
00122             pmin = input.domain().pmin(),
00123             pmax = input.domain().pmax();
00124           const def::coord
00125             pmax_dir = pmax[dir],
00126             pmin_dir = pmin[dir];
00127 
00128           P p = pmin, // Starting point.
00129             qt, qu;
00130           def::coord& p_dir  = p [dir];
00131           def::coord& qt_dir = qt[dir];
00132           def::coord& qu_dir = qu[dir];
00133 
00134           do
00135             {
00136 
00137               // Start the line.
00138               // ---------------
00139 
00140               qt = p;
00141               qt_dir = p_dir - length / 2;
00142               qu = qt;
00143               a.init();
00144 
00145               for (unsigned i = 0; i < length; ++i)
00146                 {
00147                   if (input.has(qt))
00148                     a.take(input(qt));
00149                   qt_dir++;
00150                 }
00151               if (input.has(p))
00152                 output(p) = a.to_result();
00153 
00154               // Browse the line.
00155               // ----------------
00156 
00157               while (p_dir < pmax_dir)
00158                 {
00159                   ++p_dir;
00160                   if (input.has(qt))
00161                     a.take(input(qt));
00162                   if (input.has(qu))
00163                     a.untake(input(qu));
00164                   if (input.has(p))
00165                     output(p) = a.to_result();
00166                   qt_dir++;
00167                   qu_dir++;
00168                 }
00169 
00170               p_dir = pmin_dir;
00171 
00172 
00173               // Go to the next line.
00174               // --------------------
00175 
00176               for (int c = P::dim - 1; c >= 0; --c)
00177                 {
00178                   if (c == int(dir))
00179                     continue;
00180                   if (p[c] != pmax[c])
00181                     {
00182                       ++p[c];
00183                       break;
00184                     }
00185                   p[c] = pmin[c];
00186                 }
00187 
00188             } while (p != pmin);
00189 
00190           trace::exiting("accu::impl::transform_line");
00191           return output;
00192         }
00193 
00194       } // end of namespace mln::accu::impl::generic
00195 
00196 
00197 
00198       template <typename A, typename I>
00199       inline
00200       mln_ch_value(I, mln_result(A))
00201       transform_line_fastest(const Accumulator<A>& a_,
00202                              const Image<I>& input_,
00203                              unsigned length, unsigned dir)
00204       {
00205         trace::entering("accu::impl::transform_line_fastest");
00206 
00207         const I& input = exact(input_);
00208         A a = exact(a_);
00209 
00210         internal::transform_line_tests(a, input);
00211 
00212         mln_ch_value(I, mln_result(A)) output;
00213         initialize(output, input);
00214 
00215         typedef mln_psite(I) P;
00216 
00217         mln_delta(P) dp(literal::zero);
00218         dp[dir] = 1;
00219         int step = input.delta_index(dp);
00220 
00221         P pmin = input.domain().pmin(),
00222           pmax = input.domain().pmax();
00223         const def::coord
00224           pmax_dir = pmax[dir],
00225           pmin_dir = pmin[dir];
00226 
00227         P p = pmin; // Starting point.
00228         def::coord& p_dir = p[dir];
00229 
00230         do
00231           {
00232             unsigned o_qu, o_qt;
00233             unsigned o_p = input.index_of_point(p);
00234 
00235             // Start the line.
00236             // ----------------
00237 
00238             a.take_as_init(input.element(o_p));
00239             o_qu = o_p;
00240             for (unsigned i = 1; i <= length / 2; ++i)
00241               {
00242                 o_qu -= step;
00243                 a.take(input.element(o_qu));
00244               }
00245             o_qt = o_p;
00246             for (unsigned i = 1; i <= length / 2; ++i)
00247               {
00248                 o_qt += step;
00249                 a.take(input.element(o_qt));
00250               }
00251             output.element(o_p) = a.to_result();
00252 
00253             // Browse the line.
00254             // ----------------
00255 
00256             while (p_dir < pmax_dir)
00257               {
00258                 ++p_dir;
00259 
00260                 o_p  += step;
00261                 o_qt += step;
00262                 o_qu += step;
00263 
00264                 a.take(input.element(o_qt));
00265                 a.untake(input.element(o_qu));
00266 
00267                 output.element(o_p) = a.to_result();
00268               }
00269 
00270             p_dir = pmin_dir;
00271 
00272             // Go to the next line.
00273             // --------------------
00274 
00275             for (int c = P::dim - 1; c >= 0; --c)
00276               {
00277                 if (c == int(dir))
00278                   continue;
00279                 if (p[c] != pmax[c])
00280                   {
00281                     ++p[c];
00282                     break;
00283                   }
00284                 p[c] = pmin[c];
00285               }
00286 
00287           } while (p != pmin);
00288 
00289         trace::exiting("accu::impl::transform_line_fastest");
00290         return output;
00291       }
00292 
00293 
00294     } // end of namespace mln::accu::impl
00295 
00296 
00297 
00298 
00299     // Dispatch.
00300 
00301 
00302     namespace internal
00303     {
00304 
00305       template <typename A, typename I>
00306       inline
00307       mln_ch_value(I, mln_result(A))
00308       transform_line_dispatch(trait::image::speed::any,
00309                               const Accumulator<A>& a,
00310                               const Image<I>& input,
00311                               unsigned length, unsigned dir)
00312       {
00313         return impl::generic::transform_line(a,
00314                                              input,
00315                                              length, dir);
00316       }
00317 
00318 //       template <typename A, typename I>
00319 //       inline
00320 //       mln_ch_value(I, mln_result(A))
00321 //      transform_line_dispatch(trait::image::speed::fastest,
00322 //                              const Accumulator<A>& a,
00323 //                              const Image<I>& input,
00324 //                              unsigned length, unsigned dir)
00325 //       {
00326 //      return impl::transform_line_fastest(a,
00327 //                                          input,
00328 //                                          length, dir);
00329 //       }
00330 
00331 
00332     } // end of namespace mln::accu::internal
00333 
00334 
00335 
00336 
00337     // Facades.
00338 
00339 
00340     template <typename A, typename I>
00341     inline
00342     mln_ch_value(I, mln_result(A))
00343     transform_line(const Accumulator<A>& a,
00344                    const Image<I>& input,
00345                    unsigned length, unsigned dir)
00346     {
00347       trace::entering("accu::transform_line");
00348 
00349       internal::transform_line_tests(a, input);
00350 
00351       extension::adjust(input, length / 2);
00352       mln_ch_value(I, mln_result(A)) output;
00353       output = internal::transform_line_dispatch(mln_trait_image_speed(I)(),
00354                                                  a, input, length, dir);
00355 
00356       trace::exiting("accu::transform_line");
00357       return output;
00358     }
00359 
00360 
00361     template <typename A, typename I>
00362     inline
00363     mln_ch_value(I, mln_meta_accu_result(A, mln_value(I)))
00364     transform_line(const Meta_Accumulator<A>& a,
00365                    const Image<I>& input,
00366                    unsigned length, unsigned dir)
00367     {
00368       trace::entering("accu::transform_line");
00369 
00370       typedef mln_accu_with(A, mln_value(I)) A_;
00371       A_ a_ = accu::unmeta(exact(a), mln_value(I)());
00372 
00373       internal::transform_line_tests(a_, input);
00374 
00375       extension::adjust(input, length / 2);
00376       mln_ch_value(I, mln_result(A_)) output;
00377       output = impl::generic::transform_line(a_, input, length, dir);
00378 
00379       trace::exiting("accu::transform_line");
00380       return output;
00381     }
00382 
00383 
00384 # endif // ! MLN_INCLUDE_ONLY
00385 
00386   } // end of namespace mln::accu
00387 
00388 } // end of namespace mln
00389 
00390 
00391 #endif // ! MLN_ACCU_TRANSFORM_LINE_HH

Generated on Thu Sep 8 2011 18:32:42 for Milena (Olena) by  doxygen 1.7.1