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