
* mln/world/k2/convert_on_access.hh: Rename as... * mln/world/k2/converters.hh: ... this. * mln/world/k2/fill_non_primary_from_primary_faces.hh, * mln/world/kn/immerse.hh: Take a converter functor as argument. --- milena/ChangeLog | 10 + milena/mln/world/k2/convert_on_access.hh | 126 ----------- milena/mln/world/k2/converters.hh | 232 ++++++++++++++++++++ .../k2/fill_non_primary_from_primary_faces.hh | 73 ++++--- milena/mln/world/kn/immerse.hh | 16 +- 5 files changed, 290 insertions(+), 167 deletions(-) delete mode 100644 milena/mln/world/k2/convert_on_access.hh create mode 100644 milena/mln/world/k2/converters.hh diff --git a/milena/ChangeLog b/milena/ChangeLog index bf4c572..fd1f830 100644 --- a/milena/ChangeLog +++ b/milena/ChangeLog @@ -1,5 +1,15 @@ 2012-10-18 Guillaume Lazzara <z@lrde.epita.fr> + Let the user specify conversion functions in K2 immersion. + + * mln/world/k2/convert_on_access.hh: Rename as... + * mln/world/k2/converters.hh: ... this. + + * mln/world/k2/fill_non_primary_from_primary_faces.hh, + * mln/world/kn/immerse.hh: Take a converter functor as argument. + +2012-10-18 Guillaume Lazzara <z@lrde.epita.fr> + * mln/core/routine/ops.hh: Update comments. 2012-10-18 Guillaume Lazzara <z@lrde.epita.fr> diff --git a/milena/mln/world/k2/convert_on_access.hh b/milena/mln/world/k2/convert_on_access.hh deleted file mode 100644 index 4c9ab20..0000000 --- a/milena/mln/world/k2/convert_on_access.hh +++ /dev/null @@ -1,126 +0,0 @@ -// Copyright (C) 2012 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. - -/// \file -/// -/// \brief Fill 1 faces in a K2 2D image using its 2 faces. - -#ifndef MLN_WORLD_K2_CONVERT_ON_ACCESS_HH -# define MLN_WORLD_K2_CONVERT_ON_ACCESS_HH - -# include <mln/core/alias/point2d.hh> -# include <mln/world/k2/is_non_primary_face_vertical.hh> -# include <mln/world/k2/is_non_primary_face_horizontal.hh> -# include <mln/world/k2/convert_on_access.hh> - -# include <mln/value/int_u8.hh> -# include <mln/value/intsub.hh> - -namespace mln -{ - - namespace world - { - - namespace k2 - { - - using namespace mln::value; - - template <unsigned n> - void convert_on_access(const intsub<n>& from, intsub<n/2>& to); - - template <unsigned n> - void convert_on_access(const int_u8& from, intsub<n>& to); - - template <unsigned n> - void convert_on_access(const int_u8& from, interval<intsub<n> >& to); - - template <unsigned n> - void convert_on_access(const interval<intsub<n> >& from, int& to); - - template <unsigned n> - void convert_on_access(const interval<intsub<n> >& from, value::int_u8& to); - - template <typename T, typename U> - void convert_on_access(const T& from, U& to); - - -#ifndef MLN_INCLUDE_ONLY - - template <unsigned n> - void convert_on_access(const intsub<n/2>& from, intsub<n>& to) - { - to = from.to_int(); - } - - template <unsigned n> - void convert_on_access(const int_u8& from, intsub<n>& to) - { - to = from.to_equiv(); - } - - template <unsigned n> - void convert_on_access(const int_u8& from, interval<intsub<n> >& to) - { - to = intsub<n>(from.to_interop()); - } - - template <unsigned n> - void convert_on_access(const interval<intsub<n> >& from, int& to) - { - mln_precondition(from.is_degenerated()); - to = from.first(); - } - - template <unsigned n> - void convert_on_access(const interval<intsub<n> >& from, value::int_u8& to) - { - mln_precondition(from.is_degenerated()); - to = from.first(); - } - - template <unsigned n> - void convert_on_access(const interval<intsub<n> >& from, intsub<n/2>& to) - { - mln_precondition(from.is_degenerated()); - to = from.first().to_interop(); - } - - template <typename T, typename U> - void convert_on_access(const T& from, U& to) - { - to = static_cast<U>(from); - } - -# endif // ! MLN_INCLUDE_ONLY - - } // end of namespace mln::world::k2 - - } // end of namespace mln::world - -} // end of namespace mln - -#endif // ! MLN_WORLD_K2_CONVERT_ON_ACCESS_HH diff --git a/milena/mln/world/k2/converters.hh b/milena/mln/world/k2/converters.hh new file mode 100644 index 0000000..de76087 --- /dev/null +++ b/milena/mln/world/k2/converters.hh @@ -0,0 +1,232 @@ +// Copyright (C) 2012 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. + +/// \file +/// +/// \brief Fill 1 faces in a K2 2D image using its 2 faces. + +#ifndef MLN_WORLD_K2_CONVERTERS_HH +# define MLN_WORLD_K2_CONVERTERS_HH + +# include <mln/value/int_u8.hh> +# include <mln/value/intsub.hh> +# include <mln/value/interval.hh> + +namespace mln +{ + + namespace world + { + + namespace k2 + { + + using namespace mln::value; + + template <unsigned n> + struct int_sub_n_to_intsub_n_2 + { + intsub<n/2> operator()(const intsub<n>& from) const; + intsub<n> operator()(const intsub<n/2>& from) const; + }; + + template <unsigned n> + struct int_sub_n_to_intsub_2n + { + intsub<2*n> operator()(const intsub<n>& from) const; + intsub<n> operator()(const intsub<2*n>& from) const; + }; + + template <unsigned n> + struct int_u8_to_intsub_n + { + intsub<n> operator()(const value::int_u8& from) const; + value::int_u8 operator()(const intsub<n>& from) const; + }; + + template <unsigned n> + struct int_u8_to_interval_intsub_n + { + interval<intsub<n> > operator()(const value::int_u8& from) const; + value::int_u8 operator()(const interval<intsub<n> >& from) const; + }; + + template <unsigned n> + struct interval_intsub_n_to_int + { + int operator()(const interval<intsub<n> >& from) const; + interval<intsub<n> > operator()(const int& from) const; + }; + + template <unsigned n> + struct interval_intsub_n_to_int_u8 + { + value::int_u8 operator()(const interval<intsub<n> >& from) const; + interval<intsub<n> > operator()(const value::int_u8& from) const; + }; + + template <unsigned n> + struct interval_intsub_n_to_intsub_n_2 + { + intsub<n/2> operator()(const interval<intsub<n> >& from) const; + interval<intsub<n> > operator()(const intsub<n/2>& from) const; + }; + + template <typename T1, typename T2> + struct generic_converter + { + T2 operator()(const T1& from) const; + T1 operator()(const T2& from) const; + }; + + + +#ifndef MLN_INCLUDE_ONLY + + template <unsigned n> + intsub<n/2> + int_sub_n_to_intsub_n_2<n>::operator()(const intsub<n>& from) const + { + return intsub<n/2>(from); + } + + template <unsigned n> + intsub<n> + int_sub_n_to_intsub_n_2<n>::operator()(const intsub<n/2>& from) const + { + return intsub<n>(from); + } + + + template <unsigned n> + intsub<2*n> + int_sub_n_to_intsub_2n<n>::operator()(const intsub<n>& from) const + { + return static_cast<intsub<2*n> >(from.to_int()); + } + + template <unsigned n> + intsub<n> + int_sub_n_to_intsub_2n<n>::operator()(const intsub<2*n>& from) const + { + return static_cast<intsub<n> >(from.to_int()); + } + + template <unsigned n> + intsub<n> + int_u8_to_intsub_n<n>::operator()(const int_u8& from) const + { + return from.to_equiv(); + } + + template <unsigned n> + value::int_u8 + int_u8_to_intsub_n<n>::operator()(const intsub<n>& from) const + { + return from.to_interop(); + } + + template <unsigned n> + interval<intsub<n> > + int_u8_to_interval_intsub_n<n>::operator()(const int_u8& from) const + { + return intsub<n>(from.to_interop()); + } + + template <unsigned n> + value::int_u8 + int_u8_to_interval_intsub_n<n>::operator()(const interval<intsub<n> >& from) const + { + return from.first().to_interop(); + } + + template <unsigned n> + int + interval_intsub_n_to_int<n>::operator()(const interval<intsub<n> >& from) const + { + mln_precondition(from.is_degenerated()); + return from.first(); + } + + template <unsigned n> + interval<intsub<n> > + interval_intsub_n_to_int<n>::operator()(const int& from) const + { + return interval<intsub<n> >(from); + } + + template <unsigned n> + value::int_u8 + interval_intsub_n_to_int_u8<n>::operator()(const interval<intsub<n> >& from) const + { + mln_precondition(from.is_degenerated()); + return from.first().to_interop(); + } + + template <unsigned n> + interval<intsub<n> > + interval_intsub_n_to_int_u8<n>::operator()(const value::int_u8& from) const + { + return intsub<n>(from.to_interop()); + } + + template <unsigned n> + intsub<n/2> + interval_intsub_n_to_intsub_n_2<n>::operator()(const interval<intsub<n> >& from) const + { + mln_precondition(from.is_degenerated()); + return from.first().to_interop(); + } + + template <unsigned n> + interval<intsub<n> > + interval_intsub_n_to_intsub_n_2<n>::operator()(const intsub<n/2>& from) const + { + return interval<intsub<n> >(from); + } + + template <typename T1, typename T2> + T2 + generic_converter<T1,T2>::operator()(const T1& from) const + { + return static_cast<T2>(from); + } + + template <typename T1, typename T2> + T1 + generic_converter<T1,T2>::operator()(const T2& from) const + { + return static_cast<T1>(from); + } + +# endif // ! MLN_INCLUDE_ONLY + + } // end of namespace mln::world::k2 + + } // end of namespace mln::world + +} // end of namespace mln + +#endif // ! MLN_WORLD_K2_CONVERTERS_HH diff --git a/milena/mln/world/k2/fill_non_primary_from_primary_faces.hh b/milena/mln/world/k2/fill_non_primary_from_primary_faces.hh index bc7509f..41d15cc 100644 --- a/milena/mln/world/k2/fill_non_primary_from_primary_faces.hh +++ b/milena/mln/world/k2/fill_non_primary_from_primary_faces.hh @@ -34,7 +34,7 @@ # include <mln/world/k2/is_non_primary_face_vertical.hh> # include <mln/world/k2/is_non_primary_face_horizontal.hh> # include <mln/world/k2/is_non_primary_face_cross.hh> -# include <mln/world/k2/convert_on_access.hh> +# include <mln/world/k2/converters.hh> namespace mln { @@ -76,10 +76,16 @@ namespace mln \endverbatim */ + template <typename I, typename A, typename F> + void fill_non_primary_from_primary_faces(Image<I>& inout_, + Accumulator<A>& accu_, + const F& converter); /// \overload - template <typename I, typename A> + template <typename I, typename A, typename F> void fill_non_primary_from_primary_faces(Image<I>& inout, - const Accumulator<A>& accu); + const Accumulator<A>& accu, + const F& converter); + # ifndef MLN_INCLUDE_ONLY @@ -87,58 +93,56 @@ namespace mln // Facade - template <typename I, typename A> + template <typename I, typename A, typename F> void fill_non_primary_from_primary_faces(Image<I>& inout_, - F& functor_) + F& functor_, + const F& converter_) { trace::entering("mln::world::k2::fill_non_primary_from_primary_faces"); mln_precondition(exact(inout_).is_valid()); I& inout = exact(inout_); - (void) accu_; typedef typename A::argument V; - A& accu = exact(accu_); + const F& converter = exact(converter_); mln_piter(I) p(inout.domain()); for_all(p) if (is_non_primary_face_vertical(p)) { - accu.init(); V tmp1, tmp2; - convert_on_access(inout(p + 2 * left), tmp1); - convert_on_access(inout(p + 2 * right), tmp2); - convert_on_access(f(tmp1, tmp2), inout(p)); + tmp1 = converter(inout(p + 2 * left)); + tmp2 = converter(inout(p + 2 * right)); + converter(f(tmp1, tmp2), inout(p)); } else if (is_non_primary_face_horizontal(p)) { - accu.init(); V tmp1, tmp2; - convert_on_access(inout(p + 2 * up), tmp1); - convert_on_access(inout(p + 2 * down), tmp2); - convert_on_access(f(tmp1, tmp2), inout(p)); + tmp1 = converter(inout(p + 2 * up)); + tmp2 = converter(inout(p + 2 * down)); + converter(f(tmp1, tmp2), inout(p)); } else if (is_non_primary_face_cross(p)) { - accu.init(); V tmp1, tmp2, tmp3, tmp4; - convert_on_access(inout(p + 2 * up_left), tmp1); - convert_on_access(inout(p + 2 * up_right), tmp2); - convert_on_access(inout(p + 2 * down_left), tmp3); - convert_on_access(inout(p + 2 * down_right), tmp4); - convert_on_access(f(tmp1, tmp2, tmp3, tmp4), inout(p)); + tmp1 = converter(inout(p + 2 * up_left)); + tmp2 = converter(inout(p + 2 * up_right)); + tmp3 = converter(inout(p + 2 * down_left)); + tmp4 = converter(inout(p + 2 * down_right)); + converter(f(tmp1, tmp2, tmp3, tmp4), inout(p)); } trace::exiting("mln::world::k2::fill_non_primary_from_primary_faces"); } - template <typename I, typename A> + template <typename I, typename A, typename F> void fill_non_primary_from_primary_faces(Image<I>& inout_, - Accumulator<A>& accu_) + Accumulator<A>& accu_, + const F& converter_) { trace::entering("mln::world::k2::fill_non_primary_from_primary_faces"); @@ -148,6 +152,7 @@ namespace mln typedef typename A::argument V; A& accu = exact(accu_); + const F& converter = exact(converter_); mln_piter(I) p(inout.domain()); for_all(p) @@ -156,45 +161,45 @@ namespace mln accu.init(); V tmp; - convert_on_access(inout(p + 2 * left), tmp); + tmp = converter(inout(p + 2 * left)); accu.take(tmp); - convert_on_access(inout(p + 2 * right), tmp); + tmp = converter(inout(p + 2 * right)); accu.take(tmp); - convert_on_access(accu.to_result(), inout(p)); + inout(p) = converter(accu.to_result()); } else if (is_non_primary_face_horizontal(p)) { accu.init(); V tmp; - convert_on_access(inout(p + 2 * up), tmp); + tmp = converter(inout(p + 2 * up)); accu.take(tmp); - convert_on_access(inout(p + 2 * down), tmp); + tmp = converter(inout(p + 2 * down)); accu.take(tmp); - convert_on_access(accu.to_result(), inout(p)); + inout(p) = converter(accu.to_result()); } else if (is_non_primary_face_cross(p)) { accu.init(); V tmp; - convert_on_access(inout(p + 2 * up_left), tmp); + tmp = converter(inout(p + 2 * up_left)); accu.take(tmp); - convert_on_access(inout(p + 2 * up_right), tmp); + tmp = converter(inout(p + 2 * up_right)); accu.take(tmp); - convert_on_access(inout(p + 2 * down_left), tmp); + tmp = converter(inout(p + 2 * down_left)); accu.take(tmp); - convert_on_access(inout(p + 2 * down_right), tmp); + tmp = converter(inout(p + 2 * down_right)); accu.take(tmp); - convert_on_access(accu.to_result(), inout(p)); + inout(p) = converter(accu.to_result()); } trace::exiting("mln::world::k2::fill_non_primary_from_primary_faces"); diff --git a/milena/mln/world/kn/immerse.hh b/milena/mln/world/kn/immerse.hh index 380b52f..835a4a1 100644 --- a/milena/mln/world/kn/immerse.hh +++ b/milena/mln/world/kn/immerse.hh @@ -40,7 +40,7 @@ # include <mln/world/k1/fill_0_from_1_faces.hh> # include <mln/world/k1/fill_1_from_2_faces.hh> -# include <mln/world/k2/convert_on_access.hh> +# include <mln/world/k2/converters.hh> namespace mln { @@ -73,9 +73,9 @@ namespace mln \endverbatim */ - template <typename I, typename V> + template <typename I, typename V, typename F> mln_ch_value(I, V) - immerse(const Image<I>& ima_, const unsigned n, const V& new_type); + immerse(const Image<I>& ima_, const unsigned n, const V& new_type, const F& converter_); /// \overload template <typename I> @@ -116,13 +116,15 @@ namespace mln // Facade - template <typename I, typename V> + template <typename I, typename V, typename F> mln_ch_value(I, V) - immerse(const Image<I>& ima_, const unsigned n, const V& new_type) + immerse(const Image<I>& ima_, const unsigned n, + const V& new_type, const F& converter_) { trace::entering("mln::world::kn::immerse_with"); mln_precondition(exact(ima_).is_valid()); const I& ima = exact(ima_); + const F& converter = exact(converter_); (void) new_type; mln_ch_value(I,V) @@ -133,7 +135,7 @@ namespace mln for_all(p) { V tmp; - k2::convert_on_access(ima(p), tmp); + tmp = converter(ima(p)); output(internal::immerse_point(p, n)) = tmp; } @@ -146,7 +148,7 @@ namespace mln immerse(const Image<I>& ima, const unsigned n) { typedef mln_value(I) V; - return immerse(ima, n, V()); + return immerse(ima, n, V(), k2::generic_converter<V,V>()); } -- 1.7.2.5