Milena (Olena)
User documentation 2.0a Id
|
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