Milena (Olena)  User documentation 2.0a Id
antialiased.hh
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
 All Classes Namespaces Functions Variables Typedefs Enumerator