Milena (Olena)
User documentation 2.0a Id
|
00001 // Copyright (C) 2009, 2010 EPITA Research and Development Laboratory 00002 // (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_SUBSAMPLING_ANTIALIASED_HH 00028 # define MLN_SUBSAMPLING_ANTIALIASED_HH 00029 00033 00034 00035 #include <mln/core/concept/image.hh> 00036 #include <mln/border/thickness.hh> 00037 #include <mln/extension/adjust_duplicate.hh> 00038 #include <mln/core/macros.hh> 00039 00040 namespace mln 00041 { 00042 00043 namespace subsampling 00044 { 00045 00054 template <typename I> 00055 inline 00056 mln_concrete(I) 00057 antialiased(const Image<I>& input, 00058 unsigned factor, 00059 const mln_domain(I)& output_domain, 00060 unsigned border_thickness); 00061 00062 00065 template <typename I> 00066 mln_concrete(I) 00067 antialiased(const Image<I>& input, unsigned factor); 00068 00069 00070 00071 # ifndef MLN_INCLUDE_ONLY 00072 00073 00074 00075 // Tests 00076 00077 namespace internal 00078 { 00079 00080 template <typename I> 00081 inline 00082 void 00083 antialiased_tests(const Image<I>& input, 00084 unsigned factor, 00085 const mln_domain(I)& output_domain, 00086 unsigned border_thickness) 00087 { 00088 typedef mln_site(I) P; 00089 00090 mlc_is_a(mln_domain(I), Box)::check(); 00091 mln_precondition(exact(input).is_valid()); 00092 mln_precondition(exact(input).domain().pmin() == literal::origin); 00093 00094 (void) input; 00095 (void) factor; 00096 (void) output_domain; 00097 (void) border_thickness; 00098 } 00099 00100 } // end of namespace mln::subsampling::internal 00101 00102 00103 00104 00105 // Implementations. 00106 00107 namespace impl 00108 { 00109 00110 namespace generic 00111 { 00112 00113 template <typename I> 00114 inline 00115 mln_concrete(I) 00116 antialiased(const Image<I>& input_, 00117 unsigned factor, 00118 const mln_domain(I)& output_domain, 00119 unsigned border_thickness) 00120 { 00121 (void) input_; 00122 (void) factor; 00123 (void) output_domain; 00124 (void) border_thickness; 00125 00126 // To be written... 00127 mlc_abort(I)::check(); 00128 00129 mln_concrete(I) output; 00130 return output; 00131 } 00132 00133 } // end of namespace mln::subsampling::impl::generic 00134 00135 00136 00137 template <typename I> 00138 inline 00139 mln_concrete(I) 00140 antialiased_2d_fastest_scalar(const Image<I>& input_, 00141 unsigned factor, 00142 const mln_domain(I)& output_domain, 00143 unsigned border_thickness) 00144 { 00145 trace::entering("subsampling::impl::antialiased_2d_fastest"); 00146 00147 internal::antialiased_tests(input_, factor, 00148 output_domain, border_thickness); 00149 00150 const I& input = exact(input_); 00151 00152 // No reduction. 00153 if (factor == 1) 00154 { 00155 trace::exiting("subsampling::impl::antialiased_2d_fastest"); 00156 return duplicate(input); 00157 } 00158 00159 typedef mln_value(I) V; 00160 typedef mln_sum(V) S; 00161 00162 typedef mln_site(I) P; 00163 box<P> b = output_domain; 00164 if (!b.is_valid()) 00165 { 00166 P pmin = input.domain().pmin() / factor, 00167 pmax = input.domain().pmax() / factor; 00168 b = box<P>(pmin, pmax); 00169 } 00170 typedef mln_concrete(I) O; 00171 O output(b, border_thickness); 00172 00173 // Make sure there is enough data in input border. 00174 unsigned input_border = factor - std::min(input.nrows() % factor, 00175 input.ncols() % factor); 00176 extension::adjust_duplicate(input, input_border); 00177 00178 00179 typedef const V* ptr_t; 00180 00181 util::array<ptr_t> ptrs(factor, 0); 00182 for (unsigned i = 0; i < factor; ++i) 00183 ptrs[i] = & input.at_(i, 0); 00184 00185 mln_box_runstart_piter(O) s(output.domain()); 00186 const unsigned n = s.run_length(); 00187 const unsigned 00188 factor_2 = factor * factor, 00189 factor_round = factor_2 / 2; 00190 unsigned offset = input.delta_index(point2d(factor,0) - point2d(0,factor*n)); 00191 00192 for_all(s) 00193 { 00194 mln_value(O)* po = & output(s); 00195 for (unsigned i = 0; i < n; ++i) 00196 { 00197 mln_sum(V) s = literal::zero; 00198 for (unsigned j = 0; j < factor; ++j) 00199 for (unsigned k = 0; k < factor; ++k) 00200 s += *ptrs[j]++; 00201 00202 convert::from_to((s + factor_round) / factor_2, *po); 00203 ++po; 00204 } 00205 00206 for (unsigned j = 0; j < factor; ++j) 00207 ptrs[j] += offset; 00208 } 00209 00210 trace::exiting("subsampling::impl::antialiased_2d_fastest"); 00211 return output; 00212 } 00213 00214 00215 00216 template <typename I> 00217 inline 00218 mln_concrete(I) 00219 antialiased_2d_fastest_rgb(const Image<I>& input_, 00220 unsigned factor, 00221 const mln_domain(I)& output_domain, 00222 unsigned border_thickness) 00223 { 00224 trace::entering("subsampling::impl::antialiased_2d_rgb"); 00225 00226 internal::antialiased_tests(input_, factor, 00227 output_domain, border_thickness); 00228 00229 const I& input = exact(input_); 00230 00231 00232 // No reduction. 00233 if (factor == 1) 00234 { 00235 trace::exiting("subsampling::impl::antialiased_2d_rgb"); 00236 return duplicate(input); 00237 } 00238 00239 typedef mln_value(I) V; 00240 typedef mln_sum(V) S; 00241 00242 typedef mln_site(I) P; 00243 box<P> b = output_domain; 00244 if (!b.is_valid()) 00245 { 00246 P pmin = input.domain().pmin() / factor, 00247 pmax = input.domain().pmax() / factor; 00248 b = box<P>(pmin, pmax); 00249 } 00250 typedef mln_concrete(I) O; 00251 O output(b, border_thickness); 00252 00253 // Make sure there is enough data in input border. 00254 unsigned input_border = factor - std::min(input.nrows() % factor, 00255 input.ncols() % factor); 00256 extension::adjust_duplicate(input, input_border); 00257 00258 00259 typedef const V* ptr_t; 00260 00261 util::array<ptr_t> ptrs(factor, 0); 00262 for (unsigned i = 0; i < factor; ++i) 00263 ptrs[i] = & input.at_(i, 0); 00264 00265 mln_box_runstart_piter(O) s(output.domain()); 00266 const unsigned n = s.run_length(); 00267 const unsigned 00268 factor_2 = factor * factor, 00269 factor_round = factor_2 / 2; 00270 unsigned offset = input.delta_index(point2d(factor,0) - point2d(0,factor*n)); 00271 00272 for_all(s) 00273 { 00274 mln_value(O)* po = & output(s); 00275 for (unsigned i = 0; i < n; ++i) 00276 { 00277 mln_sum(V) s = literal::zero; 00278 for (unsigned j = 0; j < factor; ++j) 00279 for (unsigned k = 0; k < factor; ++k) 00280 { 00281 algebra::vec<3, float> tmp = *ptrs[j]++; 00282 s += tmp; 00283 } 00284 00285 // FIXME: should be removed and replaced by the 00286 // commented part below. 00287 for (unsigned j = 0; j < P::dim; ++j) 00288 s[j] += factor_round; 00289 00290 *po++ = (s /*+ factor_round*/) / factor_2; 00291 } 00292 for (unsigned j = 0; j < factor; ++j) 00293 ptrs[j] += offset; 00294 } 00295 00296 trace::exiting("subsampling::impl::antialiased_2d_rgb"); 00297 return output; 00298 } 00299 00300 00301 00302 } // end of namespace mln::subsampling::impl 00303 00304 00305 00306 // Dispatch. 00307 00308 namespace internal 00309 { 00310 00311 template <unsigned dim, typename I> 00312 inline 00313 mln_concrete(I) 00314 antialiased_dispatch(trait::image::value_alignment::any, 00315 trait::image::value_storage::any, 00316 trait::image::value_access::any, 00317 const Image<I>& input, 00318 unsigned factor, 00319 const mln_domain(I)& output_domain, 00320 unsigned border_thickness) 00321 { 00322 (void) input; 00323 (void) factor; 00324 (void) output_domain; 00325 (void) border_thickness; 00326 00327 // Not implemented yet. 00328 mlc_abort(I)::check(); 00329 } 00330 00331 template <typename I> 00332 inline 00333 mln_concrete(I) 00334 antialiased_2d_fastest_dispatch(const mln_value(I)&, 00335 const Image<I>& input, 00336 unsigned factor, 00337 const mln_domain(I)& output_domain, 00338 unsigned border_thickness) 00339 { 00340 return impl::antialiased_2d_fastest_scalar(input, factor, 00341 output_domain, 00342 border_thickness); 00343 } 00344 00345 00346 template <unsigned n, typename I> 00347 inline 00348 mln_concrete(I) 00349 antialiased_2d_fastest_dispatch(const value::rgb<n>&, 00350 const Image<I>& input, 00351 unsigned factor, 00352 const mln_domain(I)& output_domain, 00353 unsigned border_thickness) 00354 { 00355 return impl::antialiased_2d_fastest_rgb(input, factor, 00356 output_domain, 00357 border_thickness); 00358 } 00359 00360 00361 template <typename I> 00362 inline 00363 mln_concrete(I) 00364 antialiased_2d_fastest_dispatch(const Image<I>& input, 00365 unsigned factor, 00366 const mln_domain(I)& output_domain, 00367 unsigned border_thickness) 00368 { 00369 typedef mln_value(I) V; 00370 return antialiased_2d_fastest_dispatch(V(), input, factor, 00371 output_domain, 00372 border_thickness); 00373 } 00374 00375 00376 template <typename I> 00377 inline 00378 mln_concrete(I) 00379 antialiased_dispatch_2d(trait::image::value_alignment::with_grid, 00380 trait::image::value_storage::one_block, 00381 trait::image::value_access::direct, 00382 const Image<I>& input, 00383 unsigned factor, 00384 const mln_domain(I)& output_domain, 00385 unsigned border_thickness) 00386 { 00387 return antialiased_2d_fastest_dispatch(input, factor, 00388 output_domain, 00389 border_thickness); 00390 } 00391 00392 00393 template <typename I> 00394 inline 00395 mln_concrete(I) 00396 antialiased_dispatch(const Image<I>& input, 00397 unsigned factor, 00398 const mln_domain(I)& output_domain, 00399 unsigned border_thickness) 00400 { 00401 unsigned dim = mln_site_(I)::dim; 00402 00403 if (dim == 2) 00404 return antialiased_dispatch_2d( 00405 mln_trait_image_value_alignment(I)(), 00406 mln_trait_image_value_storage(I)(), 00407 mln_trait_image_value_access(I)(), 00408 input, 00409 factor, 00410 output_domain, 00411 border_thickness); 00412 else 00413 trace::warning("Not implemented yet."); 00414 00415 mln_concrete(I) output; 00416 return output; 00417 } 00418 00419 } // end of namespace mln::subsampling::internal 00420 00421 00422 00423 // Facades. 00424 00425 template <typename I> 00426 inline 00427 mln_concrete(I) 00428 antialiased(const Image<I>& input, 00429 unsigned factor, 00430 const mln_domain(I)& output_domain, 00431 unsigned border_thickness) 00432 { 00433 trace::entering("subsampling::antialiased"); 00434 00435 typedef mln_site(I) P; 00436 00437 internal::antialiased_tests(input, factor, 00438 output_domain, border_thickness); 00439 00440 mln_concrete(I) 00441 output = internal::antialiased_dispatch(input, factor, 00442 output_domain, 00443 border_thickness); 00444 00445 trace::exiting("subsampling::antialiased"); 00446 return output; 00447 } 00448 00449 00450 template <typename I> 00451 inline 00452 mln_concrete(I) 00453 antialiased(const Image<I>& input, unsigned factor) 00454 { 00455 mln_domain(I) domain; 00456 return antialiased(input, factor, domain, border::thickness); 00457 } 00458 00459 00460 00461 # endif // ! MLN_INCLUDE_ONLY 00462 00463 } // end of namespace mln::subsampling 00464 00465 } // end of namespace mln 00466 00467 00468 #endif // ! MLN_SUBSAMPLING_ANTIALIASED_HH