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

duplicate.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_BORDER_DUPLICATE_HH
00027 # define MLN_BORDER_DUPLICATE_HH
00028 
00032 
00033 # include <mln/core/concept/image.hh>
00034 # include <mln/core/routine/primary.hh>
00035 # include <mln/core/box_runstart_piter.hh>
00036 # include <mln/border/get.hh>
00037 # include <mln/opt/element.hh>
00038 
00039 
00040 namespace mln
00041 {
00042 
00043   namespace border
00044   {
00045 
00055     template <typename I>
00056     void duplicate(const Image<I>& ima);
00057 
00058 
00059 # ifndef MLN_INCLUDE_ONLY
00060 
00061     namespace impl
00062     {
00063 
00064       template <typename I>
00065       inline
00066       void duplicate_1D(I& ima)
00067       {
00068         trace::entering("border::impl::duplicate_1D");
00069 
00070         typedef mln_psite(I) P;
00071         mln_box_runstart_piter(I) pl(ima.domain());
00072         unsigned len_c = ima.bbox().len(P::dim - 1);
00073         unsigned border = ima.border();
00074 
00075         for (unsigned i = 0; i < border; ++i)
00076           opt::element(ima, i) = opt::element(ima, border);
00077 
00078         unsigned st = border + len_c - 1;
00079         for (unsigned i = st + 1; i < opt::nelements(ima); ++i)
00080           opt::element(ima, i) = opt::element(ima, st);
00081 
00082         trace::exiting("border::impl::duplicate_1D");
00083       }
00084 
00085       template <typename I>
00086       inline
00087       void duplicate_2D(I& ima)
00088       {
00089         trace::entering("border::impl::duplicate_2D");
00090 
00091         typedef mln_psite(I) P;
00092         mln_box_runstart_piter(I) pl(ima.domain());
00093         unsigned border = ima.border();
00094         unsigned border_2x = 2 * ima.border();
00095         unsigned len_c = ima.bbox().len(1);
00096         unsigned len_r = ima.bbox().len(0);
00097         unsigned real_len_c = len_c + border_2x;
00098         unsigned st;
00099 
00100         // Duplicate
00101         for_all (pl)
00102           {
00103             st = ima.index_of_point (pl);
00104             for (unsigned i = 1; i <= border; ++i)
00105               opt::element(ima, st - i) = opt::element(ima, st);
00106             st = st + len_c - 1;
00107             for (unsigned i = 1; i <= border; ++i)
00108               opt::element(ima, st + i) = opt::element(ima, st);
00109           }
00110 
00111         // Duplicate n first * border line
00112         st = real_len_c * border;
00113         for (unsigned k = 0; k < border; ++k)
00114           for (unsigned i = 0; i < real_len_c; ++i)
00115             opt::element(ima, k * real_len_c + i) = opt::element(ima, st + i);
00116 
00117         // Duplicate n last * border line
00118         st = real_len_c * (border + len_r - 1);
00119         for (unsigned k = 1; k <= border; ++k)
00120           for (unsigned i = st; i < st + real_len_c; ++i)
00121             opt::element(ima, k * real_len_c + i) = opt::element(ima, i);
00122 
00123         trace::exiting("border::impl::duplicate_2D");
00124       }
00125 
00126       template <typename I>
00127       inline
00128       void duplicate_3D(I& ima)
00129       {
00130         trace::entering("border::impl::duplicate_3D");
00131 
00132         mln_precondition(ima.is_valid());
00133 
00134         typedef mln_psite(I) P;
00135         mln_box_runstart_piter(I) pl(ima.domain());
00136         unsigned border = ima.border();
00137         unsigned border_2x = 2 * ima.border();
00138         unsigned len_c = ima.bbox().len(P::dim - 1);
00139         unsigned len_r = ima.bbox().len(1);
00140         unsigned len_s = ima.bbox().len(0);
00141         unsigned real_len_c = len_c + border_2x;
00142         unsigned real_len_r = len_r + border_2x;
00143         unsigned face = real_len_c * real_len_r;
00144         unsigned st;
00145 
00146         pl.start();
00147 
00148         for (unsigned k = 0; k < len_s; ++k)
00149           {
00150 
00151             // Duplicate
00152             for (unsigned j = 0; j < len_r; ++j)
00153               {
00154                 st = ima.index_of_point (pl);
00155                 for (unsigned i = 1; i <= border; ++i)
00156                   opt::element(ima, st - i) = opt::element(ima, st);
00157                 st = st + len_c - 1;
00158                 for (unsigned i = 1; i <= border; ++i)
00159                   opt::element(ima, st + i) = opt::element(ima, st);
00160                 pl.next();
00161               }
00162 
00163             // Duplicate n last * border line
00164             st = border * face + k * face + border * real_len_c ;
00165             for (unsigned j = 1; j <= border; ++j)
00166               for (unsigned i = 0; i < real_len_c; ++i)
00167                 opt::element(ima, st - j * real_len_c + i) =
00168                   opt::element(ima, st + i);
00169 
00170             // Duplicate n last * border line
00171             st = border * face + k * face + (len_r + border - 1) * real_len_c ;
00172             for (unsigned j = 1; j <= border; ++j)
00173               for (unsigned i = 0; i < real_len_c; ++i)
00174                 opt::element(ima, st + j * real_len_c + i) =
00175                   opt::element(ima, st + i);
00176           }
00177 
00178         // Duplicate n first * border face
00179         st = border * face;
00180         for (unsigned k = 0; k < border; ++k)
00181           for (unsigned i = 0; i < face; ++i)
00182             opt::element(ima, k * face + i) = opt::element(ima, st + i);
00183 
00184         // Duplicate n last * border face
00185         st = (len_s + border - 1) * face;
00186         for (unsigned k = 1; k <= border; ++k)
00187           for (unsigned i = 0; i < face; ++i)
00188             opt::element(ima, st + k * face + i) = opt::element(ima, st + i);
00189 
00190         trace::exiting("border::impl::duplicate_3D");
00191       }
00192 
00193     } // end of namespace mln::border::impl
00194 
00195 
00196     namespace internal
00197     {
00198 
00199       template <typename I>
00200       void duplicate_dispatch_on(metal::int_<1>, I& ima)
00201       {
00202         impl::duplicate_1D(ima);
00203       }
00204 
00205       template <typename I>
00206       void duplicate_dispatch_on(metal::int_<2>, I& ima)
00207       {
00208         impl::duplicate_2D(ima);
00209       }
00210 
00211       template <typename I>
00212       void duplicate_dispatch_on(metal::int_<3>, I& ima)
00213       {
00214         impl::duplicate_3D(ima);
00215       }
00216 
00217       template <typename I>
00218       void duplicate_dispatch_on(trait::image::speed::fastest,
00219                                  const Image<I>& ima)
00220       {
00221         typedef mln_site(I) P;
00222         duplicate_dispatch_on(metal::int_<P::dim>(),
00223                               const_cast<I&>(exact(ima)));
00224       }
00225 
00226       template <typename I>
00227       void duplicate_dispatch_on(trait::image::speed::any,
00228                                  const Image<I>& ima)
00229       {
00230         // No-op.
00231       }
00232 
00233       template <typename I>
00234       void duplicate_dispatch_on(const Image<I>& ima)
00235       {
00236         duplicate_dispatch_on(mln_trait_image_speed(I)(),
00237                               ima);
00238       }
00239 
00240       template <typename I>
00241       void duplicate_dispatch(const Image<I>& ima)
00242       {
00243         duplicate_dispatch_on(primary(ima));
00244       }
00245 
00246     } // end of namespace mln::border::internal
00247 
00248 
00249     // Facade.
00250 
00251     template <typename I>
00252     void duplicate(const Image<I>& ima)
00253     {
00254       trace::entering("border::duplicate");
00255       mln_precondition(exact(ima).is_valid());
00256 
00257       if (border::get(ima) != 0)
00258         internal::duplicate_dispatch(ima);
00259 
00260       trace::exiting("border::duplicate");
00261     }
00262 
00263 
00264 # endif // ! MLN_INCLUDE_ONLY
00265 
00266   } // end of namespace mln::border
00267 
00268 } // end of namespace mln
00269 
00270 
00271 #endif // ! MLN_BORDER_DUPLICATE_HH

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