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

fill.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_FILL_HH
00027 # define MLN_BORDER_FILL_HH
00028 
00034 # include <cstring>
00035 
00036 # include <mln/core/concept/image.hh>
00037 # include <mln/core/box_runstart_piter.hh>
00038 # include <mln/opt/element.hh>
00039 
00040 
00041 namespace mln
00042 {
00043 
00044   namespace border
00045   {
00046 
00057     template <typename I>
00058     void fill(const Image<I>& ima, const mln_value(I)& v);
00059 
00060 
00061 # ifndef MLN_INCLUDE_ONLY
00062 
00063 
00064     namespace internal
00065     {
00066 
00067       template <typename I>
00068       inline
00069       void fill_tests(const Image<I>& ima, const mln_value(I)&)
00070       {
00071         mln_precondition(exact(ima).is_valid());
00072         (void) ima;
00073       }
00074 
00075     } // end of namespace mln::border::internal
00076 
00077 
00078     namespace impl
00079     {
00080 
00081       template <typename I>
00082       inline
00083       void fill_size_1(const Image<I>& ima_, const mln_value(I)& v)
00084       {
00085         trace::entering("border::impl::fill_size_1");
00086 
00087         const I& ima = exact(ima_);
00088         internal::fill_tests(ima, v);
00089 
00090         typedef mln_psite(I) P;
00091         typedef mln_psite(I) P;
00092         mln_box_runstart_piter(I) pl(ima.domain());
00093 
00094         unsigned len_r = pl.run_length();
00095         unsigned st = 0;
00096 
00097         for_all (pl)
00098           {
00099             unsigned end = ima.index_of_point (pl);
00100             std::memset((void*)&opt::element(ima, st),
00101                         *(const int*)(&v),
00102                         end - st);
00103             st = end + len_r;
00104           }
00105         std::memset((void*)&opt::element(ima, st),
00106                     *(const int*)(&v),
00107                     opt::nelements(ima) - st);
00108 
00109         trace::exiting("border::impl::fill_size_1");
00110       }
00111 
00112 
00113       template <typename I>
00114       inline
00115       void fill_size_n(const I& ima_, const mln_value(I)& v)
00116       {
00117         trace::entering("border::impl::fill_size_n");
00118 
00119         I& ima = const_cast<I&>( exact(ima_) );
00120         internal::fill_tests(ima, v);
00121 
00122         typedef mln_psite(I) P;
00123         mln_box_runstart_piter(I) pl(ima.domain());
00124         unsigned len_r = pl.run_length();
00125         unsigned st = 0;
00126 
00127         for_all (pl)
00128           {
00129             unsigned end = ima.index_of_point (pl);
00130             for (unsigned i = st; i < end; ++i)
00131               opt::element(ima, i) = v;
00132             st = end + len_r;
00133           }
00134         for (unsigned i = st; i < opt::nelements(ima); ++i)
00135           opt::element(ima, i) = v;
00136 
00137         trace::exiting("border::impl::fill_size_n");
00138       }
00139 
00140 
00141     } // end of namespace mln::border::impl
00142 
00143 
00144     namespace internal
00145     {
00146 
00147       // Dispatch.
00148 
00149       template <typename I>
00150       inline
00151       void fill_dispatch(const Image<I>& ima, const mln_value(I)& v);
00152 
00153       template <typename I>
00154       inline
00155       void fill_dispatch(mln::trait::image::category::primary,
00156                          mln::trait::image::speed::fastest,
00157                          I& ima, const mln_value(I)& v)
00158       {
00159         if (sizeof(mln_value(I)) == 1)
00160           impl::fill_size_1(ima, v);
00161         else
00162           impl::fill_size_n(ima, v);
00163       }
00164 
00165       template <typename I>
00166       inline
00167       void fill_dispatch(mln::trait::image::category::primary,
00168                          mln::trait::image::speed::any,
00169                          I& /* ima */, const mln_value(I)& /* v */)
00170       {
00171         // No border so no-op.
00172       }
00173 
00174       template <typename I>
00175       inline
00176       void fill_dispatch(mln::trait::image::category::morpher,
00177                          mln::trait::image::speed::any,
00178                          I& ima, const mln_value(I)& v)
00179       {
00180         fill_dispatch(ima.unmorph_(), v);
00181       }
00182 
00183       template <typename I>
00184       inline
00185       void fill_dispatch(const Image<I>& ima_, const mln_value(I)& v)
00186       {
00187         I& ima = const_cast<I&>(exact(ima_));
00188         fill_dispatch(mln_trait_image_category(I)(),
00189                       mln_trait_image_speed(I)(),
00190                       ima, v);
00191       }
00192 
00193     } // end of namespace mln::border::internal
00194 
00195 
00196 
00197     // Facade.
00198 
00199     template <typename I>
00200     inline
00201     void fill(const Image<I>& ima, const mln_value(I)& v)
00202     {
00203       trace::entering("border::fill");
00204 
00205       internal::fill_tests(ima, v);
00206       internal::fill_dispatch(ima, v);
00207 
00208       trace::exiting("border::fill");
00209     }
00210 
00211 
00212 # endif // ! MLN_INCLUDE_ONLY
00213 
00214   } // end of namespace mln::border
00215 
00216 } // end of namespace mln
00217 
00218 
00219 #endif // ! MLN_BORDER_FILL_HH

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