URL:
https://svn.lrde.epita.fr/svn/oln/trunk/milena/sandbox
ChangeLog:
2009-08-03 Fabien Freling <fabien.freling(a)lrde.epita.fr>
Implement support for 2D tiled images and other drafts.
* fabien/igr/segment_us_morpho.sh: Small update.
* fabien/magick/Makefile: Minor fix.
* fabien/mln/canvas/browsing/directional.hh: Draft.
* fabien/mln/canvas/browsing/snake.hh: Draft.
* fabien/mln/core/image/magick_tiled2d.hh: Implement 2D tiled image with
ImageMagick.
* fabien/mln/core/image/tiled2d.hh: Implement 2D tiled image.
* fabien/mln/data/fast_median.hh: Draft.
* fabien/mln/io/pnm/load.hh: Add support for tiled images.
* fabien/tests/core/image/Makefile: New Makefile for building.
* fabien/tests/core/image/tiled2d.cc: New test for tiled images.
---
igr/segment_us_morpho.sh | 4
mln/core/image/magick_tiled2d.hh | 56 ++++++
mln/io/pnm/load.hh | 334 +++++++++++++++++++++++++++++++++++++++
tests/core/image/Makefile | 7
tests/core/image/tiled2d.cc | 37 ++++
5 files changed, 434 insertions(+), 4 deletions(-)
Index: trunk/milena/sandbox/fabien/igr/segment_us_morpho.sh
===================================================================
--- trunk/milena/sandbox/fabien/igr/segment_us_morpho.sh (revision 4334)
+++ trunk/milena/sandbox/fabien/igr/segment_us_morpho.sh (revision 4335)
@@ -4,10 +4,6 @@
process ()
{
nlabels=`./filter_morpho_us $@`
-#if [ $? -gt 0 ]; then
-# echo "error: filter_morpho_us failed"
-# exit
-# fi
../bin/dump2pgm8b closing.dump closing.pgm
convert closing.pgm 01_closing.png
Index: trunk/milena/sandbox/fabien/tests/core/image/tiled2d.cc
===================================================================
--- trunk/milena/sandbox/fabien/tests/core/image/tiled2d.cc (revision 0)
+++ trunk/milena/sandbox/fabien/tests/core/image/tiled2d.cc (revision 4335)
@@ -0,0 +1,37 @@
+#include <mln/core/image/tiled2d.hh>
+
+#include <mln/io/ppm/load.hh>
+#include <mln/literal/colors.hh>
+#include <mln/value/rgb8.hh>
+
+#include <mln/debug/quiet.hh>
+
+
+using namespace mln;
+using value::rgb8;
+
+
+int main(int argc, char* argv[])
+{
+ if (argc != 2)
+ {
+ std::cout << "Usage: " << argv[0] << " input
output" << std::endl;
+ return 1;
+ }
+
+ tiled2d<rgb8> tiled_ima;
+
+ io::ppm::load(tiled_ima, argv[1]);
+
+ std::cout << "bbox: " << tiled_ima.bbox() << std::endl;
+ /*mln_piter_(tiled2d<rgb8>) p(tiled_ima.domain());
+ for_all(p)
+ {
+ if (p.col() % 64 == 0)
+ {
+ tiled_ima(p) = literal::purple;
+ }
+ }*/
+
+ return 0;
+}
Index: trunk/milena/sandbox/fabien/tests/core/image/Makefile
===================================================================
--- trunk/milena/sandbox/fabien/tests/core/image/Makefile (revision 0)
+++ trunk/milena/sandbox/fabien/tests/core/image/Makefile (revision 4335)
@@ -0,0 +1,7 @@
+CXX = g++
+CXXFLAGS = -DNDEBUG -O1
+LIBS = `Magick++-config --cppflags --cxxflags --ldflags --libs`
+INC = -I../../../ -I../../../../../
+
+tiled2d: tiled2d.cc
+ ${CXX} ${CXXFLAGS} ${INC} $^ -o tiled2d
Index: trunk/milena/sandbox/fabien/mln/io/pnm/load.hh
===================================================================
--- trunk/milena/sandbox/fabien/mln/io/pnm/load.hh (revision 0)
+++ trunk/milena/sandbox/fabien/mln/io/pnm/load.hh (revision 4335)
@@ -0,0 +1,334 @@
+// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 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_IO_PNM_LOAD_HH
+# define MLN_IO_PNM_LOAD_HH
+
+/// \file
+///
+/// Define a function which loads an image of kind PNM 8/16bits with
+/// given path.
+
+# include <iostream>
+# include <fstream>
+# include <string>
+
+# include <mln/core/image/image2d.hh>
+# include <mln/core/image/tiled2d.hh>
+
+# include <mln/value/int_u8.hh>
+# include <mln/value/rgb.hh>
+
+# include <mln/io/pnm/load_header.hh>
+# include <mln/io/pnm/max_component.hh>
+# include <mln/io/pnm/macros.hh>
+
+# include <mln/metal/is_a.hh>
+
+namespace mln
+{
+
+ namespace io
+ {
+
+ namespace pnm
+ {
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ template <typename I>
+ void load_ascii_value(std::ifstream& file, I& ima);
+
+ template <typename I>
+ void load_ascii_builtin(std::ifstream& file, I& ima);
+
+
+ namespace internal
+ {
+
+ template <typename I>
+ inline
+ void
+ load_ascii_dispatch(std::ifstream& file, I& ima, const
metal::bool_<true>&)
+ {
+ load_ascii_value(file, ima);
+ }
+
+ template <typename I>
+ inline
+ void
+ load_ascii_dispatch(std::ifstream& file, I& ima, const
metal::bool_<false>&)
+ {
+ load_ascii_builtin(file, ima);
+ }
+
+ } // end of namespace mln::io::pnm::internal
+
+
+ // Read a Milena rgb value (sizeof(int_u8) != 1).
+ template <unsigned int n>
+ inline
+ void read_value(std::ifstream& file, value::rgb<n>& v)
+ {
+ typedef typename value::int_u<n>::enc E;
+
+ E c;
+ file.read((char*)(&c), sizeof(E));
+ v.red() = c;
+ file.read((char*)(&c), sizeof(E));
+ v.green() = c;
+ file.read((char*)(&c), sizeof(E));
+ v.blue() = c;
+ }
+
+ // Read a Milena scalar value (sizeof(int_u8) != 1).
+ template <class V>
+ inline
+ void read_value(std::ifstream& file, value::Scalar<V>& v)
+ {
+ typedef typename V::enc E;
+
+ E c;
+ file.read((char*)(&c), sizeof(E));
+ exact(v) = c;
+ }
+
+ // Read a builtin scalar value.
+ template <typename V>
+ inline
+ void read_value(std::ifstream& file, V& v)
+ {
+ V c;
+ file.read((char*)(&c), sizeof(V));
+ v = c;
+ }
+
+ // used when (sizeof(int_u8) != 1)
+ template <typename V>
+ inline
+ void load_raw_2d_uncontiguous(std::ifstream& file, image2d<V>& ima)
+ {
+ const def::coord
+ min_row = geom::min_row(ima),
+ max_row = geom::max_row(ima),
+ min_col = geom::min_col(ima),
+ max_col = geom::max_col(ima);
+
+ point2d p;
+ for (p.row() = min_row; p.row() <= max_row; ++p.row())
+ for (p.col() = min_col; p.col() <= max_col; ++p.col())
+ read_value(file, ima(p));
+ }
+
+ // Warning if we try to load uncontiguous 2D PNM file into a tiled
+ // image, this is not currently supported.
+ template <typename V>
+ inline
+ void load_raw_2d_uncontiguous(std::ifstream& file, tiled2d<V>& ima)
+ {
+ (void) file;
+ (void) ima;
+ std::cout << "You can't load an uncontiguous 2D PNM file into ";
+ std::cout << "a tiled image" << std::endl;
+ abort();
+ }
+
+ // used in g++ > 2.95
+ template <typename I>
+ inline
+ void load_raw_2d_contiguous(std::ifstream& file, I& ima, std::string&
filename)
+ {
+ (void) filename;
+ point2d p = point2d(0, ima.domain().pmin().col());
+ typedef mln_value(I) V;
+ const mln_deduce(I, site, coord)
+ min_row = geom::min_row(ima),
+ max_row = geom::max_row(ima);
+
+ std::size_t len = geom::ncols(ima) * sizeof(V);
+ for (p.row() = min_row; p.row() <= max_row; ++p.row())
+ file.read((char*)(&ima(p)), len);
+ }
+
+ // Load raw 2d for tiled images.
+ template <typename T>
+ inline
+ void load_raw_2d_contiguous(std::ifstream& file, tiled2d<T>& ima,
std::string& filename)
+ {
+ ima.pos_() = file.tellg();
+ ima.file_() = filename;
+ }
+
+ /// load_ascii for Milena value types.
+ template <typename I>
+ inline
+ void load_ascii_value(std::ifstream& file, I& ima)
+ {
+ mln_equiv(mln_value_(I)) c;
+ mln_fwd_piter(I) p(ima.domain());
+ for_all(p)
+ {
+ file >> c;
+ ima(p) = c;
+ }
+ }
+
+ /// load_ascii for builtin value types.
+ template <typename I>
+ inline
+ void load_ascii_builtin(std::ifstream& file, I& ima)
+ {
+ mln_fwd_piter(I) p(ima.domain());
+
+ // FIXME: May be wrong!
+ // Worked out with an image with a max value of 255
+ // loaded in an image2d<unsigned char>.
+ unsigned n;
+
+ for_all(p)
+ {
+ file >> n;
+ ima(p) = n;
+ }
+ }
+
+ /// load_raw_2d.
+ /// for all pnm 8/16 bits formats
+ template <typename I>
+ inline
+ void load_raw_2d(std::ifstream& file, I& ima, std::string& filename)
+ {
+ if (sizeof(value::int_u8) == 1)
+ load_raw_2d_contiguous(file, ima, filename);
+ else
+ load_raw_2d_uncontiguous(file, ima);
+ }
+
+ /// main function : load pnm format
+ template <typename V>
+ inline
+ image2d<V> load(char type_, const std::string& filename)
+ {
+ trace::entering("mln::io::pnm::load");
+
+ std::ifstream file(filename.c_str());
+ if (! file)
+ {
+ std::cerr << "error: file '" << filename
+ << "' not found!";
+ abort();
+ }
+ char type = 0;
+ int nrows, ncols;
+ unsigned int maxval;
+ read_header(static_cast<char>(type_ - 3), type_, file, type,
+ nrows, ncols, maxval);
+
+ if (max_component(V()) != maxval)
+ {
+ std::cerr << "error: file '" << filename
+ << "' cannot be loaded into this type of image"
+ << std::endl;
+
+ std::cerr << "input image have " << maxval
+ << " as maximum value while the destination's one is "
+ << max_component(V()) << " (should be the same)."
+ << std::endl;
+ abort();
+ }
+
+ image2d<V> ima(nrows, ncols);
+ if (type == type_)
+ load_raw_2d(file, ima, filename);
+ else
+ if (type == (type_ - 3))
+ pnm::internal::load_ascii_dispatch(file, ima, mlc_is_a(V, mln::Value)());
+
+ trace::exiting("mln::io::pnm::load");
+
+ return ima;
+ }
+
+ /// An other way to load pnm files :
+ /// the destination is an argument to check if
+ /// the type match the file to load.
+ template <typename I>
+ inline
+ void load(char type_,
+ Image<I>& ima_,
+ const std::string& filename)
+ {
+ trace::entering("mln::io::pnm::load");
+
+ std::ifstream file(filename.c_str());
+ if (! file)
+ {
+ std::cerr << "error: file '" << filename
+ << "' not found!";
+ abort();
+ }
+
+ I& ima = exact(ima_);
+
+ char type = 0;
+ int nrows, ncols;
+ unsigned int maxval;
+ read_header(static_cast<char>(type_ - 3), type_, file, type,
+ nrows, ncols, maxval);
+
+ if (max_component(mln_value(I)()) != maxval)
+ {
+ std::cerr << "error: file '" << filename
+ << "' cannot be loaded into this type of image"
+ << std::endl;
+
+ std::cerr << "input image have " << maxval
+ << " as maximum value while the destination's one is "
+ << max_component(mln_value(I)()) << "."
+ << std::endl;
+ abort();
+ }
+
+ ima.init_(make::box2d(nrows, ncols));
+ if (type == type_)
+ load_raw_2d(file, ima);
+ else
+ if (type == (type_ - 3))
+ pnm::internal::load_ascii_dispatch(file, ima, mlc_is_a(mln_value(I),
mln::Value)());
+
+ trace::exiting("mln::io::pnm::load");
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::io::pnm
+
+ } // end of namespace mln::io
+
+} // end of namespace mln
+
+
+#endif // ! MLN_IO_PNM_LOAD_HH
Index: trunk/milena/sandbox/fabien/mln/core/image/magick_tiled2d.hh
===================================================================
--- trunk/milena/sandbox/fabien/mln/core/image/magick_tiled2d.hh (revision 0)
+++ trunk/milena/sandbox/fabien/mln/core/image/magick_tiled2d.hh (revision 4335)
@@ -0,0 +1,659 @@
+// Copyright (C) 2007, 2008, 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_CORE_IMAGE_TILED2D_HH
+# define MLN_CORE_IMAGE_TILED2D_HH
+
+/// \file
+/// Definition of the basic mln::tiled2d class.
+
+# include <Magick++.h>
+
+# include <mln/core/internal/image_primary.hh>
+# include <mln/core/internal/fixme.hh>
+# include <mln/core/alias/box2d.hh>
+# include <mln/core/routine/init.hh>
+
+# include <mln/border/thickness.hh>
+# include <mln/value/set.hh>
+# include <mln/fun/i2v/all_to.hh>
+# include <mln/value/proxy.hh>
+
+
+
+namespace mln
+{
+
+ // Forward declaration.
+ template <typename T> struct tiled2d;
+
+
+ namespace internal
+ {
+
+ /// Data structure for \c mln::tiled2d<T>.
+ template <typename T>
+ struct data< tiled2d<T> >
+ {
+// data(const box2d& b, unsigned bdr);
+ data(const std::string& filename);
+ ~data();
+
+ Magick::Image buffer_;
+ Magick::PixelPacket* pixel_cache;
+ T value_;
+
+ box2d b_; // theoretical box
+ unsigned bdr_;
+ box2d vb_; // virtual box, i.e., box including the virtual border
+
+ void update_vb_();
+ void allocate_();
+ void deallocate_();
+ void swap_(data< tiled2d<T> >& other_);
+ void reallocate_(unsigned new_border);
+ };
+
+ } // end of namespace mln::internal
+
+
+ namespace trait
+ {
+
+ template <typename T>
+ struct image_< tiled2d<T> > : default_image_< T, tiled2d<T>
>
+ {
+ // misc
+ typedef trait::image::category::primary category;
+ typedef trait::image::speed::slow speed;
+ typedef trait::image::size::regular size;
+
+ // value
+ typedef trait::image::vw_io::none vw_io;
+ typedef trait::image::vw_set::none vw_set;
+ typedef trait::image::value_access::direct value_access;
+ typedef trait::image::value_storage::one_block value_storage;
+ typedef trait::image::value_browsing::site_wise_only value_browsing;
+ typedef trait::image::value_alignment::with_grid value_alignment;
+ typedef trait::image::value_io::read_only value_io;
+
+ // site / domain
+ typedef trait::image::pw_io::read_write pw_io;
+ typedef trait::image::localization::basic_grid localization;
+ typedef trait::image::dimension::two_d dimension;
+
+ // extended domain
+ typedef trait::image::ext_domain::extendable ext_domain;
+ typedef trait::image::ext_value::multiple ext_value;
+ typedef trait::image::ext_io::read_only ext_io;
+ };
+
+ } // end of namespace mln::trait
+
+
+
+ /// Basic 2D image class.
+ ///
+ /// The parameter \c T is the type of pixel values. This image class
+ /// stores data in memory and has a virtual border with constant
+ /// thickness around data.
+ ///
+ /// \ingroup modimageconcrete
+ //
+ template <typename T>
+ class tiled2d : public internal::image_primary< T, mln::box2d, tiled2d<T>
>
+ {
+ typedef internal::image_primary< T, mln::box2d, tiled2d<T> > super_;
+ public:
+
+ /// Value associated type.
+ typedef T value;
+
+ /// Return type of read-only access.
+ typedef const T& rvalue;
+
+ /// Return type of read-write access.
+ typedef mln::value::proxy< tiled2d<T> > lvalue;
+
+
+ /// Skeleton.
+ typedef tiled2d< tag::value_<T> > skeleton;
+
+
+ /// Constructor without argument.
+ tiled2d();
+
+ /// Constructor with the numbers of rows and columns and the
+ /// border thickness.
+ //tiled2d(int nrows, int ncols, unsigned bdr = border::thickness);
+
+ /// Constructor with a box and the border thickness (default is
+ /// 3).
+ // tiled2d(const box2d& b, unsigned bdr = border::thickness);
+
+ /// Constructor with a filename.
+ tiled2d(const std::string& filename);
+
+
+ /// Initialize an empty image.
+ //void init_(const box2d& b, unsigned bdr = border::thickness);
+
+ /// Initialize an empty image.
+ void init_(const std::string& filename);
+
+
+ /// Test if \p p is valid.
+ bool has(const point2d& p) const;
+
+ /// Give the definition domain.
+ const box2d& domain() const;
+
+ /// Give the bounding box domain.
+ const box2d& bbox() 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.
+ mln::value::proxy< tiled2d<T> > operator()(const point2d& p);
+
+ // Read access to the image value located at point \p p.
+ const T& read_(const point2d& p) const;
+
+ // Write access to the image value located at point \p p.
+ void write_(const point2d& p, const T& value);
+
+
+ template <typename P>
+ T& alt(const P& p)
+ {
+ typedef def::coord coord_t;
+ mln_precondition(this->has(p));
+
+ return this->data_->array_ [*(coord_t*)(&p.p_hook_())]
[*((coord_t*)(&p.p_hook_()) + 1)];
+ }
+
+
+ // Specific methods:
+ // -----------------
+
+ /// Read-only access to the image value located at (\p row, \p col).
+ const T& at_(unsigned row, unsigned col) const;
+
+ /// Read-write access to the image value located at (\p row, \p col).
+ T& at_(unsigned row, unsigned col);
+
+ /// Give the number of rows.
+ unsigned nrows() const;
+
+ /// Give the number of columns.
+ unsigned ncols() const;
+
+
+ // As a fastest image:
+ // -------------------
+
+ // Give the index of a point.
+ //using super_::index_of_point;
+
+ /// Give the border thickness.
+ unsigned border() const;
+
+ /// Give the number of elements (points including border ones).
+ unsigned nelements() const;
+
+ /// Read-only access to the image value located at index \p i.
+ const T& element(unsigned i) const;
+
+ /// Read-write access to the image value located at index \p i.
+ T& element(unsigned i);
+
+ /// Give the delta-index corresponding to the delta-point \p dp.
+ int delta_index(const dpoint2d& dp) const;
+
+ /// Give the point corresponding to the index \p i.
+ point2d point_at_index(unsigned i) const;
+
+ /// Give a hook to the value buffer.
+ const Magick::Image buffer() const;
+
+ /// Give a hook to the value buffer.
+ Magick::Image buffer();
+
+
+ /// Resize image border with new_border.
+ void resize_(unsigned new_border);
+ };
+
+
+
+ // Forward declaration
+
+ template <typename T>
+ void init_(tag::border_t, unsigned& bdr, const tiled2d<T>& model);
+
+ template <typename T, typename J>
+ void init_(tag::image_t, mln::tiled2d<T>& target, const J& model);
+
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ // init_
+
+ template <typename T>
+ inline
+ void init_(tag::border_t, unsigned& bdr, const tiled2d<T>& model)
+ {
+ bdr = model.border();
+ }
+
+ template <typename T, typename J>
+ inline
+ void init_(tag::image_t, tiled2d<T>& target, const J& model)
+ {
+ box2d b;
+ init_(tag::bbox, b, model);
+ unsigned bdr;
+ init_(tag::border, bdr, model);
+ target.init_(b, bdr);
+ }
+
+
+ // internal::data< tiled2d<T> >
+
+ namespace internal
+ {
+/* template <typename T>
+ inline
+ data< tiled2d<T> >::data(const box2d& b, unsigned bdr)
+ : buffer_(0),
+ b_ (b),
+ bdr_ (bdr)
+ {
+ allocate_();
+ }*/
+
+ template <typename T>
+ inline
+ data< tiled2d<T> >::data(const std::string& filename)
+ {
+ buffer_.read(filename);
+ // DELETEME
+ std::cout << "columns: " << buffer_.columns() <<
std::endl;
+ std::cout << "rows: " << buffer_.rows() << std::endl;
+ // ! DELETEME
+ b_ = make::box2d(buffer_.rows(), buffer_.columns());
+ std::cout << "bbox: " << b_ << std::endl; // DELETEME
+ }
+
+ template <typename T>
+ inline
+ data< tiled2d<T> >::~data()
+ {
+ deallocate_();
+ }
+
+ template <typename T>
+ inline
+ void
+ data< tiled2d<T> >::update_vb_()
+ {
+ vb_.pmin() = b_.pmin() - dpoint2d(all_to(bdr_));
+ vb_.pmax() = b_.pmax() + dpoint2d(all_to(bdr_));
+ }
+
+ template <typename T>
+ inline
+ void
+ data< tiled2d<T> >::allocate_()
+ {
+ update_vb_();
+// unsigned
+// nr = vb_.len(0),
+// nc = vb_.len(1);
+// buffer_ = new T[nr * nc];
+// array_ = new T*[nr];
+// T* buf = buffer_ - vb_.pmin().col();
+// for (unsigned i = 0; i < nr; ++i)
+// {
+// array_[i] = buf;
+// buf += nc;
+// }
+// array_ -= vb_.pmin().row();
+ mln_postcondition(vb_.len(0) == b_.len(0) + 2 * bdr_);
+ mln_postcondition(vb_.len(1) == b_.len(1) + 2 * bdr_);
+ }
+
+ template <typename T>
+ inline
+ void
+ data< tiled2d<T> >::deallocate_()
+ {
+// if (buffer_)
+// {
+// delete[] buffer_;
+// buffer_ = 0;
+// }
+// if (array_)
+// {
+// array_ += vb_.pmin().row();
+// delete[] array_;
+// array_ = 0;
+// }
+ }
+
+ template <typename T>
+ inline
+ void
+ data< tiled2d<T> >::swap_(data< tiled2d<T> >& other_)
+ {
+ data< tiled2d<T> > self_ = *this;
+ *this = other_;
+ other_ = self_;
+ }
+
+ template <typename T>
+ inline
+ void
+ data< tiled2d<T> >::reallocate_(unsigned new_border)
+ {
+ data< tiled2d<T> >& tmp = *(new data< tiled2d<T>
>(this->b_, new_border));
+ this->swap_(tmp);
+ }
+
+
+ } // end of namespace mln::internal
+
+
+ // tiled2d<T>
+
+ template <typename T>
+ inline
+ tiled2d<T>::tiled2d()
+ {
+ }
+
+ template <typename T>
+ inline
+ tiled2d<T>::tiled2d(const std::string& filename)
+ {
+ init_(filename);
+ }
+
+ template <typename T>
+ inline
+ void
+ tiled2d<T>::init_(const std::string& filename)
+ {
+ mln_precondition(! this->is_valid());
+ this->data_ = new internal::data< tiled2d<T> >(filename);
+ }
+
+ template <typename T>
+ inline
+ const box2d&
+ tiled2d<T>::domain() const
+ {
+ mln_precondition(this->is_valid());
+ return this->data_->b_;
+ }
+
+ template <typename T>
+ inline
+ const box2d&
+ tiled2d<T>::bbox() const
+ {
+ mln_precondition(this->is_valid());
+ return this->data_->b_;
+ }
+
+ template <typename T>
+ inline
+ bool
+ tiled2d<T>::has(const point2d& p) const
+ {
+ mln_precondition(this->is_valid());
+ return this->data_->vb_.has(p);
+ }
+
+ template <typename T>
+ inline
+ const T&
+ tiled2d<T>::operator()(const point2d& p) const
+ {
+ return read_(p);
+ }
+
+ template <typename T>
+ inline
+ mln::value::proxy< tiled2d<T> >
+ tiled2d<T>::operator()(const point2d& p)
+ {
+ mln::value::proxy<tiled2d> prx(*this, p);
+ return prx;
+ }
+
+ template <typename T>
+ inline
+ const T&
+ tiled2d<T>::read_(const point2d& p) const
+ {
+ mln::tiled2d<T>* this_ = const_cast<mln::tiled2d<T>* >(this); //
Trust me, I have to do this(_).
+ this_->data_->pixel_cache = this_->data_->buffer_.getPixels(p.col(),
p.row(), p.col(), p.row());
+ this->data_->value_.red() = this->data_->pixel_cache->red % 256;
+ this->data_->value_.green() = this->data_->pixel_cache->green % 256;
+ this->data_->value_.blue() = this->data_->pixel_cache->blue % 256;
+ return this->data_->value_;
+ }
+
+ template <typename T>
+ inline
+ void
+ tiled2d<T>::write_(const point2d& p, const T& value)
+ {
+ std::cout << "setting value " << value << " at point
" << p << std::endl; // DELETEME
+ /*this->data_->pixel_cache = this->data_->buffer_.getPixels(p.col(),
p.row(), p.col(), p.row());
+ *(this->data_->pixel_cache) = Magick::ColorRGB(256 - value.red(),
+ 256 - value.green(),
+ 256 - value.blue());*/
+ }
+
+
+ // Specific methods:
+
+ template <typename T>
+ inline
+ const T&
+ tiled2d<T>::at_(unsigned row, unsigned col) const
+ {
+ mln_precondition(this->has(point2d(row, col)));
+ //FIXME: use the cache Luke.
+ this->data_->pixel_cache = this->data_->buffer_.getPixels(col, row, col,
row);
+ this->data_->value_.red() = this->data_->pixel_cache->red % 256;
+ this->data_->value_.green() = this->data_->pixel_cache->green % 256;
+ this->data_->value_.blue() = this->data_->pixel_cache->blue % 256;
+ return this->data_->value_;
+ }
+
+ template <typename T>
+ inline
+ T&
+ tiled2d<T>::at_(unsigned row, unsigned col)
+ {
+ mln_precondition(this->has(point2d(row, col)));
+ //FIXME: use the cache Luke.
+ this->data_->pixel_cache = this->data_->buffer_.getPixels(col, row, col,
row);
+ this->data_->value_.red() = this->data_->pixel_cache->red % 256;
+ this->data_->value_.green() = this->data_->pixel_cache->green % 256;
+ this->data_->value_.blue() = this->data_->pixel_cache->blue % 256;
+ return this->data_->value_;
+ }
+
+ template <typename T>
+ inline
+ unsigned
+ tiled2d<T>::nrows() const
+ {
+ mln_precondition(this->is_valid());
+ return this->data_->b_.len(0);
+ }
+
+ template <typename T>
+ inline
+ unsigned
+ tiled2d<T>::ncols() const
+ {
+ mln_precondition(this->is_valid());
+ return this->data_->b_.len(1);
+ }
+
+
+ // Hooks.
+
+ template <typename T>
+ inline
+ const Magick::Image
+ tiled2d<T>::buffer() const
+ {
+ mln_precondition(this->is_valid());
+ return this->data_->buffer_;
+ }
+
+ template <typename T>
+ inline
+ Magick::Image
+ tiled2d<T>::buffer()
+ {
+ mln_precondition(this->is_valid());
+ return this->data_->buffer_;
+ }
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+} // end of namespace mln
+
+
+
+# include <mln/core/trait/pixter.hh>
+# include <mln/core/dpoints_pixter.hh>
+# include <mln/core/pixter2d.hh>
+// # include <mln/core/w_window.hh>
+
+
+namespace mln
+{
+
+ namespace trait
+ {
+
+ // pixter
+
+ template <typename T>
+ struct fwd_pixter< tiled2d<T> >
+ {
+ typedef fwd_pixter2d< tiled2d<T> > ret;
+ };
+
+ template <typename T>
+ struct fwd_pixter< const tiled2d<T> >
+ {
+ typedef fwd_pixter2d< const tiled2d<T> > ret;
+ };
+
+ template <typename T>
+ struct bkd_pixter< tiled2d<T> >
+ {
+ typedef bkd_pixter2d< tiled2d<T> > ret;
+ };
+
+ template <typename T>
+ struct bkd_pixter< const tiled2d<T> >
+ {
+ typedef bkd_pixter2d< const tiled2d<T> > ret;
+ };
+
+ // qixter
+
+ template <typename T, typename W>
+ struct fwd_qixter< tiled2d<T>, W >
+ {
+ typedef dpoints_fwd_pixter< tiled2d<T> > ret;
+ };
+
+ template <typename T, typename W>
+ struct fwd_qixter< const tiled2d<T>, W >
+ {
+ typedef dpoints_fwd_pixter< const tiled2d<T> > ret;
+ };
+
+ template <typename T, typename W>
+ struct bkd_qixter< tiled2d<T>, W >
+ {
+ typedef dpoints_bkd_pixter< tiled2d<T> > ret;
+ };
+
+ template <typename T, typename W>
+ struct bkd_qixter< const tiled2d<T>, W >
+ {
+ typedef dpoints_bkd_pixter< const tiled2d<T> > ret;
+ };
+
+ // nixter
+
+ template <typename T, typename N>
+ struct fwd_nixter< tiled2d<T>, N >
+ {
+ typedef dpoints_fwd_pixter< tiled2d<T> > ret;
+ };
+
+ template <typename T, typename N>
+ struct fwd_nixter< const tiled2d<T>, N >
+ {
+ typedef dpoints_fwd_pixter< const tiled2d<T> > ret;
+ };
+
+ template <typename T, typename N>
+ struct bkd_nixter< tiled2d<T>, N >
+ {
+ typedef dpoints_bkd_pixter< tiled2d<T> > ret;
+ };
+
+ template <typename T, typename N>
+ struct bkd_nixter< const tiled2d<T>, N >
+ {
+ typedef dpoints_bkd_pixter< const tiled2d<T> > ret;
+ };
+
+ } // end of namespace mln::trait
+
+} // end of namespace mln
+
+
+# include <mln/make/image.hh>
+
+
+#endif // ! MLN_CORE_IMAGE_TILED2D_HH
Index: trunk/milena/sandbox/fabien/mln/core/image/tiled2d.hh
===================================================================
--- trunk/milena/sandbox/fabien/mln/core/image/tiled2d.hh (revision 0)
+++ trunk/milena/sandbox/fabien/mln/core/image/tiled2d.hh (revision 4335)
@@ -0,0 +1,676 @@
+// Copyright (C) 2007, 2008, 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_CORE_IMAGE_TILED2D_HH
+# define MLN_CORE_IMAGE_TILED2D_HH
+
+/// \file
+/// Definition of the basic mln::tiled2d class.
+
+# include <mln/core/internal/image_primary.hh>
+# include <mln/core/internal/fixme.hh>
+# include <mln/core/alias/box2d.hh>
+# include <mln/core/routine/init.hh>
+
+# include <mln/border/thickness.hh>
+# include <mln/value/set.hh>
+# include <mln/fun/i2v/all_to.hh>
+# include <mln/value/proxy.hh>
+
+
+
+namespace mln
+{
+
+ // Forward declaration.
+ template <typename T> struct tiled2d;
+
+
+ namespace internal
+ {
+
+ /// Data structure for \c mln::tiled2d<T>.
+ template <typename T>
+ struct data< tiled2d<T> >
+ {
+// data(const box2d& b, unsigned bdr);
+ data(const box2d& b, unsigned bdr);
+ ~data();
+
+ std::fstream* f_;
+ std::streampos pos_;
+ T value_;
+
+ box2d b_; // theoretical box
+ unsigned bdr_;
+ box2d vb_; // virtual box, i.e., box including the virtual border
+
+ void update_vb_();
+ void allocate_();
+ void deallocate_();
+ void swap_(data< tiled2d<T> >& other_);
+ void reallocate_(unsigned new_border);
+ };
+
+ } // end of namespace mln::internal
+
+
+ namespace trait
+ {
+
+ template <typename T>
+ struct image_< tiled2d<T> > : default_image_< T, tiled2d<T>
>
+ {
+ // misc
+ typedef trait::image::category::primary category;
+ typedef trait::image::speed::slow speed;
+ typedef trait::image::size::regular size;
+
+ // value
+ typedef trait::image::vw_io::none vw_io;
+ typedef trait::image::vw_set::none vw_set;
+ typedef trait::image::value_access::direct value_access;
+ typedef trait::image::value_storage::one_block value_storage;
+ typedef trait::image::value_browsing::site_wise_only value_browsing;
+ typedef trait::image::value_alignment::with_grid value_alignment;
+ typedef trait::image::value_io::read_only value_io;
+
+ // site / domain
+ typedef trait::image::pw_io::read_write pw_io;
+ typedef trait::image::localization::basic_grid localization;
+ typedef trait::image::dimension::two_d dimension;
+
+ // extended domain
+ typedef trait::image::ext_domain::extendable ext_domain;
+ typedef trait::image::ext_value::multiple ext_value;
+ typedef trait::image::ext_io::read_only ext_io;
+ };
+
+ } // end of namespace mln::trait
+
+
+
+ /// Basic 2D image class.
+ ///
+ /// The parameter \c T is the type of pixel values. This image class
+ /// stores data in memory and has a virtual border with constant
+ /// thickness around data.
+ ///
+ /// \ingroup modimageconcrete
+ //
+ template <typename T>
+ class tiled2d : public internal::image_primary< T, mln::box2d, tiled2d<T>
>
+ {
+ typedef internal::image_primary< T, mln::box2d, tiled2d<T> > super_;
+ public:
+
+ /// Value associated type.
+ typedef T value;
+
+ /// Return type of read-only access.
+ typedef const T& rvalue;
+
+ /// Return type of read-write access.
+ typedef mln::value::proxy< tiled2d<T> > lvalue;
+
+
+ /// Skeleton.
+ typedef tiled2d< tag::value_<T> > skeleton;
+
+
+ /// Constructor without argument.
+ tiled2d();
+
+ /// Constructor with the numbers of rows and columns and the
+ /// border thickness.
+ //tiled2d(int nrows, int ncols, unsigned bdr = border::thickness);
+
+ /// Constructor with a box and the border thickness (default is
+ /// 3).
+ tiled2d(const box2d& b, unsigned bdr = border::thickness);
+
+ /// Constructor with a filename.
+ //tiled2d(const std::string& filename);
+
+
+ /// Initialize an empty image.
+ void init_(const box2d& b, unsigned bdr = border::thickness);
+
+ /// Initialize an empty image.
+ //void init_(const std::string& filename);
+
+
+ /// Test if \p p is valid.
+ bool has(const point2d& p) const;
+
+ /// Give the definition domain.
+ const box2d& domain() const;
+
+ /// Give the bounding box domain.
+ const box2d& bbox() 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.
+ mln::value::proxy< tiled2d<T> > operator()(const point2d& p);
+
+ // Read access to the image value located at point \p p.
+ const T& read_(const point2d& p) const;
+
+ // Write access to the image value located at point \p p.
+ void write_(const point2d& p, const T& value);
+
+
+ template <typename P>
+ T& alt(const P& p)
+ {
+ typedef def::coord coord_t;
+ mln_precondition(this->has(p));
+
+ return this->data_->array_ [*(coord_t*)(&p.p_hook_())]
[*((coord_t*)(&p.p_hook_()) + 1)];
+ }
+
+
+ // Specific methods:
+ // -----------------
+
+ /// Read-only access to the image value located at (\p row, \p col).
+ const T& at_(unsigned row, unsigned col) const;
+
+ /// Read-write access to the image value located at (\p row, \p col).
+ T& at_(unsigned row, unsigned col);
+
+ /// Give the number of rows.
+ unsigned nrows() const;
+
+ /// Give the number of columns.
+ unsigned ncols() const;
+
+
+
+ /// Give the border thickness.
+ unsigned border() const;
+
+ /// Give the number of elements (points including border ones).
+ unsigned nelements() const;
+
+ /// Read-only access to the image value located at index \p i.
+ const T& element(unsigned i) const;
+
+ /// Read-write access to the image value located at index \p i.
+ T& element(unsigned i);
+
+ /// Give the delta-index corresponding to the delta-point \p dp.
+ int delta_index(const dpoint2d& dp) const;
+
+ /// Give the point corresponding to the index \p i.
+ point2d point_at_index(unsigned i) const;
+
+
+ // Hooks
+
+ /// Give a hook to the value buffer.
+ const std::fstream* buffer() const;
+
+ /// Give a hook to the value buffer.
+ std::fstream* buffer();
+
+ /// Give a hook to the offset for accessing data.
+ const std::streampos pos_() const;
+
+ /// Give a hook to the offset for accessing data.
+ std::streampos pos_();
+
+
+ /// Resize image border with new_border.
+ void resize_(unsigned new_border);
+ };
+
+
+
+ // Forward declaration
+
+ template <typename T>
+ void init_(tag::border_t, unsigned& bdr, const tiled2d<T>& model);
+
+ template <typename T, typename J>
+ void init_(tag::image_t, mln::tiled2d<T>& target, const J& model);
+
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ // init_
+
+ template <typename T>
+ inline
+ void init_(tag::border_t, unsigned& bdr, const tiled2d<T>& model)
+ {
+ bdr = model.border();
+ }
+
+ template <typename T, typename J>
+ inline
+ void init_(tag::image_t, tiled2d<T>& target, const J& model)
+ {
+ box2d b;
+ init_(tag::bbox, b, model);
+ unsigned bdr;
+ init_(tag::border, bdr, model);
+ target.init_(b, bdr);
+ }
+
+
+ // internal::data< tiled2d<T> >
+
+ namespace internal
+ {
+ template <typename T>
+ inline
+ data< tiled2d<T> >::data(const box2d& b, unsigned bdr)
+ : b_ (b),
+ bdr_ (bdr)
+ {
+ allocate_();
+ }
+
+ /*template <typename T>
+ inline
+ data< tiled2d<T> >::data(const std::string& filename)
+ {
+ // FIXME
+ //b_ = make::box2d(buffer_.rows(), buffer_.columns());
+ }*/
+
+ template <typename T>
+ inline
+ data< tiled2d<T> >::~data()
+ {
+ deallocate_();
+ }
+
+ template <typename T>
+ inline
+ void
+ data< tiled2d<T> >::update_vb_()
+ {
+ vb_.pmin() = b_.pmin() - dpoint2d(all_to(bdr_));
+ vb_.pmax() = b_.pmax() + dpoint2d(all_to(bdr_));
+ }
+
+ template <typename T>
+ inline
+ void
+ data< tiled2d<T> >::allocate_()
+ {
+ update_vb_();
+// unsigned
+// nr = vb_.len(0),
+// nc = vb_.len(1);
+// buffer_ = new T[nr * nc];
+// array_ = new T*[nr];
+// T* buf = buffer_ - vb_.pmin().col();
+// for (unsigned i = 0; i < nr; ++i)
+// {
+// array_[i] = buf;
+// buf += nc;
+// }
+// array_ -= vb_.pmin().row();
+ mln_postcondition(vb_.len(0) == b_.len(0) + 2 * bdr_);
+ mln_postcondition(vb_.len(1) == b_.len(1) + 2 * bdr_);
+ }
+
+ template <typename T>
+ inline
+ void
+ data< tiled2d<T> >::deallocate_()
+ {
+// if (f_)
+// delete(f_);
+ }
+
+ template <typename T>
+ inline
+ void
+ data< tiled2d<T> >::swap_(data< tiled2d<T> >& other_)
+ {
+ data< tiled2d<T> > self_ = *this;
+ *this = other_;
+ other_ = self_;
+ }
+
+ template <typename T>
+ inline
+ void
+ data< tiled2d<T> >::reallocate_(unsigned new_border)
+ {
+ data< tiled2d<T> >& tmp = *(new data< tiled2d<T>
>(this->b_, new_border));
+ this->swap_(tmp);
+ }
+
+
+ } // end of namespace mln::internal
+
+
+ // tiled2d<T>
+
+ template <typename T>
+ inline
+ tiled2d<T>::tiled2d()
+ {
+ }
+
+ template <typename T>
+ inline
+ tiled2d<T>::tiled2d(const box2d& b, unsigned bdr)
+ {
+ init_(b, bdr);
+ }
+
+ template <typename T>
+ inline
+ void
+ tiled2d<T>::init_(const box2d& b, unsigned bdr)
+ {
+ mln_precondition(! this->is_valid());
+ this->data_ = new internal::data< tiled2d<T> >(b, bdr);
+ }
+
+ /*template <typename T>
+ inline
+ tiled2d<T>::tiled2d(const std::string& filename)
+ {
+ init_(filename);
+ }
+
+ template <typename T>
+ inline
+ void
+ tiled2d<T>::init_(const std::string& filename)
+ {
+ mln_precondition(! this->is_valid());
+ this->data_ = new internal::data< tiled2d<T> >(filename);
+ }*/
+
+ template <typename T>
+ inline
+ const box2d&
+ tiled2d<T>::domain() const
+ {
+ mln_precondition(this->is_valid());
+ return this->data_->b_;
+ }
+
+ template <typename T>
+ inline
+ const box2d&
+ tiled2d<T>::bbox() const
+ {
+ mln_precondition(this->is_valid());
+ return this->data_->b_;
+ }
+
+ template <typename T>
+ inline
+ bool
+ tiled2d<T>::has(const point2d& p) const
+ {
+ mln_precondition(this->is_valid());
+ return this->data_->vb_.has(p);
+ }
+
+ template <typename T>
+ inline
+ const T&
+ tiled2d<T>::operator()(const point2d& p) const
+ {
+ return read_(p);
+ }
+
+ template <typename T>
+ inline
+ mln::value::proxy< tiled2d<T> >
+ tiled2d<T>::operator()(const point2d& p)
+ {
+ mln::value::proxy<tiled2d> prx(*this, p);
+ return prx;
+ }
+
+ template <typename T>
+ inline
+ const T&
+ tiled2d<T>::read_(const point2d& p) const
+ {
+ std::cout << "setting at point " << p << std::endl; //
DELETEME
+ return this->data_->value_;
+ }
+
+ template <typename T>
+ inline
+ void
+ tiled2d<T>::write_(const point2d& p, const T& value)
+ {
+ std::cout << "setting value " << value << " at point
" << p << std::endl; // DELETEME
+ /*this->data_->pixel_cache = this->data_->buffer_.getPixels(p.col(),
p.row(), p.col(), p.row());
+ *(this->data_->pixel_cache) = Magick::ColorRGB(256 - value.red(),
+ 256 - value.green(),
+ 256 - value.blue());*/
+ }
+
+
+ // Specific methods:
+
+ template <typename T>
+ inline
+ const T&
+ tiled2d<T>::at_(unsigned row, unsigned col) const
+ {
+ mln_precondition(this->has(point2d(row, col)));
+ //FIXME: use the cache Luke.
+ this->data_->pixel_cache = this->data_->buffer_.getPixels(col, row, col,
row);
+ this->data_->value_.red() = this->data_->pixel_cache->red % 256;
+ this->data_->value_.green() = this->data_->pixel_cache->green % 256;
+ this->data_->value_.blue() = this->data_->pixel_cache->blue % 256;
+ return this->data_->value_;
+ }
+
+ template <typename T>
+ inline
+ T&
+ tiled2d<T>::at_(unsigned row, unsigned col)
+ {
+ mln_precondition(this->has(point2d(row, col)));
+ //FIXME: use the cache Luke.
+ this->data_->pixel_cache = this->data_->buffer_.getPixels(col, row, col,
row);
+ this->data_->value_.red() = this->data_->pixel_cache->red % 256;
+ this->data_->value_.green() = this->data_->pixel_cache->green % 256;
+ this->data_->value_.blue() = this->data_->pixel_cache->blue % 256;
+ return this->data_->value_;
+ }
+
+ template <typename T>
+ inline
+ unsigned
+ tiled2d<T>::nrows() const
+ {
+ mln_precondition(this->is_valid());
+ return this->data_->b_.len(0);
+ }
+
+ template <typename T>
+ inline
+ unsigned
+ tiled2d<T>::ncols() const
+ {
+ mln_precondition(this->is_valid());
+ return this->data_->b_.len(1);
+ }
+
+
+ // Hooks.
+
+ template <typename T>
+ inline
+ const std::fstream*
+ tiled2d<T>::buffer() const
+ {
+ mln_precondition(this->is_valid());
+ return this->data_->f_;
+ }
+
+ template <typename T>
+ inline
+ std::fstream*
+ tiled2d<T>::buffer()
+ {
+ mln_precondition(this->is_valid());
+ return this->data_->f_;
+ }
+
+ template <typename T>
+ inline
+ const std::streampos
+ tiled2d<T>::pos_() const
+ {
+ mln_precondition(this->is_valid());
+ return this->data_->pos_;
+ }
+
+ template <typename T>
+ inline
+ std::streampos
+ tiled2d<T>::pos_()
+ {
+ mln_precondition(this->is_valid());
+ return this->data_->pos_;
+ }
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+} // end of namespace mln
+
+
+
+# include <mln/core/trait/pixter.hh>
+# include <mln/core/dpoints_pixter.hh>
+# include <mln/core/pixter2d.hh>
+// # include <mln/core/w_window.hh>
+
+
+namespace mln
+{
+
+ namespace trait
+ {
+
+ // pixter
+
+ template <typename T>
+ struct fwd_pixter< tiled2d<T> >
+ {
+ typedef fwd_pixter2d< tiled2d<T> > ret;
+ };
+
+ template <typename T>
+ struct fwd_pixter< const tiled2d<T> >
+ {
+ typedef fwd_pixter2d< const tiled2d<T> > ret;
+ };
+
+ template <typename T>
+ struct bkd_pixter< tiled2d<T> >
+ {
+ typedef bkd_pixter2d< tiled2d<T> > ret;
+ };
+
+ template <typename T>
+ struct bkd_pixter< const tiled2d<T> >
+ {
+ typedef bkd_pixter2d< const tiled2d<T> > ret;
+ };
+
+ // qixter
+
+ template <typename T, typename W>
+ struct fwd_qixter< tiled2d<T>, W >
+ {
+ typedef dpoints_fwd_pixter< tiled2d<T> > ret;
+ };
+
+ template <typename T, typename W>
+ struct fwd_qixter< const tiled2d<T>, W >
+ {
+ typedef dpoints_fwd_pixter< const tiled2d<T> > ret;
+ };
+
+ template <typename T, typename W>
+ struct bkd_qixter< tiled2d<T>, W >
+ {
+ typedef dpoints_bkd_pixter< tiled2d<T> > ret;
+ };
+
+ template <typename T, typename W>
+ struct bkd_qixter< const tiled2d<T>, W >
+ {
+ typedef dpoints_bkd_pixter< const tiled2d<T> > ret;
+ };
+
+ // nixter
+
+ template <typename T, typename N>
+ struct fwd_nixter< tiled2d<T>, N >
+ {
+ typedef dpoints_fwd_pixter< tiled2d<T> > ret;
+ };
+
+ template <typename T, typename N>
+ struct fwd_nixter< const tiled2d<T>, N >
+ {
+ typedef dpoints_fwd_pixter< const tiled2d<T> > ret;
+ };
+
+ template <typename T, typename N>
+ struct bkd_nixter< tiled2d<T>, N >
+ {
+ typedef dpoints_bkd_pixter< tiled2d<T> > ret;
+ };
+
+ template <typename T, typename N>
+ struct bkd_nixter< const tiled2d<T>, N >
+ {
+ typedef dpoints_bkd_pixter< const tiled2d<T> > ret;
+ };
+
+ } // end of namespace mln::trait
+
+} // end of namespace mln
+
+
+# include <mln/make/image.hh>
+
+
+#endif // ! MLN_CORE_IMAGE_TILED2D_HH
Index: trunk/milena/sandbox/fabien/mln/data/fast_median.hh
===================================================================
--- trunk/milena/sandbox/fabien/mln/data/fast_median.hh (revision 0)
+++ trunk/milena/sandbox/fabien/mln/data/fast_median.hh (revision 4335)
@@ -0,0 +1,180 @@
+// Copyright (C) 2007, 2008, 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_DATA_FAST_MEDIAN_HH
+# define MLN_DATA_FAST_MEDIAN_HH
+
+/*! \file
+ *
+ * \brief Fast Median filtering of an image.
+ *
+ * \todo There are implicit assumptions about input being 2D!!!
+ */
+
+# include <mln/core/concept/image.hh>
+# include <mln/core/alias/window2d.hh>
+# include <mln/accu/stat/median_h.hh>
+
+# include <mln/win/shift.hh>
+# include <mln/win/diff.hh>
+
+# include <mln/geom/min_col.hh>
+# include <mln/geom/min_row.hh>
+# include <mln/geom/max_col.hh>
+# include <mln/geom/max_row.hh>
+
+
+namespace mln
+{
+
+ namespace data
+ {
+
+ /*! Compute in \p output the median filter of image \p input by
+ * the window \p win.
+ *
+ * \param[in] input The image to be filtered.
+ * \param[in] win The window.
+ * \param[in,out] output The output image.
+ *
+ * \pre \p input and \p output have to be initialized.
+ */
+ template <typename I, typename W, typename O>
+ void fast_median(const Image<I>& input, const Window<W>& win,
+ Image<O>& output);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+ namespace impl
+ {
+
+ template <typename I, typename W, typename O>
+ inline
+ void fast_median(const I& input,
+ const W& win,
+ O& output)
+ {
+ mln_precondition(input.is_valid());
+ mln_precondition(output.is_valid());
+
+ def::coord
+ min_row = geom::min_row(input), max_row = geom::max_row(input),
+ min_col = geom::min_col(input), max_col = geom::max_col(input);
+
+ window2d
+ win_fwd_plus = win - win::shift(win, left),
+ win_fwd_minus = win::shift(win, left) - win,
+ win_bkd_plus = win - win::shift(win, right),
+ win_bkd_minus = win::shift(win, right) - win,
+ win_bot = win - win::shift(win, up),
+ win_top = win::shift(win, up) - win;
+
+ accu::stat::median_h<mln_value(I)> med;
+
+ // initialization
+
+ point2d p = input.domain().pmin() + up;
+
+ mln_qixter(const I, window2d)
+ q_fp(input, win_fwd_plus, p), q_fm(input, win_fwd_minus, p),
+ q_bp(input, win_bkd_plus, p), q_bm(input, win_bkd_minus, p),
+ q_top(input, win_top, p), q_bot(input, win_bot, p);
+
+ med.init();
+ {
+ mln_qixter(const I, W) q(input, win, p);
+ for_all(q)
+ med.take(q.val());
+ }
+
+ def::coord& row = p.row();
+ def::coord& col = p.col();
+ bool fwd = true;
+
+ mln_assertion(p.col() == min_col);
+ mln_assertion(p.row() == min_row - 1);
+
+ for (row = min_row; row <= max_row; ++row)
+ {
+
+ // "go down"
+ for_all(q_top)
+ med.untake(q_top.val());
+
+ for_all(q_bot)
+ med.take(q_bot.val());
+
+ output(p) = med;
+
+ if (fwd)
+ // browse line fwd
+ while (col < max_col)
+ {
+ ++col;
+ for_all(q_fm)
+ med.untake(q_fm.val());
+ for_all(q_fp)
+ med.take(q_fp.val());
+ output(p) = med;
+ }
+ else
+ // browse line bkd
+ while (col > min_col)
+ {
+ --col;
+ for_all(q_bm)
+ med.untake(q_bm.val());
+ for_all(q_bp)
+ med.take(q_bp.val());
+ output(p) = med;
+ }
+ // change browsing
+ fwd = ! fwd;
+ }
+ }
+
+ } // end of namespace mln::data::impl
+
+
+ // facade
+
+ template <typename I, typename W, typename O>
+ inline
+ void fast_median(const Image<I>& input, const Window<W>& win,
+ Image<O>& output)
+ {
+ impl::fast_median(exact(input), exact(win), exact(output));
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::data
+
+} // end of namespace mln
+
+
+#endif // ! MLN_DATA_FAST_MEDIAN_HH
Index: trunk/milena/sandbox/fabien/mln/canvas/browsing/snake.hh
===================================================================
--- trunk/milena/sandbox/fabien/mln/canvas/browsing/snake.hh (revision 0)
+++ trunk/milena/sandbox/fabien/mln/canvas/browsing/snake.hh (revision 4335)
@@ -0,0 +1,128 @@
+// 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_CANVAS_BROWSING_SNAKE_HH
+# define MLN_CANVAS_BROWSING_SNAKE_HH
+
+/// \file
+///
+/// Browsing in a snake-way, forward.
+
+# include <vector>
+# include <mln/core/concept/browsing.hh>
+
+
+namespace mln
+{
+
+ namespace canvas
+ {
+
+ namespace browsing
+ {
+
+ template <typename I, typename W, typename F>
+ inline
+ mln_ch_value(I, mln_result(F))
+ snake(const Image<I>& input, const Neighborhood<N>& nbh, F&
functor);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ template <typename I, typename W, typename F>
+ inline
+ mln_ch_value(I, mln_result(F))
+ snake(const Image<I>& input_, const Neighborhood<N>& nbh,
F& functor)
+ {
+ trace::entering("canvas::browsing::snake");
+
+ I input = exact(input_);
+ mln_precondition(input.is_valid());
+
+ // p init
+ f.p = f.input.bbox().pmin();// - f.dps[0];
+
+ std::vector< int > directions(f.moves.size(), 0);
+ unsigned deph = 0;
+ unsigned total_deph = f.moves.size() / 2 + 1;
+
+ // initialization
+ f.init();
+
+ bool first = true;
+ directions[deph] = 1;
+ deph = total_deph - 1;
+
+ // Call the move function (for the first point)
+ (f.*(f.moves[(deph - 1) * 2 - 1 + directions[deph - 1]])) ();
+ while (deph > 0) // If direction is empty, break
+ {
+ mln_assertion(deph <= total_deph);
+ mln_assertion(deph > 0);
+ // If f.p is near the border (we ended a direction) -> next child
+ if (!f.input.domain().has(f.p +
+ f.dps[(deph - 1) * 2 - 1 + directions[deph - 1]]))
+ {
+ // Go up the tree
+ deph--;
+ if (deph >= 1)
+ // Change directions
+ directions[deph] = directions[deph] == 1 ? 0 : 1;
+ continue;
+ }
+
+ if (!first)
+ {
+ // Move f.p
+ f.p += f.dps[(deph - 1) * 2 - 1 + directions[deph - 1]];
+ // Call the move function
+ (f.*(f.moves[(deph - 1) * 2 - 1 + directions[deph - 1]])) ();
+ }
+ else
+ first = false;
+
+ if (deph != total_deph)
+ {
+ // Go down the tree
+ deph++;
+ first = true;
+ }
+ }
+
+ trace::exiting("canvas::browsing::snake");
+ }
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::canvas::browsing
+
+ } // end of namespace mln::canvas
+
+} // end of namespace mln
+
+
+#endif // ! MLN_CANVAS_BROWSING_SNAKE_HH
+
Index: trunk/milena/sandbox/fabien/mln/canvas/browsing/directional.hh
===================================================================
--- trunk/milena/sandbox/fabien/mln/canvas/browsing/directional.hh (revision 0)
+++ trunk/milena/sandbox/fabien/mln/canvas/browsing/directional.hh (revision 4335)
@@ -0,0 +1,157 @@
+// 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_CANVAS_BROWSING_DIRECTIONAL_HH
+# define MLN_CANVAS_BROWSING_DIRECTIONAL_HH
+
+/// \file
+///
+/// Directional browsing of an image.
+
+# include <mln/core/concept/browsing.hh>
+# include <mln/core/concept/image.hh>
+
+namespace mln
+{
+
+ namespace canvas
+ {
+
+ namespace browsing
+ {
+
+ /// Browsing in a certain direction.
+ ///
+ /// This canvas browse all the point of an image 'input' of type
+ /// 'I' and of dimension 'dim' in the direction 'dir'.
+ ///
+ /// The functor should provide (In addition to 'input', 'I',
+ /// 'dim' and 'dir') three methods :
+ ///
+ /// - init() : Will be called at the beginning.
+ /// - next() : Will be called at each point 'p' (also provided by
+ /// the fonctor).
+ /// - final(): Will be called at the end.
+ ///
+ /// F shall features : \n
+ /// { \n
+ /// --- as types: \n
+ /// I; \n
+ /// --- as attributes: \n
+ /// dim; \n
+ /// dir; // and test dir < dim \n
+ /// input; \n
+ /// p; \n
+ /// --- as methods: \n
+ /// void init(); \n
+ /// void next(); \n
+ /// void final(); \n
+ /// } \n
+ ///
+ /// Example : \n
+ ///
+ /// 1 0 0
+ /// 2 0 0
+ /// 3 0 0
+ ///
+ /// 4 0 0
+ /// 5 0 0
+ /// 6 0 0
+ ///
+ /// 7 0 0
+ /// 8 0 0
+ /// 9 0 0
+ ///
+ ///
+ ///
+ template<typename I, typename W, typename F>
+ inline
+ void
+ directional(const Image<I>& input, F& functor);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ template <typename I, typename W, typename F>
+ inline
+ void
+ directional(const Image<I>& input_, F& functor)
+ {
+ trace::entering("canvas::browsing::directional");
+
+ const I& input = exact(input_);
+
+ mln_precondition(f.dir < f.dim);
+
+ mln_psite(I)
+ pmin = f.input.domain().pmin(),
+ pmax = f.input.domain().pmax();
+
+ f.p = pmin;
+
+ f.init();
+
+ do
+ {
+
+ // Browse the run
+ f.init_run();
+ while (f.p[f.dir] <= pmax[f.dir])
+ {
+ f.next();
+ ++f.p[f.dir];
+ }
+ f.p[f.dir] = pmin[f.dir];
+
+
+ // Select the next run start
+ for (int c = F::dim - 1; c >= 0; --c)
+ {
+ if (c == int(f.dir))
+ continue;
+ if (f.p[c] != pmax[c])
+ {
+ ++f.p[c];
+ break;
+ }
+ f.p[c] = pmin[c];
+ }
+
+ } while (f.p != pmin);
+
+ f.final();
+
+ trace::exiting("canvas::browsing::directional");
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::canvas::browsing
+
+ } // end of namespace mln::canvas
+
+} // end of namespace mln
+
+#endif // ! MLN_CANVAS_BROWSING_DIRECTIONAL_HH
Index: trunk/milena/sandbox/fabien/magick/Makefile
===================================================================
--- trunk/milena/sandbox/fabien/magick/Makefile (revision 4334)
+++ trunk/milena/sandbox/fabien/magick/Makefile (revision 4335)
@@ -1,12 +1,14 @@
-CXX = llvm-g++
-CXXFLAGS = -DNDEBUG -O4
+CXX = g++
+CXXFLAGS = -DNDEBUG -O1
LIBS = `Magick++-config --cppflags --cxxflags --ldflags --libs`
INC = -I../../../
-all: magick
magick: magick.cc
${CXX} ${INC} ${LIBS} $^ -o mln_magick
save: save.cc
${CXX} ${INC} ${LIBS} $^ -o magick_save
+
+tiled: tiled_image.cc
+ ${CXX} ${INC} ${LIBS} $^ -o tiled