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
00122 mlc_abort(I)::check();
00123
00124 mln_concrete(I) output;
00125 return output;
00126 }
00127
00128 }
00129
00130
00131
00132 template <typename I>
00133 inline
00134 mln_concrete(I)
00135 antialiased_2d_fastest_scalar(const Image<I>& input_,
00136 unsigned factor,
00137 const mln_domain(I)& output_domain,
00138 unsigned border_thickness)
00139 {
00140 trace::entering("subsampling::impl::antialiased_2d_fastest");
00141
00142 internal::antialiased_tests(input_, factor,
00143 output_domain, border_thickness);
00144
00145 const I& input = exact(input_);
00146
00147
00148 if (factor == 1)
00149 {
00150 trace::exiting("subsampling::impl::antialiased_2d_fastest");
00151 return duplicate(input);
00152 }
00153
00154 typedef mln_value(I) V;
00155 typedef mln_sum(V) S;
00156
00157 typedef mln_site(I) P;
00158 box<P> b = output_domain;
00159 if (!b.is_valid())
00160 {
00161 P pmin = input.domain().pmin() / factor,
00162 pmax = input.domain().pmax() / factor;
00163 b = box<P>(pmin, pmax);
00164 }
00165 typedef mln_concrete(I) O;
00166 O output(b, border_thickness);
00167
00168
00169 unsigned input_border = factor - std::min(input.nrows() % factor,
00170 input.ncols() % factor);
00171 extension::adjust_duplicate(input, input_border);
00172
00173
00174 typedef const V* ptr_t;
00175
00176 util::array<ptr_t> ptrs(factor, 0);
00177 for (unsigned i = 0; i < factor; ++i)
00178 ptrs[i] = & input.at_(i, 0);
00179
00180 mln_box_runstart_piter(O) s(output.domain());
00181 const unsigned n = s.run_length();
00182 const unsigned
00183 factor_2 = factor * factor,
00184 factor_round = factor_2 / 2;
00185 unsigned offset = input.delta_index(point2d(factor,0) - point2d(0,factor*n));
00186
00187 for_all(s)
00188 {
00189 mln_value(O)* po = & output(s);
00190 for (unsigned i = 0; i < n; ++i)
00191 {
00192 mln_sum(V) s = literal::zero;
00193 for (unsigned j = 0; j < factor; ++j)
00194 for (unsigned k = 0; k < factor; ++k)
00195 s += *ptrs[j]++;
00196
00197 convert::from_to((s + factor_round) / factor_2, *po);
00198 ++po;
00199 }
00200
00201 for (unsigned j = 0; j < factor; ++j)
00202 ptrs[j] += offset;
00203 }
00204
00205 trace::exiting("subsampling::impl::antialiased_2d_fastest");
00206 return output;
00207 }
00208
00209
00210
00211 template <typename I>
00212 inline
00213 mln_concrete(I)
00214 antialiased_2d_fastest_rgb(const Image<I>& input_,
00215 unsigned factor,
00216 const mln_domain(I)& output_domain,
00217 unsigned border_thickness)
00218 {
00219 trace::entering("subsampling::impl::antialiased_2d_rgb");
00220
00221 internal::antialiased_tests(input_, factor,
00222 output_domain, border_thickness);
00223
00224 const I& input = exact(input_);
00225
00226
00227
00228 if (factor == 1)
00229 {
00230 trace::exiting("subsampling::impl::antialiased_2d_rgb");
00231 return duplicate(input);
00232 }
00233
00234 typedef mln_value(I) V;
00235 typedef mln_sum(V) S;
00236
00237 typedef mln_site(I) P;
00238 box<P> b = output_domain;
00239 if (!b.is_valid())
00240 {
00241 P pmin = input.domain().pmin() / factor,
00242 pmax = input.domain().pmax() / factor;
00243 b = box<P>(pmin, pmax);
00244 }
00245 typedef mln_concrete(I) O;
00246 O output(b, border_thickness);
00247
00248
00249 unsigned input_border = factor - std::min(input.nrows() % factor,
00250 input.ncols() % factor);
00251 extension::adjust_duplicate(input, input_border);
00252
00253
00254 typedef const V* ptr_t;
00255
00256 util::array<ptr_t> ptrs(factor, 0);
00257 for (unsigned i = 0; i < factor; ++i)
00258 ptrs[i] = & input.at_(i, 0);
00259
00260 mln_box_runstart_piter(O) s(output.domain());
00261 const unsigned n = s.run_length();
00262 const unsigned
00263 factor_2 = factor * factor,
00264 factor_round = factor_2 / 2;
00265 unsigned offset = input.delta_index(point2d(factor,0) - point2d(0,factor*n));
00266
00267 for_all(s)
00268 {
00269 mln_value(O)* po = & output(s);
00270 for (unsigned i = 0; i < n; ++i)
00271 {
00272 mln_sum(V) s = literal::zero;
00273 for (unsigned j = 0; j < factor; ++j)
00274 for (unsigned k = 0; k < factor; ++k)
00275 {
00276 algebra::vec<3, float> tmp = *ptrs[j]++;
00277 s += tmp;
00278 }
00279
00280
00281
00282 for (unsigned j = 0; j < P::dim; ++j)
00283 s[j] += factor_round;
00284
00285 *po++ = (s ) / factor_2;
00286 }
00287 for (unsigned j = 0; j < factor; ++j)
00288 ptrs[j] += offset;
00289 }
00290
00291 trace::exiting("subsampling::impl::antialiased_2d_rgb");
00292 return output;
00293 }
00294
00295
00296
00297 }
00298
00299
00300
00301
00302
00303 namespace internal
00304 {
00305
00306 template <unsigned dim, typename I>
00307 inline
00308 mln_concrete(I)
00309 antialiased_dispatch(trait::image::value_alignment::any,
00310 trait::image::value_storage::any,
00311 trait::image::value_access::any,
00312 const Image<I>& input,
00313 unsigned factor,
00314 const mln_domain(I)& output_domain,
00315 unsigned border_thickness)
00316 {
00317
00318 mlc_abort(I)::check();
00319 }
00320
00321 template <typename I>
00322 inline
00323 mln_concrete(I)
00324 antialiased_2d_fastest_dispatch(const mln_value(I)&,
00325 const Image<I>& input,
00326 unsigned factor,
00327 const mln_domain(I)& output_domain,
00328 unsigned border_thickness)
00329 {
00330 return impl::antialiased_2d_fastest_scalar(input, factor,
00331 output_domain,
00332 border_thickness);
00333 }
00334
00335
00336 template <unsigned n, typename I>
00337 inline
00338 mln_concrete(I)
00339 antialiased_2d_fastest_dispatch(const value::rgb<n>&,
00340 const Image<I>& input,
00341 unsigned factor,
00342 const mln_domain(I)& output_domain,
00343 unsigned border_thickness)
00344 {
00345 return impl::antialiased_2d_fastest_rgb(input, factor,
00346 output_domain,
00347 border_thickness);
00348 }
00349
00350
00351 template <typename I>
00352 inline
00353 mln_concrete(I)
00354 antialiased_2d_fastest_dispatch(const Image<I>& input,
00355 unsigned factor,
00356 const mln_domain(I)& output_domain,
00357 unsigned border_thickness)
00358 {
00359 typedef mln_value(I) V;
00360 return antialiased_2d_fastest_dispatch(V(), input, factor,
00361 output_domain,
00362 border_thickness);
00363 }
00364
00365
00366 template <typename I>
00367 inline
00368 mln_concrete(I)
00369 antialiased_dispatch_2d(trait::image::value_alignment::with_grid,
00370 trait::image::value_storage::one_block,
00371 trait::image::value_access::direct,
00372 const Image<I>& input,
00373 unsigned factor,
00374 const mln_domain(I)& output_domain,
00375 unsigned border_thickness)
00376 {
00377 return antialiased_2d_fastest_dispatch(input, factor,
00378 output_domain,
00379 border_thickness);
00380 }
00381
00382
00383 template <typename I>
00384 inline
00385 mln_concrete(I)
00386 antialiased_dispatch(const Image<I>& input,
00387 unsigned factor,
00388 const mln_domain(I)& output_domain,
00389 unsigned border_thickness)
00390 {
00391 unsigned dim = mln_site_(I)::dim;
00392
00393 if (dim == 2)
00394 return antialiased_dispatch_2d(
00395 mln_trait_image_value_alignment(I)(),
00396 mln_trait_image_value_storage(I)(),
00397 mln_trait_image_value_access(I)(),
00398 input,
00399 factor,
00400 output_domain,
00401 border_thickness);
00402 else
00403 trace::warning("Not implemented yet.");
00404
00405 mln_concrete(I) output;
00406 return output;
00407 }
00408
00409 }
00410
00411
00412
00413
00414
00415 template <typename I>
00416 inline
00417 mln_concrete(I)
00418 antialiased(const Image<I>& input,
00419 unsigned factor,
00420 const mln_domain(I)& output_domain,
00421 unsigned border_thickness)
00422 {
00423 trace::entering("subsampling::antialiased");
00424
00425 typedef mln_site(I) P;
00426
00427 internal::antialiased_tests(input, factor,
00428 output_domain, border_thickness);
00429
00430 mln_concrete(I)
00431 output = internal::antialiased_dispatch(input, factor,
00432 output_domain,
00433 border_thickness);
00434
00435 trace::exiting("subsampling::antialiased");
00436 return output;
00437 }
00438
00439
00440 template <typename I>
00441 inline
00442 mln_concrete(I)
00443 antialiased(const Image<I>& input, unsigned factor)
00444 {
00445 mln_domain(I) domain;
00446 return antialiased(input, factor, domain, border::thickness);
00447 }
00448
00449
00450
00451 # endif // ! MLN_INCLUDE_ONLY
00452
00453 }
00454
00455 }
00456
00457
00458 #endif // ! MLN_SUBSAMPLING_ANTIALIASED_HH