URL:
https://svn.lrde.epita.fr/svn/oln/trunk/milena
ChangeLog:
2007-10-16 Matthieu Garrigues <garrigues(a)lrde.epita.fr>
Add fi_adaptor class to interact with Free Image.
* mln/core/fi_adaptor.hh: The fi_adaptor class.
* tests/fi_adaptor.cc: An example of use.
* mln/display/color_pretty.hh: Fix to color more values.
* mln/display/save.hh: Nothing
* mln/value/rgb.hh: Disable dangerous constructor.
---
mln/core/fi_adaptor.hh | 456 ++++++++++++++++++++++++++++++++++++++++++++
mln/display/color_pretty.hh | 24 ++
mln/display/save.hh | 1
mln/value/rgb.hh | 16 -
tests/fi_adaptor.cc | 79 +++++++
5 files changed, 567 insertions(+), 9 deletions(-)
Index: trunk/milena/tests/fi_adaptor.cc
===================================================================
--- trunk/milena/tests/fi_adaptor.cc (revision 0)
+++ trunk/milena/tests/fi_adaptor.cc (revision 1343)
@@ -0,0 +1,79 @@
+// Copyright (C) 2007 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.
+
+/*! \file tests/fi_adaptor.cc
+ *
+ * \brief Test on mln::fi_adaptor.
+ */
+
+#include <mln/core/fi_adaptor.hh>
+#include <mln/core/image2d.hh>
+#include <mln/win/rectangle2d.hh>
+
+#include <mln/value/int_u8.hh>
+
+#include <mln/level/paste.hh>
+#include <mln/level/median.hh>
+
+#include <mln/display/show.hh>
+#include <mln/display/save.hh>
+
+#include <FreeImagePlus.h>
+
+
+using namespace mln;
+
+int main()
+{
+ using typename value::int_u8;
+
+#ifdef FREEIMAGE_LIB
+ //FIXME : is it necessary??
+ FreeImage_Initialise();
+#endif // FREEIMAGE_LIB
+
+ win::rectangle2d rect(51, 51);
+
+ fi_adaptor< image2d<int_u8> > adaptor;
+
+ adaptor.load("../img/lena.pgm");
+
+ image2d<int_u8> ima(adaptor.domain());
+
+ level::median(adaptor, rect, ima);
+
+ level::paste(ima, adaptor);
+
+ display::save (adaptor);
+ display::show (adaptor, "xv");
+
+ // call this ONLY when linking with FreeImage as a static library
+#ifdef FREEIMAGE_LIB
+ FreeImage_DeInitialise();
+#endif // FREEIMAGE_LIB
+
+}
Index: trunk/milena/mln/core/fi_adaptor.hh
===================================================================
--- trunk/milena/mln/core/fi_adaptor.hh (revision 0)
+++ trunk/milena/mln/core/fi_adaptor.hh (revision 1343)
@@ -0,0 +1,456 @@
+// Copyright (C) 2007 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 MLN_CORE_FI_ADAPTOR_HH
+# define MLN_CORE_FI_ADAPTOR_HH
+
+
+/*! \file mln/core/image2d.hh
+ *
+ * \brief Definition of the fi_adaptor image class. This class aim
+ * to use the fipImage class (Main FreeImagePlus class) thought one of
+ * our class. Then we can pass image data as our algorithms and
+ * FreeImagePlus's ones.
+ *
+ * For compatibility reasons, images from FreeImage library which
+ * doesn't take more than 7 are converted to 8 bits.
+ *
+ *
+ * COMPILATION:
+ * If you need this class you will need to install FreeImagePlus then
+ * compile you software with the flag -lfreeimageplus.
+ *
+ */
+
+
+# include <mln/core/internal/image_primary.hh>
+# include <mln/core/box2d.hh>
+# include <mln/core/line_piter.hh>
+# include <mln/value/set.hh>
+
+# include <FreeImagePlus.h>
+
+namespace mln
+{
+ // Fwd decl.
+ template <typename I> struct fi_adaptor;
+
+ namespace internal
+ {
+ template <typename I>
+ struct data_< fi_adaptor<I> >
+ {
+ data_();
+ ~data_();
+
+ fipImage fi_ima_;
+ bool fi_ima_loaded;
+
+ mln_value(I)* buffer_;
+ mln_value(I)** array_;
+
+ box2d b_; // theoretical box
+
+ void sync_with_adaptee_();
+ void deallocate_();
+ void swap_(data_< fi_adaptor<I> >& other_);
+ };
+
+ } // end of namespace mln::internal
+
+
+
+ namespace trait
+ {
+
+ template <typename I>
+ struct image_< fi_adaptor<I> > : default_image_< mln_value(I),
fi_adaptor<I> >
+ {
+ typedef trait::image::category::primary category;
+
+ typedef trait::image::access::random access;
+ typedef trait::image::space::two_d space;
+ typedef trait::image::size::regular size;
+ typedef trait::image::support::aligned support;
+
+ typedef trait::image::border::none border;
+ typedef trait::image::data::raw data;
+ typedef trait::image::io::read_write io;
+ typedef trait::image::speed::fast speed;
+ };
+
+ } // end of namespace mln::trait
+
+
+ template <typename I>
+ struct fi_adaptor : public internal::image_primary_< box2d, fi_adaptor<I>
>
+ {
+ // Warning: just to make effective types appear in Doxygen:
+ typedef box2d pset;
+ typedef point2d psite;
+ typedef point2d point;
+ typedef dpoint2d dpoint;
+ typedef mln_fwd_piter(box2d) fwd_piter;
+ typedef mln_bkd_piter(box2d) bkd_piter;
+ typedef line_piter_<point> line_piter;
+ // End of warning.
+
+ /// Typedef T.
+ typedef mln_value(I) T;
+
+ /// Value associated type.
+ typedef T value;
+
+ /// Return type of read-only access.
+ typedef const T& rvalue;
+
+ /// Return type of read-write access.
+ typedef T& lvalue;
+
+ /// Skeleton.
+ typedef fi_adaptor< tag::value_<T> > skeleton;
+
+ /// Value_Set associated type.
+ typedef mln::value::set<T> vset;
+
+
+ /// Constructor without argument.
+ fi_adaptor();
+
+ /// Constructor with a fipImage
+ fi_adaptor(fipImage& ima);
+
+ /// Initialize an empty image.
+ void init_();
+
+ /// Give the set of values of the image.
+ const vset& values() const;
+
+ /// Give the definition domain.
+ const box2d& domain() const;
+
+ /// Give the number of cells.
+ std::size_t ncells() const;
+
+ /// Read-only access to the image value located at point \p p.
+ const T& operator()(const point2d& p) const;
+
+ /// Read-write access to the image value located at point \p p.
+ T& operator()(const point2d& p);
+
+ /// Read-only access to the image value located at offset \p o.
+ const T& operator[](unsigned o) const;
+
+ /// Read-write access to the image value located at offset \p o.
+ T& operator[](unsigned o);
+
+ /// Read-only access to the image value located at (\p row, \p col).
+ const T& at(int row, int col) const;
+
+ /// Read-write access to the image value located at (\p row, \p col).
+ T& at(int row, int col);
+
+
+ /// Fast Image method
+
+ /// Give the offset corresponding to the delta-point \p dp.
+ int offset(const dpoint2d& dp) const;
+
+ /// Give the point corresponding to the offset \p o.
+ point2d point_at_offset(unsigned o) const;
+
+ /// Give a hook to the value buffer.
+ const T* buffer() const;
+
+ /// Give a hook to the value buffer.
+ T* buffer();
+
+ /// \{ Access to adaptee.
+ fipImage& adaptee();
+ const fipImage& adaptee() const;
+ /// \}
+
+ /// \{ Delegatee functions to construct the image. Should be use it
+ /// before calling adaptee() method.
+ BOOL load(const char* lpszPathName, int flag = 0);
+ BOOL loadU(const wchar_t* lpszPathName, int flag = 0);
+ BOOL loadFromHandle(FreeImageIO *io, fi_handle handle, int flag = 0);
+ BOOL loadFromMemory(fipMemoryIO& memIO, int flag = 0);
+ /// \}
+ };
+
+
+ // internal::data_< fi_adaptor<I> >
+
+ namespace internal
+ {
+ template <typename I>
+ data_< fi_adaptor<I> >::data_()
+ {
+ }
+
+ template <typename I>
+ data_< fi_adaptor<I> >::~data_()
+ {
+ deallocate_();
+ }
+
+ template <typename I>
+ void
+ data_< fi_adaptor<I> >::sync_with_adaptee_()
+ {
+ mln_precondition(fi_ima_.isValid());
+ deallocate_();
+ b_ = make::box2d(fi_ima_.getHeight(),
+ fi_ima_.getWidth());
+
+ unsigned
+ nr = fi_ima_.getHeight(),
+ nc = fi_ima_.getWidth();
+ buffer_ = (mln_value(I)*) fi_ima_.accessPixels();
+ array_ = new mln_value(I)*[nr];
+ mln_value(I)* buf = buffer_;
+ for (unsigned i = 0; i < nr; ++i)
+ {
+ array_[i] = buf;
+ buf += nc;
+ }
+ }
+
+ template <typename I>
+ void
+ data_< fi_adaptor<I> >::deallocate_()
+ {
+ if (array_)
+ {
+ delete[] array_;
+ array_ = 0;
+ }
+ }
+
+ template <typename I>
+ void
+ data_< fi_adaptor<I> >::swap_(data_< fi_adaptor<I> >&
other_)
+ {
+ data_< fi_adaptor<I> > self_ = *this;
+ *this = other_;
+ other_ = self_;
+ }
+
+ } // end of namespace mln::internal
+
+
+ // fi_adaptor<I>
+
+ template <typename I>
+ fi_adaptor<I>::fi_adaptor()
+ {
+ }
+
+ template <typename I>
+ void
+ fi_adaptor<I>::init_()
+ {
+ this->data_ = new internal::data_< fi_adaptor<I> >();
+ }
+
+ template <typename I>
+ const typename fi_adaptor<I>::vset&
+ fi_adaptor<I>::values() const
+ {
+ return vset::the();
+ }
+
+ template <typename I>
+ const box2d&
+ fi_adaptor<I>::domain() const
+ {
+ mln_precondition(this->has_data());
+ return this->data_->b_;
+ }
+
+ template <typename I>
+ std::size_t
+ fi_adaptor<I>::ncells() const
+ {
+ mln_precondition(this->has_data());
+ return this->data_->b_.npoints();
+ }
+
+ template <typename I>
+ const mln_value(I)&
+ fi_adaptor<I>::operator()(const point2d& p) const
+ {
+ mln_precondition(this->owns_(p));
+ return this->data_->array_[this->domain().len(0) - 1 - p.row()][p.col()];
+ }
+
+ template <typename I>
+ mln_value(I)&
+ fi_adaptor<I>::operator()(const point2d& p)
+ {
+ mln_precondition(this->owns_(p));
+ return this->data_->array_[this->domain().len(0) - 1 - p.row()][p.col()];
+ }
+
+ template <typename I>
+ const mln_value(I)&
+ fi_adaptor<I>::operator[](unsigned o) const
+ {
+ mln_precondition(o < ncells());
+ return *(this->data_->buffer_ + o);
+ }
+
+ template <typename I>
+ mln_value(I)&
+ fi_adaptor<I>::operator[](unsigned o)
+ {
+ mln_precondition(o < ncells());
+ return *(this->data_->buffer_ + o);
+ }
+
+ template <typename I>
+ const mln_value(I)&
+ fi_adaptor<I>::at(int row, int col) const
+ {
+ mln_precondition(this->owns_(make::point2d(row, col)));
+ return this->data_->array_[this->domain().len(0) - 1 - row][col];
+ }
+
+ template <typename I>
+ mln_value(I)&
+ fi_adaptor<I>::at(int row, int col)
+ {
+ mln_precondition(this->owns_(make::point2d(row, col)));
+ return this->data_->array_[this->domain().len(0) - 1 - row][col];
+ }
+
+ template <typename I>
+ const mln_value(I)*
+ fi_adaptor<I>::buffer() const
+ {
+ mln_precondition(this->has_data());
+ return this->data_->buffer_;
+ }
+
+ template <typename I>
+ mln_value(I)*
+ fi_adaptor<I>::buffer()
+ {
+ mln_precondition(this->has_data());
+ return this->data_->buffer_;
+ }
+
+ template <typename I>
+ int
+ fi_adaptor<I>::offset(const dpoint2d& dp) const
+ {
+ mln_precondition(this->has_data());
+ int o = dp[0] * this->data_->b_.len(1) + dp[1];
+ return o;
+ }
+
+ template <typename I>
+ point2d
+ fi_adaptor<I>::point_at_offset(unsigned o) const
+ {
+ mln_precondition(o < ncells());
+ point2d p = make::point2d(this->data_->b_.max_row() - o /
this->data_->b_.len(1) - this->data_->b_.min_row(),
+ o % this->data_->b_.len(1) + this->data_->b_.min_col());
+ mln_postcondition(& this->operator()(p) == this->data_->buffer_ + o);
+
+ return p;
+ }
+
+ template <typename I>
+ fipImage&
+ fi_adaptor<I>::adaptee()
+ {
+ mln_precondition(this->has_data());
+ return this->data_->fi_ima_;
+ }
+
+ template <typename I>
+ const fipImage&
+ fi_adaptor<I>::adaptee() const
+ {
+ mln_precondition(this->has_data());
+ return this->data_->fi_ima_;
+ }
+
+ template <typename I>
+ BOOL
+ fi_adaptor<I>::load(const char* lpszPathName, int flag)
+ {
+ init_();
+ BOOL r = this->data_->fi_ima_.load(lpszPathName, flag);
+ if (this->data_->fi_ima_.getBitsPerPixel() < 8)
+ this->data_->fi_ima_.convertTo8Bits();
+ this->data_->sync_with_adaptee_();
+ return r;
+ }
+
+ template <typename I>
+ BOOL
+ fi_adaptor<I>::loadU(const wchar_t* lpszPathName, int flag)
+ {
+ init_();
+ BOOL r = this->data_->fi_ima_.loadU(lpszPathName, flag);
+ if (this->data_->fi_ima_.getBitsPerPixel() < 8)
+ this->data_->fi_ima_.convertTo8Bits();
+ this->data_->sync_with_adaptee_();
+ return r;
+ }
+
+ template <typename I>
+ BOOL
+ fi_adaptor<I>::loadFromHandle(FreeImageIO *io, fi_handle handle, int flag)
+ {
+ init_();
+ BOOL r = this->data_->fi_ima_.loadFromHandle(io, handle, flag);
+ if (this->data_->fi_ima_.getBitsPerPixel() < 8)
+ this->data_->fi_ima_.convertTo8Bits();
+ this->data_->sync_with_adaptee_();
+ return r;
+ }
+
+ template <typename I>
+ BOOL
+ fi_adaptor<I>::loadFromMemory(fipMemoryIO& memIO, int flag)
+ {
+ init_();
+ BOOL r = this->data_->fi_ima_.loadFromMemory(memIO, flag);
+ if (this->data_->fi_ima_.getBitsPerPixel() < 8)
+ this->data_->fi_ima_.convertTo8Bits();
+ this->data_->sync_with_adaptee_();
+ return r;
+ }
+
+} // end of namespace mln
+
+
+#endif // ! MLN_CORE_FI_ADAPTOR_HH
Index: trunk/milena/mln/value/rgb.hh
===================================================================
--- trunk/milena/mln/value/rgb.hh (revision 1342)
+++ trunk/milena/mln/value/rgb.hh (revision 1343)
@@ -91,7 +91,7 @@
rgb<n>();
rgb<n>(equiv a);
rgb<n>(enc r, enc g, enc b);
- rgb<n>(enc l);
+ //rgb<n>(enc l);
rgb<n>(const literal::white_t&);
rgb<n>(const literal::black_t&);
rgb<n>(const literal::blue_t&);
@@ -190,13 +190,13 @@
this->c_[2] = b;
}
- template <unsigned n>
- rgb<n>::rgb(enc l)
- {
- this->c_[0] = l;
- this->c_[1] = l;
- this->c_[2] = l;
- }
+// template <unsigned n>
+// rgb<n>::rgb(enc l)
+// {
+// this->c_[0] = l;
+// this->c_[1] = l;
+// this->c_[2] = l;
+// }
template <unsigned n>
rgb<n>::rgb(const literal::white_t&)
Index: trunk/milena/mln/display/color_pretty.hh
===================================================================
--- trunk/milena/mln/display/color_pretty.hh (revision 1342)
+++ trunk/milena/mln/display/color_pretty.hh (revision 1343)
@@ -56,6 +56,28 @@
namespace impl
{
+ template <typename V>
+ value::rgb8
+ color_value(V v)
+ {
+ //r = v * (mln_max(V) / mln_max(value::int_u8) );
+ return value::rgb8(v, v, v);
+ }
+
+ template <unsigned int n>
+ value::rgb8
+ color_value(value::rgb<n> v)
+ {
+ return v;
+ }
+
+ value::rgb8
+ color_value(bool b)
+ {
+ value::int_u8 r = b ? 255 : 0;
+ return value::rgb8(r, r, r);
+ }
+
template <typename I>
typename trait::image_from_mesh < mln_mesh(I), value::rgb8 >::ret
@@ -72,7 +94,7 @@
mln_piter(I) p(input.domain());
for_all(p)
- output(p) = value::rgb8(input(p));
+ output(p) = value::rgb8(color_value(input(p)));
}
return output;
}
Index: trunk/milena/mln/display/save.hh
===================================================================
--- trunk/milena/mln/display/save.hh (revision 1342)
+++ trunk/milena/mln/display/save.hh (revision 1343)
@@ -74,6 +74,7 @@
std::string path_tmp = tmp;
io::ppm::save(out, path_tmp);
+
std::cout << input.id_ () << " = " << path_tmp <<
std::endl;
map_saved_image_tmp_[(void*)input.id_ ()] = path_tmp;
}