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