https://svn.lrde.epita.fr/svn/oln/trunk/olena Index: ChangeLog from Roland Levillain <roland@lrde.epita.fr> Add a morpher adding a look-up table to an image. * oln/core/lookup_table.hh: New. * oln/morpher/with_lut.hh: New morpher. * oln/Makefile.am (nobase_oln_HEADERS): Add core/lookup_table.hh and morpher/with_lut.hh. * tests/morphers/with_lut.cc: New test. * tests/morphers/Makefile.am (check_PROGRAMS): Add with_lut. (with_lut_SOURCES): New. oln/Makefile.am | 2 oln/core/lookup_table.hh | 125 +++++++++++++++++++++++++++++++ oln/morpher/with_lut.hh | 177 +++++++++++++++++++++++++++++++++++++++++++++ tests/morphers/Makefile.am | 2 tests/morphers/with_lut.cc | 96 ++++++++++++++++++++++++ 5 files changed, 402 insertions(+) Index: tests/morphers/with_lut.cc --- tests/morphers/with_lut.cc (revision 0) +++ tests/morphers/with_lut.cc (revision 0) @@ -0,0 +1,96 @@ +// Copyright (C) 2006 EPITA Research and Development Laboratory +// +// This file is part of the Olena Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License version 2 as published by the +// Free Software Foundation. +// +// This library 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 this library; see the file COPYING. If not, write to +// the Free Software Foundation, 51 Franklin Street, Fifth Floor, +// Boston, MA 02111-1307, USA. +// +// As a special exception, you may use this file as part of a free +// software library 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. + +/// Test the look-up table morpher. + +#include <oln/basics2d.hh> +#include <oln/morpher/with_lut.hh> +#include <oln/value/color/rgb.hh> +#include <oln/level/fill.hh> +#include <oln/debug/print.hh> + + +// FIXME: Remove. +using namespace oln; + +template <typename I> +void image_test(const oln::abstract::image<I>&) +{ + // Do nothing. +} + +oln::value::color::rgb8 white(255, 255, 255); +oln::value::color::rgb8 blue ( 0, 0, 255); + +int main() +{ + using oln::value::color::rgb8; + + unsigned data[] = { 0, 1, 2, 0, 1, 2, 0, 1, 2}; + + typedef image2d<unsigned> image_t; + image_t ima(3, 3); + level::fill(ima, data); + debug::print(ima); + + typedef lookup_table<unsigned, rgb8> lut_t; + lut_t lut; + rgb8 c(16, 6, 4); + lut. + add(0, blue). + add(1, white). + add(2, c); + std::cout << lut << std::endl; + + typedef morpher::with_lut<image_t, lut_t> lutimage_t; + lutimage_t ima2 = ima + lut; + + // ima2 is an image, and can be as argument to to image routines. + image_test(ima2); + + // FIXME: To be enabled later. +#if 0 + // it is value-wise accessible: + ima2.value(c) = red; +#endif + + // let's look at it + debug::print(ima2); + std::cout << std::endl; + + // it is a 2D image so we have: + point2d p(1, 1); + std::cout << "ima2(p) =" << ima2(p) << std::endl; + // or (likewise): + std::cout << "ima2.at(1, 1) =" << ima2.at(1, 1) << std::endl; + + // FIXME: To be enabled later. +#if 0 + // FIXME... + level::apply(ima2, fun); // 3 ops only !!! +#endif +} Index: tests/morphers/Makefile.am --- tests/morphers/Makefile.am (revision 673) +++ tests/morphers/Makefile.am (working copy) @@ -24,6 +24,7 @@ slice_morpher \ stack_morpher \ value_cast \ + with_lut \ \ morphers @@ -33,6 +34,7 @@ slice_morpher_SOURCES = slice_morpher.cc stack_morpher_SOURCES = stack_morpher.cc value_cast_SOURCES = value_cast.cc +with_lut_SOURCES = with_lut.cc morphers_SOURCES = morphers.cc Index: oln/core/lookup_table.hh --- oln/core/lookup_table.hh (revision 0) +++ oln/core/lookup_table.hh (revision 0) @@ -0,0 +1,125 @@ +// Copyright (C) 2006 EPITA Research and Development Laboratory +// +// This file is part of the Olena Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License version 2 as published by the +// Free Software Foundation. +// +// This library 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 this library; see the file COPYING. If not, write to +// the Free Software Foundation, 51 Franklin Street, Fifth Floor, +// Boston, MA 02111-1307, USA. +// +// As a special exception, you may use this file as part of a free +// software library 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 OLN_CORE_LOOKUP_TABLE_HH +# define OLN_CORE_LOOKUP_TABLE_HH + +# include <map> +# include <ostream> + +namespace oln +{ + + template <typename Key, typename Data> + class lookup_table + { + typedef lookup_table<Key, Data> self_t; + + public: + typedef Key key_type; + typedef Data data_type; + typedef std::map<Key, Data> map_type; + + public: + lookup_table(); + + self_t& add (const key_type& k, const data_type& d); + + const data_type operator () (const key_type& key) const; + + const map_type& map() const; + + private: + std::map<Key, Data> map_; + }; + + +# ifndef OLN_INCLUDE_ONLY + + template <typename Key, typename Data> + lookup_table<Key, Data>::lookup_table() : + map_() + { + } + + template <typename Key, typename Data> + lookup_table<Key, Data>& + lookup_table<Key, Data>::add (const Key& k, const Data& d) + { + map_.insert(std::make_pair(k, d)); + return *this; + } + + template <typename Key, typename Data> + const Data + lookup_table<Key, Data>::operator () (const Key& key) const + { + typedef typename lookup_table<Key, Data>::map_type map_t; + typename map_t::const_iterator i = map_.find(key); + // FIXME: Is this the expected behavior when the LUT has no data + // for \a key. + assert(i != map_.end()); + return i->second; + } + + template <typename Key, typename Data> + const typename lookup_table<Key, Data>::map_type& + lookup_table<Key, Data>::map() const + { + return map_; + } + +# endif + + + /// Print a look-up table. + template <typename Key, typename Data> + std::ostream& + operator<< (std::ostream& ostr, const lookup_table<Key, Data>& lut); + + +# ifndef OLN_INCLUDE_ONLY + + template <typename Key, typename Data> + std::ostream& + operator<< (std::ostream& ostr, const lookup_table<Key, Data>& lut) + { + typedef lookup_table<Key, Data> lut_t; + const typename lut_t::map_type& map = lut.map(); + for (typename lut_t::map_type::const_iterator i = map.begin (); + i != map.end(); ++i) + ostr << " " << i->first << " -> " << i->second << std::endl; + return ostr; + } + +# endif + +} // end of namespace oln + + + +#endif // ! OLN_CORE_LOOKUP_TABLE_HH Index: oln/Makefile.am --- oln/Makefile.am (revision 673) +++ oln/Makefile.am (working copy) @@ -148,6 +148,7 @@ core/fwd_decls.hh \ core/image_entry.hh \ core/iterator_vtypes.hh \ + core/lookup_table.hh \ core/macros.hh \ core/neighborhood_entry.hh \ core/point_set_entry.hh \ @@ -177,6 +178,7 @@ morpher/thru_fun.hh \ morpher/thru_mfun.hh \ morpher/value_cast.hh \ + morpher/with_lut.hh \ \ value/color/rgb.hh \ \ Index: oln/morpher/with_lut.hh --- oln/morpher/with_lut.hh (revision 0) +++ oln/morpher/with_lut.hh (revision 0) @@ -0,0 +1,177 @@ +// Copyright (C) 2006 EPITA Research and Development Laboratory +// +// This file is part of the Olena Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License version 2 as published by the +// Free Software Foundation. +// +// This library 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 this library; see the file COPYING. If not, write to +// the Free Software Foundation, 51 Franklin Street, Fifth Floor, +// Boston, MA 02111-1307, USA. +// +// As a special exception, you may use this file as part of a free +// software library 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 OLN_MORPHER_WITH_LUT_HH +# define OLN_MORPHER_WITH_LUT_HH + +# include <oln/morpher/internal/image_value_morpher.hh> +# include <oln/core/lookup_table.hh> + + +namespace oln +{ + + namespace morpher + { + // Forward declaration. + template <typename Image, typename Lut> struct with_lut; + + } // end of namespace oln::morpher + + + /// Super type. + template <typename Image, typename Lut> + struct set_super_type< morpher::with_lut<Image, Lut> > + { + typedef morpher::with_lut<Image, Lut> self_t; + typedef morpher::internal::image_value_morpher<Image, self_t> ret; + }; + + /// Virtual types associated to oln::morpher::with_lut<Image, Lut>. + /// \{ + template <typename Image, typename Lut> + struct vtypes< morpher::with_lut<Image, Lut> > + { + private: + typedef oln_type_of(Image, rvalue) orig_value_type; + public: + typedef mlc::true_ is_computed_type; + // Value type. + typedef typename Lut::data_type value_type; + // Look-up table type. + typedef Lut lut_type; + }; + + // Rvalue. + template <typename Image, typename Lut> + struct single_vtype< morpher::with_lut<Image, Lut>, typedef_::rvalue_type > + { + typedef morpher::with_lut<Image, Lut> self_t; + typedef oln_value(self_t) ret; + }; + + // FIXME: What about lvalue type? + +// // Lvalue. +// template <typename Image> +// struct single_vtype< morpher::slice<Image>, typedef_::lvalue_type > +// { +// typedef oln_type_of(Image, lvalue) ret; +// }; + /// \} + + + namespace morpher + { + /// Look-up table addition morpher. + template <typename Image, typename Lut> + class with_lut : public stc_get_supers(mlc_comma_1(with_lut<Image, Lut>)) + // FIXME: Ensure oln_value(Image) == Lut::data_type? Or just let + // the ctor check this property? + { + private: + typedef with_lut<Image, Lut> self_t; + typedef stc_get_super(self_t) super_t; + typedef Lut lut_t; + typedef oln_type_of(self_t, value) value_t; + typedef oln_type_of(self_t, rvalue) rvalue_t; + typedef oln_type_of(self_t, psite) psite_t; + // FIXME: Useful typedef? +// typedef oln_type_of(Image, value) orig_value_t; + + public: + with_lut(const Image& image, const Lut& lut); + const lut_t& lut() const; + + rvalue_t impl_op_read(const psite_t& p) const; + + // FIXME: Implement impl_op_write() when there is value proxy? + + protected: + lut_t lut_; + }; + + +# ifndef OLN_INCLUDE_ONLY + + template <typename Image, typename Lut> + with_lut<Image, Lut>::with_lut(const Image& image, const Lut& lut) : + super_t(image), + lut_(lut) + { + mlc::assert_equal_< oln_value(Image), typename Lut::key_type >::check(); + } + + template <typename Image, typename Lut> + typename with_lut<Image, Lut>::rvalue_t + with_lut<Image, Lut>:: + impl_op_read(const typename with_lut<Image, Lut>::psite_t& p) const + { + // FIXME: What if lut_ has no value for `this->image_(p)'? At + // least, document the behavior of this method (will it abort, + // does the LUT have to provide a default value, etc.) + return lut_(this->image_(p)); + } + + template <typename Image, typename Lut> + const typename with_lut<Image, Lut>::lut_t& + with_lut<Image, Lut>::lut() const + { + return lut_; + } + +# endif + + } // end of namespace oln::morpher + + + + template <typename I, typename K, typename D> + morpher::with_lut< I, lookup_table<K, D> > + operator + (const abstract::image<I>& image, + const lookup_table<K, D>& lut); + + +# ifndef OLN_INCLUDE_ONLY + + template <typename I, typename K, typename D> + morpher::with_lut< I, lookup_table<K, D> > + operator + (const abstract::image<I>& image, + const lookup_table<K, D>& lut) + { + typedef lookup_table<K, D> lut_t; + mlc::assert_equal_< oln_value(I), typename lut_t::key_type >::check(); + morpher::with_lut<I, lut_t> tmp(image.exact(), lut); + return tmp; + } + +# endif + +} // end of namespace oln + + +#endif // ! OLN_MORPHER_WITH_LUT_HH