• Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Classes
  • Files
  • File List

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           // To be written...
00122           mlc_abort(I)::check();
00123 
00124           mln_concrete(I) output;
00125           return output;
00126         }
00127 
00128       } // end of namespace mln::subsampling::impl::generic
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         // No reduction.
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         // Make sure there is enough data in input border.
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         // No reduction.
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         // Make sure there is enough data in input border.
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               // FIXME: should be removed and replaced by the
00281               // commented part below.
00282               for (unsigned j = 0; j < P::dim; ++j)
00283                 s[j] += factor_round;
00284 
00285               *po++ = (s /*+ factor_round*/) / 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     } // end of namespace mln::subsampling::impl
00298 
00299 
00300 
00301     // Dispatch.
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         // Not implemented yet.
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     } // end of namespace mln::subsampling::internal
00410 
00411 
00412 
00413     // Facades.
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   } // end of namespace mln::subsampling
00454 
00455 } // end of namespace mln
00456 
00457 
00458 #endif // ! MLN_SUBSAMPLING_ANTIALIASED_HH

Generated on Tue Oct 4 2011 15:23:24 for Milena (Olena) by  doxygen 1.7.1