* mln/subsampling/antialiased.hh: New.
---
milena/ChangeLog | 6 +
milena/mln/subsampling/antialiased.hh | 421 +++++++++++++++++++++++++++++++++
2 files changed, 427 insertions(+), 0 deletions(-)
create mode 100644 milena/mln/subsampling/antialiased.hh
diff --git a/milena/ChangeLog b/milena/ChangeLog
index 39c2d80..c2335e8 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -1,5 +1,11 @@
2009-12-14 Guillaume Lazzara <z(a)lrde.epita.fr>
+ Add an antialiased subsampling.
+
+ * mln/subsampling/antialiased.hh: New.
+
+2009-12-14 Guillaume Lazzara <z(a)lrde.epita.fr>
+
Add hooks for subclasses in labeled_image_base.
* mln/core/internal/labeled_image_base.hh: New methods which can
diff --git a/milena/mln/subsampling/antialiased.hh
b/milena/mln/subsampling/antialiased.hh
new file mode 100644
index 0000000..ccb947e
--- /dev/null
+++ b/milena/mln/subsampling/antialiased.hh
@@ -0,0 +1,421 @@
+// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef MLN_SUBSAMPLING_ANTIALIASED_HH
+# define MLN_SUBSAMPLING_ANTIALIASED_HH
+
+/// \file
+///
+/// Antialiased subsampling.
+
+/// \fixme: shift is not used for the moment......
+
+#include <mln/core/concept/image.hh>
+#include <mln/border/thickness.hh>
+
+
+namespace mln
+{
+
+ namespace subsampling
+ {
+
+ /*! FIXME: Doc.
+ */
+ template <typename I>
+ inline
+ mln_concrete(I)
+ antialiased(const Image<I>& input,
+ unsigned gap,
+ const mln_deduce(I, site, delta)& shift,
+ const mln_domain(I)& output_domain,
+ unsigned border_thickness);
+
+
+ /*! \overload
+ */
+ template <typename I>
+ mln_concrete(I)
+ antialiased(const Image<I>& input,
+ unsigned gap,
+ const mln_deduce(I, site, delta)& shift); // FIXME: Add round_up_size.
+
+
+ /*! \overload
+ */
+ template <typename I>
+ mln_concrete(I)
+ antialiased(const Image<I>& input, unsigned gap);
+
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ // Tests
+
+ namespace internal
+ {
+
+ template <typename I>
+ inline
+ void
+ antialiased_tests(const Image<I>& input,
+ unsigned gap,
+ const mln_deduce(I, site, delta)& shift,
+ const mln_domain(I)& output_domain,
+ unsigned border_thickness)
+ {
+ typedef mln_site(I) P;
+
+ mlc_is_a(mln_domain(I), Box)::check();
+ mln_precondition(exact(input).is_valid());
+ mln_precondition(exact(input).domain().pmin() == literal::origin);
+ mln_precondition(gap > 1);
+ for (unsigned i = 0; i < P::dim; ++i)
+ mln_precondition(shift[i] < static_cast<int>(gap));
+
+ (void) input;
+ (void) gap;
+ (void) shift;
+ (void) output_domain;
+ (void) border_thickness;
+ }
+
+
+ } // end of namespace mln::subsampling::internal
+
+
+
+
+ // Implementations.
+
+ namespace impl
+ {
+
+ namespace generic
+ {
+
+ template <typename I>
+ inline
+ mln_concrete(I)
+ antialiased(const Image<I>& input_,
+ unsigned gap,
+ const mln_deduce(I, site, delta)& shift,
+ const mln_domain(I)& output_domain,
+ unsigned border_thickness)
+ {
+ // To be written...
+ mlc_abort(I)::check();
+
+ mln_concrete(I) output;
+ return output;
+ }
+
+ } // end of namespace mln::subsampling::impl::generic
+
+
+ template <typename I>
+ inline
+ mln_concrete(I)
+ antialiased_2d_antialias_fastest_2(const Image<I>& input_,
+ const mln_deduce(I, site, delta)& shift,
+ const mln_domain(I)& output_domain,
+ unsigned border_thickness)
+ {
+ trace::entering("subsampling::impl::antialiased_2d_antialias_fastest_2");
+
+ internal::antialiased_tests(input_, 2, shift,
+ output_domain, border_thickness);
+
+ const I& input = exact(input_);
+
+ typedef mln_value(I) V;
+ typedef mln_sum(V) S;
+
+ typedef mln_site(I) P;
+ box<P> b = output_domain;
+ if (!b.is_valid())
+ {
+ P pmin = input.domain().pmin() / 2,
+ pmax = input.domain().pmax() / 2;
+ b = box<P>(pmin, pmax);
+ }
+
+ typedef mln_concrete(I) O;
+ O output(b, border_thickness);
+
+ const V* ptr1 = & input.at_(0, 0);
+ const V* ptr2 = & input.at_(1, 0);
+
+ mln_box_runstart_piter(O) s(output.domain());
+ const unsigned n = s.run_length();
+
+ unsigned offset = input.delta_index(point2d(2,0) - point2d(0,2*n));
+
+ for_all(s)
+ {
+ mln_value(O)* po = & output(s);
+ for (unsigned i = 0; i < n; ++i)
+ {
+ S s;
+ s = *ptr1 + *(ptr1 + 1);
+ s += *ptr2 + *(ptr2 + 1);
+ ptr1 += 2;
+ ptr2 += 2;
+
+ *po++ = (s + 2) / 4;
+ }
+ ptr1 += offset;
+ ptr2 += offset;
+ }
+
+ trace::exiting("subsampling::impl::antialiased_2d_antialias_fastest_2");
+ return output;
+ }
+
+
+
+ template <typename I>
+ inline
+ mln_concrete(I)
+ antialiased_2d_antialias_fastest_3(const Image<I>& input_,
+ const mln_deduce(I, site, delta)& shift,
+ const mln_domain(I)& output_domain,
+ unsigned border_thickness)
+ {
+ trace::entering("subsampling::impl::antialiased_2d_antialias_fastest_3");
+
+ internal::antialiased_tests(input_, 3, shift,
+ output_domain, border_thickness);
+
+ const I& input = exact(input_);
+
+ typedef mln_value(I) V;
+ typedef mln_sum(V) S;
+
+ typedef mln_site(I) P;
+ box<P> b = output_domain;
+ if (!b.is_valid())
+ {
+ P pmin = input.domain().pmin() / 3,
+ pmax = input.domain().pmax() / 3;
+ b = box<P>(pmin, pmax);
+ }
+ typedef mln_concrete(I) O;
+ O output(b, border_thickness);
+
+ const V* ptr1 = & input.at_(0, 0);
+ const V* ptr2 = & input.at_(1, 0);
+ const V* ptr3 = & input.at_(2, 0);
+
+ mln_box_runstart_piter(O) s(output.domain());
+ const unsigned n = s.run_length();
+
+ unsigned offset = input.delta_index(point2d(3,0) - point2d(0,3*n));
+
+ for_all(s)
+ {
+ mln_value(O)* po = & output(s);
+ for (unsigned i = 0; i < n; ++i)
+ {
+ S s;
+ s = *ptr1 + *(ptr1 + 1) + *(ptr1 + 2);
+ s += *ptr2 + *(ptr2 + 1) + *(ptr2 + 2);
+ s += *ptr3 + *(ptr3 + 1) + *(ptr3 + 2);
+ ptr1 += 3;
+ ptr2 += 3;
+ ptr3 += 3;
+
+ *po++ = (s + 4) / 9;
+ }
+ ptr1 += offset;
+ ptr2 += offset;
+ ptr3 += offset;
+ }
+
+ trace::exiting("subsampling::impl::antialiased_2d_antialias_fastest_3");
+ return output;
+ }
+
+
+
+ } // end of namespace mln::subsampling::impl
+
+
+
+ // Dispatch.
+
+ namespace internal
+ {
+
+ template <unsigned dim, typename I>
+ inline
+ mln_concrete(I)
+ antialiased_dispatch(trait::image::value_alignment::any,
+ trait::image::value_storage::any,
+ trait::image::value_access::any,
+ const Image<I>& input,
+ unsigned gap,
+ const mln_deduce(I, site, delta)& shift,
+ const mln_domain(I)& output_domain,
+ unsigned border_thickness)
+ {
+ // Not implemented yet.
+ mlc_abort(I)::check();
+ }
+
+ template <typename I>
+ inline
+ mln_concrete(I)
+ antialiased_2d_antialias_fastest_dispatch(
+ const Image<I>& input,
+ unsigned gap,
+ const mln_deduce(I, site, delta)& shift,
+ const mln_domain(I)& output_domain,
+ unsigned border_thickness)
+ {
+ if (gap == 2)
+ return impl::antialiased_2d_antialias_fastest_2(input, shift,
+ output_domain,
+ border_thickness);
+ else if (gap == 3)
+ return impl::antialiased_2d_antialias_fastest_3(input, shift,
+ output_domain,
+ border_thickness);
+ else
+ trace::warning("Not implemented yet!");
+
+ mln_concrete(I) output;
+ return output;
+ }
+
+
+ template <typename I>
+ inline
+ mln_concrete(I)
+ antialiased_dispatch_2d(trait::image::value_alignment::with_grid,
+ trait::image::value_storage::one_block,
+ trait::image::value_access::direct,
+ const Image<I>& input,
+ unsigned gap,
+ const mln_deduce(I, site, delta)& shift,
+ const mln_domain(I)& output_domain,
+ unsigned border_thickness)
+ {
+ return antialiased_2d_antialias_fastest_dispatch(input, gap,
+ shift,
+ output_domain,
+ border_thickness);
+ }
+
+
+ template <typename I>
+ inline
+ mln_concrete(I)
+ antialiased_dispatch(const Image<I>& input,
+ unsigned gap,
+ const mln_deduce(I, site, delta)& shift,
+ const mln_domain(I)& output_domain,
+ unsigned border_thickness)
+ {
+ unsigned dim = mln_site_(I)::dim;
+
+ if (dim == 2)
+ return antialiased_dispatch_2d(
+ mln_trait_image_value_alignment(I)(),
+ mln_trait_image_value_storage(I)(),
+ mln_trait_image_value_access(I)(),
+ input,
+ gap,
+ shift,
+ output_domain,
+ border_thickness);
+ else
+ trace::warning("Not implemented yet.");
+
+ mln_concrete(I) output;
+ return output;
+ }
+
+ } // end of namespace mln::subsampling::internal
+
+
+
+ // Facades.
+
+ template <typename I>
+ inline
+ mln_concrete(I)
+ antialiased(const Image<I>& input,
+ unsigned gap,
+ const mln_deduce(I, site, delta)& shift,
+ const mln_domain(I)& output_domain,
+ unsigned border_thickness)
+ {
+ trace::entering("subsampling::antialiased");
+
+ typedef mln_site(I) P;
+
+ internal::antialiased_tests(input, gap, shift,
+ output_domain, border_thickness);
+
+ mln_concrete(I) output;
+ output = internal::antialiased_dispatch(input, gap, shift,
+ output_domain, border_thickness);
+
+ trace::exiting("subsampling::antialiased");
+ return output;
+ }
+
+
+ template <typename I>
+ inline
+ mln_concrete(I)
+ antialiased(const Image<I>& input,
+ unsigned gap,
+ const mln_deduce(I, site, delta)& shift)
+ {
+ mln_domain(I) domain;
+ return antialiased(input, gap, shift, domain, border::thickness);
+ }
+
+
+ template <typename I>
+ inline
+ mln_concrete(I)
+ antialiased(const Image<I>& input, unsigned gap)
+ {
+ return antialiased(input, gap, literal::zero);
+ }
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::subsampling
+
+} // end of namespace mln
+
+
+#endif // ! MLN_SUBSAMPLING_ANTIALIASED_HH
--
1.5.6.5