* mln/core/site_set/p_complex.hh (mln::p_complex<D, P>): Inherit
from internal::site_set_base_.
(mln::p_complex<D, P>::self_)
(mln::p_complex<D, P>::super_)
(mln::p_complex<D, P>::element_)
(mln::p_complex<D, P>::piter):
New typedefs.
(mln::p_complex<D, P>::nsites): Change the return type of this
method to unsigned.
(mln::p_complex<D, P>::is_valid)
(mln::p_complex<D, P>::memory_size):
New methods.
(mln::p_complex<D, P>::bbox): Remove method.
(mln::p_complex<D, P>::bb_): Remove attribute.
(mln::p_complex<D, P>::p_complex)
(mln::p_complex<D, P>::has)
(mln::p_complex<D, P>::cplx):
Update methods.
(operator==(const mln::p_complex<D, P>&, const mln::p_complex<D, P>&)):
New operator.
---
milena/ChangeLog | 25 ++++++
milena/mln/core/site_set/p_complex.hh | 151 ++++++++++++++++++++++++---------
2 files changed, 134 insertions(+), 42 deletions(-)
diff --git a/milena/ChangeLog b/milena/ChangeLog
index 1636331..02ae1c6 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -1,5 +1,30 @@
2008-09-22 Roland Levillain <roland(a)lrde.epita.fr>
+ Update site set mln::p_complex.
+
+ * mln/core/site_set/p_complex.hh (mln::p_complex<D, P>): Inherit
+ from internal::site_set_base_.
+ (mln::p_complex<D, P>::self_)
+ (mln::p_complex<D, P>::super_)
+ (mln::p_complex<D, P>::element_)
+ (mln::p_complex<D, P>::piter):
+ New typedefs.
+ (mln::p_complex<D, P>::nsites): Change the return type of this
+ method to unsigned.
+ (mln::p_complex<D, P>::is_valid)
+ (mln::p_complex<D, P>::memory_size):
+ New methods.
+ (mln::p_complex<D, P>::bbox): Remove method.
+ (mln::p_complex<D, P>::bb_): Remove attribute.
+ (mln::p_complex<D, P>::p_complex)
+ (mln::p_complex<D, P>::has)
+ (mln::p_complex<D, P>::cplx):
+ Update methods.
+ (operator==(const mln::p_complex<D, P>&, const mln::p_complex<D, P>&)):
+ New operator.
+
+2008-09-22 Roland Levillain <roland(a)lrde.epita.fr>
+
Complete the overhaul of line graph images.
* mln/core/image/line_graph_image.hh:
diff --git a/milena/mln/core/site_set/p_complex.hh b/milena/mln/core/site_set/p_complex.hh
index 840ae40..6065df4 100644
--- a/milena/mln/core/site_set/p_complex.hh
+++ b/milena/mln/core/site_set/p_complex.hh
@@ -33,7 +33,6 @@
# include <mln/core/internal/site_set_base.hh>
-# include <mln/accu/bbox.hh>
# include <mln/util/tracked_ptr.hh>
# include <mln/core/complex.hh>
@@ -49,24 +48,53 @@ namespace mln
template <unsigned D, typename P> class p_complex_bkd_piter_;
- // FIXME: Rename as p_faces?
+ namespace trait
+ {
+ template <unsigned D, typename P>
+ struct site_set_< p_complex<D, P> >
+ {
+ typedef trait::site_set::nsites::known nsites;
+ // FIXME: Depends on P!
+ typedef trait::site_set::bbox::unknown bbox;
+ typedef trait::site_set::contents::fixed contents;
+ typedef trait::site_set::arity::unique arity;
+ };
+ } // end of namespace mln::trait
+
+
+ /* FIXME: We should decide was P represents:
+
+ - a unique site type for all faces of all dimensions?
+ (Acceptable for a first implementation -- the one currently
+ chosen.)
+
+ - the site type associated to 0-faces only (site types of n-faces
+ with n > 1 will be deduced from this one)?
+ (Better, but not really flexible.)
- /* FIXME: For compatibility reasons with mln::Point_Set, a point
- type \P is attached to this complex-based pset (but it is not
- used actually). We should either:
+ - a type list of the site types associated faces of each
+ dimensions, e.g.
- - use it, and make it mandatory (good solution for the moment);
- - use it, and make it optional (better solution, but implies
- changes in mln::Point_Set;
- - remove it (easy and bad solution). */
+ mln_type_list(point2d,
+ mln_type_list(site_pair<point2d>,
+ mln_type_list(site_set<point2d>, // or site_triplet<point2d>
+ mln_empty_list)))
+
+ for a 2-complex?
+ (The best solution so far, but requires more work.) */
+
+ /* FIXME: Aggregate site data (location). */
/// A complex psite set based on a the \N-faces of a complex of
/// dimension \p D (a \p D-complex).
template <unsigned D, typename P>
- struct p_complex
- : public internal::site_set_base_< complex_psite<D, P>,
- p_complex<D, P> >
+ class p_complex
+ : public internal::site_set_base_< complex_psite<D, P>, p_complex<D, P> >
{
+ typedef p_complex<D, P> self_;
+ typedef internal::site_set_base_< complex_psite<D, P>, self_ > super_;
+
+ public:
/// \brief Construct a complex psite set from a complex.
///
/// \param gr The complex upon which the complex psite set is built.
@@ -75,27 +103,50 @@ namespace mln
/// still valid after the initial complex has been removed.
p_complex (const complex<D>& cplx);
+ /// Associated types.
+ /// \{
+ /// Element associated type.
+ typedef mln_site(super_) element;
+
/// Point_Site associated type.
typedef complex_psite<D, P> psite;
- /// Forward Point_Iterator associated type.
+ /// Forward Site_Iterator associated type.
typedef p_complex_fwd_piter_<D, P> fwd_piter;
- /// Backward Point_Iterator associated type.
+
+ /// Backward Site_Iterator associated type.
typedef p_complex_bkd_piter_<D, P> bkd_piter;
- /// \brief Return The number of points (sites) of the set, i.e., the
- /// number of \em faces.
+ /// Site_Iterator associated type.
+ typedef fwd_piter piter;
+ /// \}
+
+ /// \brief Return The number of sites of the set, i.e., the number
+ /// of \em faces.
///
- /// Required by the mln::Point_Set concept.
- std::size_t nsites() const;
+ /// (Required by the mln::Site_Set concept, since the property
+ /// trait::site_set::nsites::known of this site set is set to
+ /// `known'.)
+ /* FIXME: Return type should be std::size_t (see
+ mln/core/concept/site_set.hh). */
+ unsigned nsites() const;
/// Return The number of faces in the complex.
std::size_t nfaces() const;
- // FIXME: Add nfaces(unsigned) routines?
+ // FIXME: Add nfaces(unsigned) routines? Yes, if this can
+ // simplify (and lighten) the implementation of piters, psites,
+ // etc.
+ /// Is this site set valid?
+ bool is_valid() const;
+
+ /// Does this site set has \a p?
bool has(const psite& p) const;
+ // FIXME: Dummy.
+ std::size_t memory_size() const;
+
/// Accessors.
/// \{
/// Return the complex associated to the p_complex domain (const
@@ -106,9 +157,6 @@ namespace mln
/// Return the complex associated to the p_complex domain (mutable
/// version).
complex<D>& cplx();
-
- /// Give the exact bounding box.
- const box<P>& bbox() const;
/// \}
private:
@@ -129,8 +177,13 @@ namespace mln
similar to graphs, where vertex and edge handles (named `id's)
are not tied to a specific graph. */
mutable util::tracked_ptr< complex<D> > cplx_;
- // FIXME: Remove as soon as bbox become optional.
- box<P> bb_;
+
+ // FIXME: Remove as soon as the tracked_ptr is move into the
+ // complex itself.
+ template <unsigned D_, typename P_>
+ friend
+ bool operator==(const p_complex<D_, P_>& lhs,
+ const p_complex<D_, P_>& rhs);
};
@@ -164,16 +217,11 @@ namespace mln
// Create a deep, managed copy of CPLX.
: cplx_(new complex<D>(cplx))
{
- // FIXME: Dummy initialization.
- accu::bbox<P> a;
- for (unsigned i = 0; i < nsites(); ++i)
- a.take(P());
- bb_ = a.to_result();
}
template <unsigned D, typename P>
inline
- std::size_t
+ unsigned
p_complex<D, P>::nsites() const
{
return nfaces();
@@ -190,20 +238,40 @@ namespace mln
template <unsigned D, typename P>
inline
bool
+ p_complex<D, P>::is_valid() const
+ {
+ // FIXME: Might be too low-level, again.
+ return (cplx_.ptr_);
+ }
+
+ template <unsigned D, typename P>
+ inline
+ bool
p_complex<D, P>::has(const psite& p) const
{
+ mln_precondition(is_valid());
return
// Check whether P's complex is compatible with this pset's complex.
- &p.cplx() == &cplx() &&
+ (p.site_set() == *this) &&
// Check whether the complex has the face associated to P.
- p.face().is_valid();
+ (p.is_valid());
+ }
+
+ template <unsigned D, typename P>
+ inline
+ std::size_t
+ p_complex<D, P>::memory_size() const
+ {
+ // FIXME: Dummy; implement (see other site sets).
+ abort();
+ return 0;
}
template <unsigned D, typename P>
complex<D>&
p_complex<D, P>::cplx() const
{
- mln_precondition(cplx_);
+ mln_precondition(is_valid());
return *cplx_.ptr_;
}
@@ -211,24 +279,23 @@ namespace mln
complex<D>&
p_complex<D, P>::cplx()
{
- mln_precondition(cplx_);
+ mln_precondition(is_valid());
return *cplx_.ptr_;
}
- template <unsigned D, typename P>
- inline
- const box<P>&
- p_complex<D, P>::bbox() const
- {
- // FIXME: Dummy value.
- return bb_;
- }
+ /*--------------.
+ | Comparisons. |
+ `--------------*/
template <unsigned D, typename P>
bool
operator==(const p_complex<D, P>& lhs, const p_complex<D, P>& rhs)
{
+ /* FIXME: We should not rely on pointer equality here, as graph
+ will soon become shells using (shared) tracked pointers to
+ actual data. So, delegate the equality test to the graphs
+ themselves. */
return lhs.cplx_.ptr_ == rhs.cplx_.ptr_;
}
--
1.6.0.1
https://svn.lrde.epita.fr/svn/oln/branches/cleanup-2008/milena
Index: ChangeLog
from Nicolas Ballas <ballas(a)lrde.epita.fr>
Update median"".
* tests/level/median_.cc: New.
* mln/level/median.hh: .
* mln/win/rectangle2d.hh: .
mln/level/median.hh | 15 ++++++------
mln/win/rectangle2d.hh | 9 ++++---
tests/level/median_.cc | 59 +++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 73 insertions(+), 10 deletions(-)
Index: tests/level/median_.cc
--- tests/level/median_.cc (revision 0)
+++ tests/level/median_.cc (revision 0)
@@ -0,0 +1,59 @@
+// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory (LRDE)
+//
+// 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/level/median.cc
+ *
+ * \brief Test on mln::level::median.
+ */
+
+#include <mln/core/image/image2d.hh>
+#include <mln/win/rectangle2d.hh>
+
+#include <mln/io/pgm/load.hh>
+#include <mln/io/pgm/save.hh>
+
+#include <mln/value/int_u8.hh>
+#include <mln/level/median.hh>
+
+#include "tests/data.hh"
+
+
+int main()
+{
+ using namespace mln;
+ using value::int_u8;
+
+ win::rectangle2d rect(5, 5);
+ border::thickness = 6;
+
+ image2d<int_u8> lena;
+ io::pgm::load(lena, MLN_IMG_DIR "/lena.pgm");
+ image2d<int_u8> out(lena.domain());
+
+ level::impl::median_(lena, rect, out);
+ io::pgm::save(out, "out.pgm");
+}
Index: mln/level/median.hh
--- mln/level/median.hh (revision 2346)
+++ mln/level/median.hh (working copy)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007 EPITA Research and Development Laboratory
+// Copyright (C) 2007, 2008 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
@@ -98,7 +98,7 @@
struct median_t
{
typedef mln_psite(I) P;
- typedef mln_dpsite(I) D;
+ typedef mln_dpsite(P) D;
// i/o
@@ -108,10 +108,10 @@
// aux data
- accu::median_h<mln_vset(I)> med;
+ accu::median_h<mln_value(I)> med;
P p;
window<D> win_fp, win_fm, win_bp, win_bm, win_dp, win_dm;
- mln_qiter(W) q_fp, q_fm, q_bp, q_bm, q_dp, q_dm;
+ mln_qiter(window<D>) q_fp, q_fm, q_bp, q_bm, q_dp, q_dm;
// ctor
@@ -123,7 +123,7 @@
win(exact(win_)),
output(exact(output_)),
// aux data
- med(input.values_eligible()),
+ med(),
p(),
win_fp(set::diff(win, geom::shift(win, left))),
win_fm(set::diff(geom::shift(win, left), win)),
@@ -196,7 +196,7 @@
// aux data
mln_psite(I) p;
- accu::median_h<mln_vset(I)> med;
+ accu::median_h<mln_value(I)> med;
// ctor
inline
@@ -304,7 +304,8 @@
trace::entering("level::median_dir");
mlc_is(mln_trait_image_value_io(O), trait::image::value_io::read_write)::check();
- mlc_is(mln_trait_image_support(I), trait::image::support::aligned)::check();
+ mlc_is(mln_trait_image_localization(I),
+ trait::image::localization::basic_grid)::check();
mlc_converts_to(mln_value(I), mln_value(O))::check();
mln_precondition(exact(output).domain() == exact(input).domain());
Index: mln/win/rectangle2d.hh
--- mln/win/rectangle2d.hh (revision 2346)
+++ mln/win/rectangle2d.hh (working copy)
@@ -38,6 +38,7 @@
# include <mln/core/internal/window_base.hh>
# include <mln/core/internal/dpoints_base.hh>
# include <mln/core/alias/dpoint2d.hh>
+# include <mln/core/def/coord.hh>
namespace mln
@@ -131,9 +132,11 @@
width_(width)
{
mln_precondition(height % 2 == 1 && width % 2 == 1);
- const int drow = height / 2, dcol = width / 2;
- for (int row = - drow; row <= drow; ++row)
- for (int col = - dcol; col <= dcol; ++col)
+ const def::coord drow = (def::coord) (height / 2);
+ const def::coord dcol = (def::coord) (width / 2);
+
+ for (def::coord row = (def::coord) -drow; row <= drow; ++row)
+ for (def::coord col = (def::coord) -dcol; col <= dcol; ++col)
this->insert(dpoint2d(row, col));
}
URL: https://svn.lrde.epita.fr/svn/oln/branches/cleanup-2008/milena
ChangeLog:
2008-09-22 Guillaume Lazzara <z(a)lrde.epita.fr>
Update tutorial.
* tutorial.tex: Add sections about values and differences between
sites and psites.
---
tutorial.tex | 175 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 169 insertions(+), 6 deletions(-)
Index: branches/cleanup-2008/milena/doc/tutorial/tutorial.tex
===================================================================
--- branches/cleanup-2008/milena/doc/tutorial/tutorial.tex (revision 2345)
+++ branches/cleanup-2008/milena/doc/tutorial/tutorial.tex (revision 2346)
@@ -186,10 +186,10 @@
An image is composed both of:
\begin{itemize}
\item A function $$
-f : \left\{
+ima : \left\{
\begin{array}{lll}
Site &\rightarrow & Value \\
- p & \mapsto & v
+ p & \mapsto & ima(p)
\end{array}
\right.
$$
@@ -212,8 +212,31 @@
ici, site <=> Point2d
-[sample code]
+\section{About value, rvalue and lvalue}
+Image types provide a method to access values, namely "operator() const".
+Yet, its signature is NOT "value operator()(const site\& p) const"
+but "rvalue operator()(const psite\& p) const"
+
+For instance, with I being image2d$<$int\_u8$>$, we have :
+
+ I::value == int\_u8 but I::rvalue == const int\_u8\&
+
+so copying the value when the call "f(p)" returns is avoided.
+In that case, it is a low-level implementation issue that makes rvalue
+be different from value. In some other cases, the difference can be
+more fundamental. For instance, a proxy is returned so that some extra
+code is performed if this value is eventually read.
+
+Likewise, lvalue is also used as return type for methods such as "operator()".
+The difference is that lvalue allows the data to be modified.
+
+With I being image2d$<$int\_u8$>$, we have :
+
+ I::value == int\_u8 but I::lvalue == int\_u8\&
+
+
+\section{Sample code}
In order to create a 2D image, you have two possibilites:
\begin{lstlisting}[frame=single]
// which builds an empty image;
@@ -333,13 +356,14 @@
\end{itemize}
+
\subsection{Interface}
\begin{tabular}{|l|l|l|l|p{4cm}|}
\hline
Return Type & Name & Arguments & Const & Comments \\ \hline
-site\_set & domain & - & X - & \\ \hline
+I::pvset & domain & - & X - & \\ \hline
const Value\& & operator() & const point\& p & X & Used for reading. \\ \hline
Value\& & operator() & const point\& p & - & Used for writing. \\ \hline
const P\& & at & unsigned x,
@@ -349,7 +373,7 @@
bool & has & const Point\& p & X & \\ \hline
bool & has\_data & - & X & Returns true if the domain is defined. \\ \hline
site\_id & id & - & X & Return the Id of the underlying shared data. \\ \hline
-FIXME & destination & - & X & Value set of all the possible site values in this
+I::vset & destination & - & X & Value set of all the possible site values in this
Image. \\ \hline
site\_set & bbox & - & - & Returns the bounding box of the domain. \\ \hline
site\_set & bbox\_large & - & - & Returns the bouding box of the domain and the
@@ -368,9 +392,143 @@
+
+\chapter{Sites and psites}
+
+\section{Need for site}
+
+As we have seen before, an image is defined on a grid. It has associated
+data and a site set which defines the domain of the image on that grid.
+Usually, we need to access a value by its coordinates. With default images it
+can be done easily, at no cost.
+
+Example with an image2d:
+
+\begin{lstlisting}[frame=single]
+ c 0 1 2 3
+ r
+ +-+-+-+-+
+ 0 | |x| | |
+ +-+-+-+-+
+ 1 | | | | |
+ +-+-+-+-+
+\end{lstlisting}
+
+The site x is the point (0, 1). The image values are stored in a
+multi-dimensional array. The point coordinates can be used directly. The site
+(0, 1) \textbf{is} the point (0, 1) and the data is stored at row 0 and column
+1.
+
+Here we have:
+
+ I::site == I::psite == point2d
+
+where, roughly, point2d = \{ row, column \}.
+
+\section{Need for psite}
+
+Sometimes, accessing a value in constant-time complexity, O(1), is not
+possible with a site object.
+
+Let's have a small example. Define a function returning a value for a given
+point:
+
+\begin{lstlisting}[frame=single]
+ unsigned my_values(const point2d& p)
+ {
+ if (p.row() == 0)
+ return 8;
+ return 9;
+ }
+\end{lstlisting}
+So, for each point having (0, x) as coordinate, this function will return 8,
+otherwise it will be 9.
+
+Then, define a p\_array with few point2d:
+
+\begin{lstlisting}[frame=single]
+ p_array<point2d> arr;
+ arr.append(point2d(3, 6));
+ arr.append(point2d(3, 7));
+ arr.append(point2d(3, 8));
+ arr.append(point2d(4, 8));
+ arr.append(point2d(4, 9));
+\end{lstlisting}
+
+Now, create a point-wise image from this function and this p\_array:
+\begin{lstlisting}[frame=single]
+ mln_VAR(ima, my_values | arr);
+\end{lstlisting}
+
+Ima is actually that image:
+\begin{lstlisting}[frame=single]
+ c 6 7 8 9
+ r
+ +-+-+-+
+ 3 | |x| |
+ +-+-+-+-+
+ 4 | | |
+ +-+-+
+\end{lstlisting}
+
+However, in memory, since it is based on a p\_array, values are stored in a
+vector.
+
+The site x is the point (3, 7). The image values are stored in a
+vector where the index is the offset of the cell from the beginning of the
+vector. The site x thus corresponds to the cell 1.
+
+
+\begin{lstlisting}[frame=single]
+arr[] = 0 1 2 3 4
+ +-+-+-+-+-+
+ | |x| | | |
+ +-+-+-+-+-+
+\end{lstlisting}
+
+Obviously, from the site coordinates, we cannot access the associated data in
+constant-time. That's why we need a different mechanism in order to access
+this data: the psites.
+
+Here we have:
+
+ I::site == point2d but I::psite == pseudo\_site$<$point2d$>$
+
+where, roughly, pseudo\_site$<$point2d$>$ = \{ i\_in\_p\_array, p\_array\_ptr
+\}.
+
+Psites contains all the needed information to access the values in
+constant-time.
+
+\section{From psite to site}
+
+In the last example there was an image of type I such as I::site != I::psite.
+In that case, an object of type I::psite is actually convertible towards an
+object of type I::site. Furthermore, a psite shall behave as if it was a
+site.
+
+Design note: it seems impossible to offer through the interface of
+some psite what is expected from its corresponding site. For instance, when a
+site has a given feature, say a method "m", then this
+method has to appear in the psite interface. However, thanks to
+inheritance, we fetch an interface and an implementation that delegates
+to the site.
+
+For instance, in the last example, I::psite has a method ::row() because
+I::site, point2d, provides such a method.
+
+How it works: a psite inherits from internal::site\_impl$<$site$>$ which is
+specialized for every site type; for instance, internal::site\_impl$<$point2d$>$
+owns the method "coord row() const" which is defined as
+"return exact(this)->to\_site().row()"
+
+
\chapter{Iterators}
Each container object in Olena like site sets or images have iterators.
+The iteration mechanism for images is directly derived from the mechanism
+for site set.
+
There are usually three kinds:
\begin{itemize}
\item \textbf{fwd\_iter}, depends on the container,
@@ -378,6 +536,10 @@
\item \textbf{iter}, usually the same as fwd\_iter. It is guaranteed to
iterate all over the elements.
\end{itemize}
+Every iterable object have these three kinds of iterator. There are all
+bidirectional containers.
+Whatever the iterator used, the basic iterator has the only property of
+browsing every site once.
The iterator type name depends on the data pointed by it: \\
@@ -700,6 +862,7 @@
}
\end{lstlisting}
+
\chapter{Graphes and images}
\section{Description}
Olena enables the possibility of using graphes with images.
@@ -875,6 +1038,6 @@
}
\end{lstlisting}
-//FIXME talk about p_vertices and p_edges.
+//FIXME talk about p\_vertices and p\_edges.
\end{document}
\ No newline at end of file
URL: https://svn.lrde.epita.fr/svn/oln/branches/cleanup-2008/milena
ChangeLog:
2008-09-22 Matthieu Garrigues <garrigues(a)lrde.epita.fr>
Add snake_vert browsing canvas.
* mln/canvas/browsing/snake_vert.hh: New, snake vert browsing
canvas. This canvas browse all the point of an image 'input' like
this :
1 4 5
|| /\ ||
|| || ||
\/ || \/
2 3 6
* tests/canvas/browsing/Makefile.am: Add snake_vert test.
* tests/canvas/browsing/snake_vert.cc: New. The test.
* mln/canvas/browsing/snake_fwd.hh: Desactivate check
of dimension.
---
mln/canvas/browsing/snake_fwd.hh | 8 +
mln/canvas/browsing/snake_vert.hh | 166 ++++++++++++++++++++++++++++++++++++
tests/canvas/browsing/Makefile.am | 2
tests/canvas/browsing/snake_vert.cc | 96 ++++++++++++++++++++
4 files changed, 269 insertions(+), 3 deletions(-)
Index: branches/cleanup-2008/milena/tests/canvas/browsing/snake_vert.cc
===================================================================
--- branches/cleanup-2008/milena/tests/canvas/browsing/snake_vert.cc (revision 0)
+++ branches/cleanup-2008/milena/tests/canvas/browsing/snake_vert.cc (revision 2344)
@@ -0,0 +1,96 @@
+// 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/canvas/browsing/snake_vert.cc
+ *
+ * \brief Tests on mln::canvas::browsing::snake_vert.
+ */
+
+#include <mln/core/image/image2d.hh>
+#include <mln/canvas/browsing/snake_vert.hh>
+#include <mln/fun/p2v/iota.hh>
+#include <mln/debug/println.hh>
+
+// FIXME: Move code below into mln/canvas/browsing/iota.hh.
+
+
+template <typename I, typename F>
+struct assign_browsing_functor
+{
+ enum { dim = I::site::dim };
+
+
+ I input;
+ F f;
+
+ assign_browsing_functor(I& input, F f = F())
+ : input(input),
+ f(f)
+ {}
+
+ mln_psite(I) p;
+
+ void init() {}
+ void final() {}
+ void next()
+ {
+ input(p) = f(p);
+// mln_assertion(input(p) - 1 == p[0] * input.domain().ncols()
+// + ( (p[0] % 2) ? input.domain().ncols() - 1 - p[1] : p[1]));
+ }
+ void fwd() { next(); }
+ void up() { next(); }
+ void down() { next(); }
+};
+
+namespace mln
+{
+
+ template <typename I, typename F, typename B>
+ void my_test(Image<I>& ima_,
+ const Function_p2v<F>& f_,
+ const Browsing<B>& browse_)
+ {
+ I& ima = exact(ima_);
+ const F& f = exact(f_);
+ const B& browse = exact(browse_);
+
+ assign_browsing_functor<I, F> fun(ima, f);
+ browse(fun);
+ }
+
+}
+
+
+int main()
+{
+ using namespace mln;
+ image2d<unsigned> ima2(2, 7);
+
+ my_test(ima2, fun::p2v::iota, canvas::browsing::snake_vert);
+ debug::println(ima2);
+}
Index: branches/cleanup-2008/milena/tests/canvas/browsing/Makefile.am
===================================================================
--- branches/cleanup-2008/milena/tests/canvas/browsing/Makefile.am (revision 2343)
+++ branches/cleanup-2008/milena/tests/canvas/browsing/Makefile.am (revision 2344)
@@ -5,11 +5,13 @@
check_PROGRAMS = \
fwd \
snake_fwd \
+ snake_vert \
directional \
dir_struct_elt_incr_update
fwd_SOURCES = fwd.cc
snake_fwd_SOURCES = snake_fwd.cc
+snake_vert_SOURCES = snake_vert.cc
directional_SOURCES = directional.cc
dir_struct_elt_incr_update_SOURCES = dir_struct_elt_incr_update.cc
Index: branches/cleanup-2008/milena/mln/canvas/browsing/snake_fwd.hh
===================================================================
--- branches/cleanup-2008/milena/mln/canvas/browsing/snake_fwd.hh (revision 2343)
+++ branches/cleanup-2008/milena/mln/canvas/browsing/snake_fwd.hh (revision 2344)
@@ -101,7 +101,9 @@
void
snake_fwd_t::operator()(F& f) const
{
- // FIXME: Check the dimension (2D) or generalize.
+ // Fixme: check the dimension of the input
+// mlc_equal(mln_trait_image_dimension(I)(),
+// trait::image::dimension::two_d)::check();
trace::entering("canvas::browsing::snake_fwd");
mln_precondition(f.input.has_data());
int
@@ -141,9 +143,9 @@
while (col > min_col)
{
--col;
- trace::entering("canvas::browsing::snake_fwd");
+ trace::entering("canvas::browsing::snake_fwd::bkd");
f.bkd();
- trace::exiting("canvas::browsing::snake_fwd");
+ trace::exiting("canvas::browsing::snake_fwd::bkd");
}
// change browsing
Index: branches/cleanup-2008/milena/mln/canvas/browsing/snake_vert.hh
===================================================================
--- branches/cleanup-2008/milena/mln/canvas/browsing/snake_vert.hh (revision 0)
+++ branches/cleanup-2008/milena/mln/canvas/browsing/snake_vert.hh (revision 2344)
@@ -0,0 +1,166 @@
+// 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_CANVAS_BROWSING_SNAKE_VERT_HH
+# define MLN_CANVAS_BROWSING_SNAKE_VERT_HH
+
+/*! \file mln/canvas/browsing/snake_vert.hh
+ *
+ * \brief Browsing in a snake-way, forward.
+ */
+
+# include <mln/core/concept/browsing.hh>
+# include <mln/geom/size2d.hh>
+
+
+namespace mln
+{
+
+ namespace canvas
+ {
+
+ namespace browsing
+ {
+
+ /*!
+ * \brief Browsing in a snake-way, forward.
+ *
+ * This canvas browse all the point of an image 'input' like
+ * this :
+ *
+ * | /\ |
+ * | | |
+ * \/ | \/
+ *
+ * The fonctor should provide (In addition to 'input') four
+ * methods :
+ *
+ * - init() : Will be called at the beginning.
+ * - down() : Will be called after each moving down.
+ * - up() : Will ba called after each moving up.
+ * - fwd() : Will be called after each moving right. (will
+ * also be called once at the first point).
+ *
+ * This methods should acces to the current working point 'p'
+ * also provided by the functor.
+ *
+ * Warning: This canvas works only on 2D.
+ *
+ * F shall feature: \n
+ * { \n
+ * --- as attributes: \n
+ * input; \n
+ * p; \n
+ * --- as methods: \n
+ * void init(); \n
+ * void down(); \n
+ * void up(); \n
+ * void fwd(); \n
+ * } \n
+ *
+ */
+
+ struct snake_vert_t : public Browsing< snake_vert_t >
+ {
+ template <typename F>
+ void operator()(F& f) const;
+ }
+
+ snake_vert;
+
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ template <typename F>
+ inline
+ void
+ snake_vert_t::operator()(F& f) const
+ {
+ // Fixme: check the dimension of the input
+// mlc_equal(mln_trait_image_dimension(I)(),
+// trait::image::dimension::two_d)::check();
+ trace::entering("canvas::browsing::snake_vert");
+ mln_precondition(f.input.has_data());
+ int
+ min_row = geom::min_row(f.input), max_row = geom::max_row(f.input),
+ min_col = geom::min_col(f.input), max_col = geom::max_col(f.input);
+
+ // p
+ f.p = f.input.bbox().pmin();
+ def::coord& row = f.p.row();
+ def::coord& col = f.p.col();
+
+ // initialization
+ trace::entering("canvas::browsing::snake_vert::init");
+ f.init();
+ trace::exiting("canvas::browsing::snake_vert::init");
+
+ bool down = true;
+ for (col = min_col; col <= max_col; ++col)
+ // FIXME: Add "if (f.input.has(p))"?
+ {
+ // go fwd
+ trace::entering("canvas::browsing::snake_vert::init");
+ f.fwd();
+ trace::exiting("canvas::browsing::snake_vert::init");
+
+ if (down)
+ // browse col down.
+ while (row < max_row)
+ {
+ ++row;
+ trace::entering("canvas::browsing::snake_vert::down");
+ f.down();
+ trace::exiting("canvas::browsing::snake_vert::down");
+ }
+ else
+ // browse col up.
+ while (row > min_row)
+ {
+ --row;
+ trace::entering("canvas::browsing::snake_vert::up");
+ f.up();
+ trace::exiting("canvas::browsing::snake_vert::up");
+ }
+
+ // change browsing
+ down = ! down;
+ }
+ trace::exiting("canvas::browsing::snake_vert");
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::canvas::browsing
+
+ } // end of namespace mln::canvas
+
+} // end of namespace mln
+
+
+#endif // ! MLN_CANVAS_BROWSING_SNAKE_VERT_HH