3786: Add some code to extend the work of Etienne and Fred.

https://svn.lrde.epita.fr/svn/oln/trunk/milena/sandbox Index: ChangeLog from Thierry Geraud <thierry.geraud@lrde.epita.fr> Add some code to extend the work of Etienne and Fred. * theo/experimental/histo_image.cc: New. histo_image.cc | 421 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 421 insertions(+) Index: theo/experimental/histo_image.cc --- theo/experimental/histo_image.cc (revision 0) +++ theo/experimental/histo_image.cc (revision 0) @@ -0,0 +1,421 @@ +#include <mln/value/int_u8.hh> +#include <mln/value/int_s.hh> +#include <mln/value/rgb8.hh> +#include <mln/trait/value/comp.hh> + +#include <mln/core/alias/box1d.hh> +#include <mln/core/image/image1d.hh> +#include <mln/core/image/image3d.hh> + +#include <mln/core/concept/function.hh> +#include <mln/metal/ands.hh> + + + +namespace mln +{ + + + // -------------------------------------------------- fun + + + namespace fun + { + + // . . . . . . . . . . . . . . . v2v:: value <-> index + + // This is a revamp of mln/value/internal/convert.hh. It remains + // to be updated with Fred's new function writting. Then we'll be + // able to make it better, i.e., to handle the different cases + // properly. Precisely a case for scalars with low quantization + // (with a special encoding like quantized float, or not), a case + // for vectors with low quant, etc. + + namespace v2v + { + + // value -> index + + template <typename T> + struct index_of_value : Function_v2v< index_of_value<T> >, + private metal::bool_<(mln_dim(T) == 1)>::check_t + { + typedef unsigned result; + unsigned operator()(const T& v) const + { + return unsigned( int(v) - int(mln_min(T)) ); + } + }; + + template <> + struct index_of_value<bool> : Function_v2v< index_of_value<bool> > + { + typedef unsigned result; + unsigned operator()(bool b) const + { + return b ? 1u : 0u; + } + }; + + template <typename T> + unsigned + meta_index_of_value(const T& v) + { + index_of_value<T> f; + return f(v); + } + + // index -> value + + template <typename T> + struct value_at_index : Function_v2v< value_at_index<T> >, + private metal::bool_<(mln_dim(T) == 1)>::check_t + { + typedef T result; + T operator()(unsigned i) const + { + return T( int(mln_min(T)) + int(i) ); + } + }; + + template <> + struct value_at_index<bool> : Function_v2v< value_at_index<bool> > + { + typedef bool result; + bool operator()(unsigned i) const + { + mln_precondition(i < 2); + return i == 1u ? true : false; + } + }; + + + // . . . . . . . . . . . . . . . value -> point n-D + + + namespace internal + { + + // FIXME: It can be straightforwardly written using + // fun::ith_component. Yet there is no test file for this + // function. + + template <unsigned dim, typename T> + struct point_from_value; + + template <typename T> + struct point_from_value< 1, T > + { + static point1d run(const T& v) + { + return point1d(meta_index_of_value(v)); + } + }; + + template <typename T> + struct point_from_value< 2, T > + { + static point2d run(const T& v) + { + return point2d(meta_index_of_value(v[0]), + meta_index_of_value(v[1])); + } + }; + + template <typename T> + struct point_from_value< 3, T > + { + static point3d run(const T& v) + { + return point3d(meta_index_of_value(v[0]), + meta_index_of_value(v[1]), + meta_index_of_value(v[2])); + } + }; + + } // mln::fun::v2v::internal + + + template <typename T> + struct point_from_value : Function_v2v< point_from_value<T> > + { + enum { d = mln_dim(T) }; + typedef mln_regular_grid_from_dim(d) G; + typedef mln::point<G, def::coord> result; + + result operator()(const T& v) const + { + return internal::point_from_value<d,T>::run(v); + } + + index_of_value<T> f_; + }; + + template <typename T> + mln_result(point_from_value<T>) + meta_point_from_value(const T& v) + { + point_from_value<T> f; + return f(v); + } + + } // mln::fun::v2v + + + + + // . . . . . . . . . . . . . . . p2p::fold* + + namespace p2p + { + + struct fold1d : Function_p2p< fold1d > + { + typedef point1d result; + result operator()(const point1d& p) const + { + point1d tmp(p[0] % b.len(0)); + return tmp; + } + box1d b; + }; + + template <bool along_0, bool along_1> + struct fold2d : Function_p2p< fold2d<along_0,along_1> > + { + typedef point2d result; + result operator()(const point2d& p) const + { + point2d tmp(along_0 ? p[0] % b.len(0) : p[0], + along_1 ? p[1] % b.len(1) : p[1]); + return tmp; + } + box2d b; + }; + + template <bool along_0, bool along_1, bool along_2> + struct fold3d : Function_p2p< fold3d<along_0,along_1,along_2> > + { + typedef point3d result; + result operator()(const point3d& p) const + { + point3d tmp(along_0 ? p[0] % b.len(0) : p[0], + along_1 ? p[1] % b.len(1) : p[1], + along_2 ? p[2] % b.len(2) : p[2]); + return tmp; + } + box3d b; + }; + + } // mln::fun::p2p + + + } // mln::fun + + + // -------------------------------------------------- value + + + namespace value + { + + template <unsigned n, int inf, int sup> + struct circular + { + }; + + + namespace internal + { + template <typename T> + struct is_circular_helper : metal::false_ + {}; + + template <unsigned n, int inf, int sup> + struct is_circular_helper< circular<n,inf,sup> > : metal::true_ + {}; + + template <typename T> + struct is_circular : is_circular_helper<T>::eval + { + }; + + } // mln::value::internal + + } // mln::value + + + namespace trait + { + + template <unsigned n, int inf, int sup> + struct value_< mln::value::circular<n, inf, sup> > + { + enum { + dim = 1, + nbits = n, + card = mln_value_card_from_(n) + }; + // ... + }; + + } // end of namespace trait + + + // -------------------------------------------------- histo + + + namespace histo + { + + namespace internal + { + + template <int dim, typename T> + struct image_from_value_helper + { + }; + + // dim = 1 + + template <typename T, bool is_c> + struct image_from_value_helper_1; + + template <typename T> + struct image_from_value_helper_1< T, false > + { + typedef image1d<unsigned> ret; + + static ret get_image() + { + ret tmp(mln_card(T)); + return tmp; + } + }; + + template <typename T> + struct image_from_value_helper_1< T, true > + { + typedef void ret; + }; + + template <typename T> + struct image_from_value_helper< 1, T > + { + enum { is_c = value::internal::is_circular<T>::value }; + typedef image_from_value_helper_1< T, is_c > helper; + }; + + // dim = 3 + + template <typename C0, bool is_c0, + typename C1, bool is_c1, + typename C2, bool is_c2, + typename T> + struct image_from_value_helper_3; + + template <typename C0, typename C1, typename C2, + typename T> + struct image_from_value_helper_3< C0, false, + C1, false, + C2, false, + T > + { + typedef image3d<unsigned> ret; + static ret get_image() + { + ret tmp(mln_card(C0), mln_card(C1), mln_card(C2)); + return tmp; + } + }; + + template <typename C0, typename C1, typename C2, + typename T> + struct image_from_value_helper_3< C0, true, + C1, false, + C2, false, + T > + { + typedef void ret; + }; + + template <typename T> + struct image_from_value_helper< 3, T > + { + typedef mln_trait_value_comp(T, 0) C0; + typedef mln_trait_value_comp(T, 1) C1; + typedef mln_trait_value_comp(T, 2) C2; + typedef image_from_value_helper_3< C0, value::internal::is_circular<C0>::value, + C1, value::internal::is_circular<C1>::value, + C2, value::internal::is_circular<C2>::value, + T > helper; + }; + + template <typename T> + struct image_from_value_ // Entry point. + { + typedef typename image_from_value_helper<mln_dim(T), T>::helper helper; + }; + + + } // mln::histo::internal + + template <typename T> + struct image_from_value : internal::image_from_value_<T>::helper + { + }; + + + + // First code: the result of this function shall be replaced by + // an histo::image<T> where T is mln_value(I). As a consequence, + // we will not have to call meta_point_from_value... + + template <typename I> + typename image_from_value<mln_value(I)>::ret + compute_image(const Image<I>& input_) + { + const I& input = exact(input_); + typedef image_from_value<mln_value(I)> helper; + typename helper::ret h = helper::get_image(); + + mln_piter(I) p(input.domain()); + for_all(p) + ++h( fun::v2v::meta_point_from_value(input(p)) ); + + return h; + } + + } // mln::histo + +} // mln + + +int main() +{ + using namespace mln; + + { + typedef bool T; + std::cout << histo::image_from_value<T>::get_image().domain() << std::endl; + } + + { + typedef unsigned char T; + std::cout << histo::image_from_value<T>::get_image().domain() << std::endl; + } + + { + typedef value::int_s<3> T; + std::cout << histo::image_from_value<T>::get_image().domain() << std::endl; + } + + { + typedef value::rgb8 T; + std::cout << histo::image_from_value<T>::get_image().domain() << std::endl; + } + + { + // typedef value::circular<8,0,9> T; + } +}
participants (1)
-
Thierry Geraud