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

line.hh

00001 // Copyright (C) 2007, 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_LINE_HH
00027 # define MLN_ACCU_LINE_HH
00028 
00034 
00035 # include <mln/core/concept/meta_accumulator.hh>
00036 # include <mln/core/concept/image.hh>
00037 
00038 
00039 
00040 namespace mln
00041 {
00042 
00043   namespace accu
00044   {
00045 
00046     // FIXME:
00047 
00062     template <typename Meta_Accu, unsigned Dir, // Free parameters.
00063               typename I, typename O>
00064     void
00065     line(const Image<I>& input,
00066          const mln_site(I)& p_start, unsigned len,
00067          unsigned half_length,
00068          Image<O>& output);
00069 
00070 
00071 
00072 # ifndef MLN_INCLUDE_ONLY
00073 
00074     namespace internal
00075     {
00076 
00077       template <typename Meta_Accu, unsigned Dir, // Free parameters.
00078                 typename I, typename O>
00079       void
00080       line_tests(const Image<I>& input_,
00081                  const mln_site(I)&, unsigned,
00082                  unsigned,
00083                  Image<O>& output_)
00084       {
00085         mlc_is_a(Meta_Accu, Meta_Accumulator)::check();
00086 
00087         typedef mln_accu_with(Meta_Accu, mln_value(I)) A;
00088         mlc_converts_to(mln_result(A), mln_value(O))::check();
00089 
00090         typedef mln_site(I) P;
00091         mlc_bool(Dir < P::dim)::check();
00092 
00093         mlc_is(mln_trait_image_value_io(O),
00094                mln::trait::image::value_io::read_write)::check();
00095 
00096         const I& input = exact(input_);
00097         O& output = exact(output_);
00098         mln_precondition(input.is_valid());
00099         mln_precondition(output.is_valid());
00100       }
00101       
00102     } // end of namespace mln::accu::internal
00103 
00104 
00105     namespace impl
00106     {
00107 
00108       namespace generic
00109       {
00110         
00111         template <typename Meta_Accu, unsigned Dir,
00112                   typename I, typename O>
00113         void
00114         line(const Image<I>& input_,
00115              const mln_site(I)& p_start, unsigned len_,
00116              unsigned half_length_,
00117              Image<O>& output_)
00118         {
00119           typedef mln_site(I) P;
00120           typedef mln_accu_with(Meta_Accu, mln_value(I)) A;
00121 
00122           const I& input = exact(input_);
00123           O& output = exact(output_);
00124 
00125           // Avoid warning in signed/unsigned comparison.
00126           const def::coord len = static_cast<def::coord>(len_);
00127           const def::coord half_length = static_cast<def::coord>(half_length_);
00128 
00129           // Checks and tests.
00130           internal::line_tests<Meta_Accu, Dir>(input,
00131                                                p_start, len,
00132                                                half_length,
00133                                                output);
00134 
00135           // Initialization.
00136           const def::coord start = p_start[Dir];
00137           const def::coord last = static_cast<def::coord>(start + len - 1);
00138           A a; // Accumulator.
00139           a.init();
00140           P p; // Current point.
00141 
00142           // Start (first line point).
00143           p = p_start;
00144           P q = p;
00145           for (def::coord c = 0; c <= half_length && c < len; ++c)
00146             {
00147               a.take(input(q));
00148               ++q[Dir];
00149             }
00150           output(p) = a;
00151 
00152           def::coord& cur = p[Dir];
00153           if (cur == last)
00154             return;
00155 
00156           // Begin of line.
00157 
00158           P p_plus = p_start;
00159           def::coord& plus = p_plus[Dir];
00160           plus = static_cast<def::coord>(plus + half_length);
00161 
00162           while (cur < start + half_length && cur < last)
00163             {
00164               ++cur;
00165               ++plus;
00166               if (plus <= last)
00167                 a.take(input(p_plus));
00168               output(p) = a;
00169             }
00170 
00171           if (cur == last)
00172             return;
00173 
00174           // Middle of line.
00175 
00176           P p_minus = p_start;
00177           def::coord& minus = p_minus[Dir];
00178           --minus;
00179 
00180           while (cur < last - half_length)
00181             {
00182               ++cur;
00183               ++plus;
00184               ++minus;
00185               mln_invariant(plus >= start && plus <= last);
00186               a.take(input(p_plus));
00187               mln_invariant(minus >= start && minus <= last);
00188               a.untake(input(p_minus));
00189               output(p) = a;
00190             }
00191 
00192           if (cur == last)
00193             return;
00194 
00195           // End of line.
00196 
00197           while (cur < last)
00198             {
00199               ++cur;
00200               ++minus;
00201               mln_invariant(minus >= start && minus <= last);
00202               a.untake(input(p_minus));
00203               output(p) = a;
00204             }
00205         }
00206 
00207       } // end of namespace mln::accu::impl::generic
00208 
00209 
00210 
00211       template <typename Meta_Accu, unsigned Dir,
00212                 typename I, typename O>
00213       void
00214       line_fastest(const Image<I>& input_,
00215                    const mln_site(I)& p_start, unsigned len,
00216                    unsigned half_length,
00217                    Image<O>& output_)
00218       {
00219         typedef mln_site(I)  P;
00220         typedef mln_value(I) V;
00221         typedef mln_accu_with(Meta_Accu, V) A;
00222 
00223         const I& input = exact(input_);
00224         O& output = exact(output_);
00225 
00226         // Checks and tests.
00227         internal::line_tests<Meta_Accu, Dir>(input,
00228                                              p_start, len,
00229                                              half_length,
00230                                              output);
00231 
00232         // Initialization.
00233 
00234         const def::coord start = p_start[Dir];
00235         const def::coord last = start + len - 1;
00236 
00237         const V* p_in    = & input(p_start);
00238         V* p_out   = & output(p_start);
00239 
00240         mln_delta(P) dp = literal::zero;
00241         dp[Dir] = 1;
00242         unsigned offset = input.delta_index(dp);
00243 
00244         A a; // Accumulator.
00245         a.init();
00246 
00247         // Start (first line point).
00248 
00249         const V* q = p_in;
00250         for (def::coord c = 0; c <= half_length && c < len; ++c)
00251           {
00252             a.take(*q);
00253             q += offset;
00254           }
00255         *p_out = a;
00256 
00257         def::coord cur = p_start[Dir];
00258         if (cur == last)
00259           return;
00260 
00261         // Begin of line.
00262 
00263         def::coord plus = start + half_length;
00264         const V* p_plus = p_in + half_length * offset;
00265 
00266         while (cur < start + half_length && cur < last)
00267           {
00268             ++cur;
00269             p_in += offset;
00270             ++plus;
00271             p_plus += offset;
00272             if (plus <= last)
00273               a.take(*p_plus);
00274             p_out += offset;
00275             *p_out = a;
00276           }
00277 
00278         if (cur == last)
00279           return;
00280 
00281         // Middle of line.
00282 
00283         def::coord minus = start - 1;
00284         const V* p_minus = p_in - offset;
00285 
00286         while (cur < last - half_length)
00287           {
00288             ++cur;
00289             p_in += offset;
00290             ++plus;
00291             p_plus += offset;
00292             ++minus;
00293             p_minus += offset;
00294             mln_invariant(plus >= start && plus <= last);
00295             a.take(*p_plus);
00296             mln_invariant(minus >= start && minus <= last);
00297             a.untake(*p_minus);
00298             p_out += offset;
00299             *p_out = a;
00300           }
00301 
00302         if (cur == last)
00303           return;
00304 
00305         // End of line.
00306 
00307         while (cur < last)
00308           {
00309             ++cur;
00310             p_in += offset;
00311             ++minus;
00312             p_minus += offset;
00313             mln_invariant(minus >= start && minus <= last);
00314             a.untake(*p_minus);
00315             p_out += offset;
00316             *p_out = a;
00317           }
00318 
00319       }
00320 
00321 
00322 
00323 
00324     } // end of namespace mln::accu::impl
00325 
00326 
00327     namespace internal
00328     {
00329 
00330       template <typename Meta_Accu, unsigned Dir, // Free parameters.
00331                 typename I, typename O>
00332       void
00333       line_dispatch(trait::image::speed::any,
00334                     const Image<I>& input,
00335                     const mln_site(I)& p_start, unsigned len,
00336                     unsigned half_length,
00337                     Image<O>& output)
00338       {
00339         impl::generic::line<Meta_Accu, Dir>(input,
00340                                             p_start, len,
00341                                             half_length,
00342                                             output);
00343       }
00344 
00345 //       template <typename Meta_Accu, unsigned Dir, // Free parameters.
00346 //              typename I, typename O>
00347 //       void
00348 //       line_dispatch(trait::image::speed::fastest,
00349 //                  const Image<I>& input,
00350 //                  const mln_site(I)& p_start, unsigned len,
00351 //                  unsigned half_length,
00352 //                  Image<O>& output)
00353 //       {
00354 //      impl::line_fastest<Meta_Accu, Dir>(input,
00355 //                                         p_start, len,
00356 //                                         half_length,
00357 //                                         output);
00358 //       }
00359 
00360       template <typename Meta_Accu, unsigned Dir, // Free parameters.
00361                 typename I, typename O>
00362       void
00363       line_dispatch(const Image<I>& input,
00364                     const mln_site(I)& p_start, unsigned len,
00365                     unsigned half_length,
00366                     Image<O>& output)
00367       {
00368         line_dispatch<Meta_Accu, Dir>(mln_trait_image_speed(I)(),
00369                                       input,
00370                                       p_start, len,
00371                                       half_length,
00372                                       output);
00373       }
00374       
00375     } // end of namespace mln::accu::internal
00376 
00377 
00378     template <typename Meta_Accu, unsigned Dir, // Free parameters.
00379               typename I, typename O>
00380     void
00381     line(const Image<I>& input,
00382          const mln_site(I)& p_start, unsigned len,
00383          unsigned half_length,
00384          Image<O>& output)
00385     {
00386       internal::line_tests<Meta_Accu, Dir>(input,
00387                                            p_start, len,
00388                                            half_length,
00389                                            output);
00390       internal::line_dispatch<Meta_Accu, Dir>(input,
00391                                               p_start, len,
00392                                               half_length,
00393                                               output);
00394     }
00395 
00396 # endif // ! MLN_INCLUDE_ONLY
00397 
00398   } // end of namespace mln::accu
00399 
00400 } // end of namespace mln
00401 
00402 
00403 #endif // ! MLN_ACCU_LINE_HH

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