00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
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
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 }
00101
00102
00103
00104
00105
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
00127 mlc_abort(I)::check();
00128
00129 mln_concrete(I) output;
00130 return output;
00131 }
00132
00133 }
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
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
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
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
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
00286
00287 for (unsigned j = 0; j < P::dim; ++j)
00288 s[j] += factor_round;
00289
00290 *po++ = (s ) / 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 }
00303
00304
00305
00306
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
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 }
00420
00421
00422
00423
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 }
00464
00465 }
00466
00467
00468 #endif // ! MLN_SUBSAMPLING_ANTIALIASED_HH