Olena-patches
Threads by month
- ----- 2025 -----
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- 9625 discussions
Re: [Olena-patches] [Olena] #7: Miscellaneous tasks related to the Olena 1.0 release process
by Olena 02 May '08
by Olena 02 May '08
02 May '08
#7: Miscellaneous tasks related to the Olena 1.0 release process
-----------------------+----------------------------------------------------
Reporter: levill_r | Owner: levill_r
Type: task | Status: new
Priority: major | Milestone: Olena 1.0
Component: other | Version: 1.0
Resolution: | Keywords: release NEWS dates copyright headers sandbox
-----------------------+----------------------------------------------------
Old description:
> To do before the release:
> * move away any information about sandboxes (as they won't be
> distributed):
> * create a !ChangeLog in source:trunk/milena/sandbox, or several
> !ChangeLogs in subdirectories;
> * move information from source:trunk/milena/ChangeLog to this (these)
> file(s);
> * warn the Olena Team about these changes, and have them document
> changes in the right place;
> * update `NEWS` (see the similar task for Olena 0.10a/0.11: #8);
> * update `AUTHORS`;
> * ensure all copyright headers are sound (using Benoît Sigoure's
> `gplize.sh` script, or a variant of it);
> * use Vaucanson' `reheader` script to fix broken headers.
>
> Split this ticket in several parts if the tasks are either too big or too
> numerous.
New description:
To do before the release:
* use Benoît Sigoure's set of Autoconf macros to check for some Boost
libraries (e.g., the BGL). See also #138;
* move away any information about sandboxes (as they won't be
distributed):
* create a !ChangeLog in source:trunk/milena/sandbox, or several
!ChangeLogs in subdirectories;
* move information from source:trunk/milena/ChangeLog to this (these)
file(s);
* warn the Olena Team about these changes, and have them document
changes in the right place;
* update `NEWS` (see the similar task for Olena 0.10a/0.11: #8);
* update `AUTHORS`;
* ensure all copyright headers are sound (using Benoît Sigoure's
`gplize.sh` script, or a variant of it);
* use Vaucanson' `reheader` script to fix broken headers.
Split this ticket in several parts if the tasks are either too big or too
numerous.
Comment (by levill_r):
Add Tsuna's boost.m4 to the to do list.
--
Ticket URL: <https://trac.lrde.org/olena/ticket/7#comment:9>
Olena <http://olena.lrde.epita.fr>
Olena, a generic and efficient C++ image processing library.
1
0
Re: [Olena-patches] [Olena] #7: Miscellaneous tasks related to the Olena 1.0 release process
by Olena 02 May '08
by Olena 02 May '08
02 May '08
#7: Miscellaneous tasks related to the Olena 1.0 release process
-----------------------+----------------------------------------------------
Reporter: levill_r | Owner: levill_r
Type: task | Status: new
Priority: major | Milestone: Olena 1.0
Component: other | Version: 1.0
Resolution: | Keywords: release NEWS dates copyright headers sandbox
-----------------------+----------------------------------------------------
Changes (by levill_r):
* keywords: release NEWS dates copyright headers => release NEWS dates
copyright headers sandbox
* priority: trivial => major
Old description:
> To do before the release
> * update `NEWS` (see the similar task for Olena 0.10a/0.11: #8);
> * update `AUTHORS`;
> * ensure all copyright headers are sound (using Benoît Sigoure's
> `gplize.sh` script, or a variant of it);
> * use Vaucanson' `reheader` script to fix broken headers.
>
> Split this ticket in several parts if the tasks are either too big or too
> numerous.
New description:
To do before the release:
* move away any information about sandboxes (as they won't be
distributed):
* create a !ChangeLog in source:trunk/milena/sandbox, or several
!ChangeLogs in subdirectories;
* move information from source:trunk/milena/ChangeLog to this (these)
file(s);
* warn the Olena Team about these changes, and have them document
changes in the right place;
* update `NEWS` (see the similar task for Olena 0.10a/0.11: #8);
* update `AUTHORS`;
* ensure all copyright headers are sound (using Benoît Sigoure's
`gplize.sh` script, or a variant of it);
* use Vaucanson' `reheader` script to fix broken headers.
Split this ticket in several parts if the tasks are either too big or too
numerous.
Comment:
Mention the case of sandboxes.
--
Ticket URL: <https://trac.lrde.org/olena/ticket/7#comment:8>
Olena <http://olena.lrde.epita.fr>
Olena, a generic and efficient C++ image processing library.
1
0
https://svn.lrde.epita.fr/svn/oln/trunk/milena
Index: ChangeLog
from Roland Levillain <roland(a)lrde.epita.fr>
Add adjaceny tests for mln::p_line_graph.
* mln/core/p_line_graph.hh
(mln::p_line_graph<P>::adjacent)
(mln::p_line_graph<P>::adjacent_or_equal):
New methods.
(mln::p_line_graph<P>::p_line_graph): Remove outdated FIXME.
* mln/core/p_graph.hh: Improve documentation.
(mln::p_graph<P>::p_graph): Remove outdated FIXME.
* tests/core/graph_image.cc, tests/core/line_graph_image.cc:
Exercise adjacency tests.
* tests/core/line_graph_elt_neighborhood.cc,
* tests/core/line_graph_elt_window.cc:
Typos in documentation.
* tests/core/graph_elt_neighborhood.cc,
* tests/core/graph_elt_window.cc:
Aesthetic changes.
mln/core/p_graph.hh | 22 ++++----
mln/core/p_line_graph.hh | 81 +++++++++++++++++++++++++++++-
tests/core/graph_elt_neighborhood.cc | 6 --
tests/core/graph_elt_window.cc | 6 --
tests/core/graph_image.cc | 29 +++++++++-
tests/core/line_graph_elt_neighborhood.cc | 9 +--
tests/core/line_graph_elt_window.cc | 9 +--
tests/core/line_graph_image.cc | 26 ++++++++-
8 files changed, 149 insertions(+), 39 deletions(-)
Index: mln/core/p_line_graph.hh
--- mln/core/p_line_graph.hh (revision 1911)
+++ mln/core/p_line_graph.hh (working copy)
@@ -89,6 +89,22 @@
bool has(const psite& p) const;
+ /// Adjacency tests.
+ /// \{
+ /// Return true if the psites \a lhs and \a rhs are adjacent.
+ /// (If \a lhs and \a rhs are equal, return false).
+ bool adjacent(const psite& lhs, const psite& rhs) const;
+ /// Return true if the edges \a lhs and \a rhs are adjacent.
+ /// (If \a lhs and \a rhs are equal, return false).
+ bool adjacent(const util::edge_id& lhs, const util::edge_id& rhs) const;
+
+ /// Return true if the psites \a lhs and \a rhs are adjacent, or equal.
+ bool adjacent_or_equal(const psite& lhs, const psite& rhs) const;
+ /// Return true if the edges \a lhs and \a rhs are adjacent, or equal
+ bool adjacent_or_equal(const util::edge_id& lhs,
+ const util::edge_id& rhs) const;
+ /// \}
+
// FIXME: Should be private.
util::tracked_ptr<graph> gr_;
// FIXME: (Roland) Is it really useful/needed?
@@ -125,10 +141,9 @@
template<typename P>
inline
p_line_graph<P>::p_line_graph (const util::graph<P>& gr)
+ // Create a deep, managed copy of GR.
: gr_ (new util::graph<P>(gr))
{
- // FIXME: Warning: if the underlying graph is updated later, this
- // won't be taken into account by this p_line_graph!
accu::bbox<P> a;
for (unsigned i = 0; i < nnodes(); ++i)
a.take(gr_->node_data(i));
@@ -179,6 +194,68 @@
(p.id() < gr_->nedges());
}
+ template <typename P>
+ inline
+ bool
+ p_line_graph<P>::adjacent(const psite& lhs, const psite& rhs) const
+ {
+ mln_assertion(&lhs.plg() == this && rhs.plg() == this);
+ return adjacent(lhs.id(), rhs.id());
+ }
+
+ /* FIXME: This could be more efficient, if the graph structure had a
+ richer interface. */
+ template <typename P>
+ inline
+ bool
+ p_line_graph<P>::adjacent(const util::edge_id& lhs,
+ const util::edge_id& rhs) const
+ {
+ mln_assertion(lhs < this->npoints());
+ mln_assertion(rhs < this->npoints());
+
+ // Ensure LHS and RHS are *not* equal.
+ if (lhs == rhs)
+ return false;
+
+ // Check whether LHS and RHS are adjacent (i.e., whether LHS and
+ // RHS share a common vertex.
+ /* FIXME: This is too low-level. Yet another service the graph
+ should provide. */
+ if (gr_->edge(lhs).n1() == gr_->edge(rhs).n1() ||
+ gr_->edge(lhs).n1() == gr_->edge(rhs).n2() ||
+ gr_->edge(lhs).n2() == gr_->edge(rhs).n1() ||
+ gr_->edge(lhs).n2() == gr_->edge(rhs).n2())
+ return true;
+
+ return false;
+ }
+
+ template <typename P>
+ inline
+ bool
+ p_line_graph<P>::adjacent_or_equal(const psite& lhs, const psite& rhs) const
+ {
+ mln_assertion(&lhs.pg() == this && rhs.pg() == this);
+ return adjacent_or_equal(lhs.id(), rhs.id());
+ }
+
+ template <typename P>
+ inline
+ bool
+ p_line_graph<P>::adjacent_or_equal(const util::edge_id& lhs,
+ const util::edge_id& rhs) const
+ {
+ mln_assertion(lhs < this->npoints());
+ mln_assertion(rhs < this->npoints());
+
+ // Check whether LHS and RHS are equal.
+ if (lhs == rhs)
+ return true;
+ // Check whether RHS and LHS are adjacent.
+ return adjacent(lhs, rhs);
+ }
+
template <typename P>
bool
Index: mln/core/p_graph.hh
--- mln/core/p_graph.hh (revision 1911)
+++ mln/core/p_graph.hh (working copy)
@@ -96,14 +96,16 @@
/// Adjacency tests.
/// \{
- /// Return true if the psites lhs and rhs are adjacent.
+ /// Return true if the psites \a lhs and \a rhs are adjacent.
+ /// (If \a lhs and \a rhs are equal, return false).
bool adjacent(const psite& lhs, const psite& rhs) const;
- /// Return true if the nodes lhs and rhs are adjacent.
+ /// Return true if the nodes \a lhs and \a rhs are adjacent.
+ /// (If \a lhs and \a rhs are equal, return false).
bool adjacent(const util::node_id& lhs, const util::node_id& rhs) const;
- /// Return true if the psites lhs and rhs are adjacent, or equal.
+ /// Return true if the psites \a lhs and \a rhs are adjacent, or equal.
bool adjacent_or_equal(const psite& lhs, const psite& rhs) const;
- /// Return true if the nodes lhs and rhs are adjacent, or equal
+ /// Return true if the nodes \a lhs and \a rhs are adjacent, or equal
bool adjacent_or_equal(const util::node_id& lhs,
const util::node_id& rhs) const;
/// \}
@@ -151,10 +153,9 @@
template<typename P>
inline
p_graph<P>::p_graph (const util::graph<P>& gr)
+ // Create a deep, managed copy of GR.
: gr_ (new util::graph<P>(gr))
{
- // FIXME: Warning: if the underlying graph is updated later, this
- // won't be taken into account by this p_graph!
accu::bbox<P> a;
for (unsigned i = 0; i < npoints(); ++i)
a.take(gr_->node_data(i));
@@ -258,7 +259,8 @@
// Ensure LHS and RHS are *not* equal.
if (rhs == lhs)
return false;
- // Check whether RHS and LHS are adjacent (i.e., whether RHS is
+
+ // Check whether LHS and RHS are adjacent (i.e., whether RHS is
// among the neighbors of LHS).
typedef std::vector<util::edge_id> edges_t;
const edges_t& lhs_neighbs = gr_->nodes()[lhs]->edges;
@@ -290,10 +292,10 @@
mln_assertion(rhs < this->npoints());
// Check whether LHS and RHS are equal.
- if (rhs == lhs)
+ if (lhs == rhs)
return true;
- // Check whether RHS and LHS are adjacent.
- return adjacent(rhs, lhs);
+ // Check whether LHS and RHS are adjacent.
+ return adjacent(lhs, rhs);
}
template <typename P>
Index: tests/core/graph_image.cc
--- tests/core/graph_image.cc (revision 1911)
+++ tests/core/graph_image.cc (working copy)
@@ -50,6 +50,19 @@
| Graph. |
`--------*/
+ /* The graph is as follows:
+
+ 0 1 2 3 4
+ .-----------
+ |
+ 0 | 0 2
+ 1 | \ / |
+ 2 | 1 |
+ 3 | \ |
+ 4 | 3-4
+
+ */
+
// Points associated to nodes.
std::vector<point2d> points;
points.push_back(make::point2d(0,0)); // Point associated to node 0.
@@ -70,12 +83,20 @@
g.add_edge(3, 4);
g.add_edge(4, 2);
- /*-------.
- | Graph. |
- `-------*/
+ g.print_debug(std::cout);
+
+ /*----------------------.
+ | Graph image support. |
+ `----------------------*/
p_graph<point2d> pg(g);
- g.print_debug(std::cout);
+
+ // Check adjacencies of vertex 1.
+ mln_assertion( pg.adjacent(1, 0));
+ mln_assertion(!pg.adjacent(1, 1));
+ mln_assertion( pg.adjacent(1, 2));
+ mln_assertion( pg.adjacent(1, 3));
+ mln_assertion(!pg.adjacent(1, 4));
/*-------------.
| Graph image. |
Index: tests/core/line_graph_image.cc
--- tests/core/line_graph_image.cc (revision 1911)
+++ tests/core/line_graph_image.cc (working copy)
@@ -50,6 +50,19 @@
| Graph. |
`--------*/
+ /* The graph and its corresponding line graph are as follows:
+
+ 0 1 2 3 4 0 1 2 3 4
+ .----------- .-----------
+ | |
+ 0 | 0 2 0 | * *
+ 1 | \ / | 1 | 0 1 |
+ 2 | 1 | 2 | * 4
+ 3 | \ | 3 | 2 |
+ 4 | 3-4 4 | *3*
+
+ */
+
// Points associated to nodes.
std::vector<point2d> points;
points.push_back(make::point2d(0,0)); // Point associated to node 0.
@@ -70,12 +83,19 @@
g.add_edge(3, 4);
g.add_edge(4, 2);
- /*-------.
- | Graph. |
- `-------*/
+ /*---------------------------.
+ | Line graph image support. |
+ `---------------------------*/
p_line_graph<point2d> plg(g);
+ // Check adjacencies of edge 1.
+ mln_assertion( plg.adjacent(1, 0));
+ mln_assertion(!plg.adjacent(1, 1));
+ mln_assertion( plg.adjacent(1, 2));
+ mln_assertion(!plg.adjacent(1, 3));
+ mln_assertion( plg.adjacent(1, 4));
+
/*-------------------.
| Line graph image. |
`-------------------*/
Index: tests/core/line_graph_elt_neighborhood.cc
--- tests/core/line_graph_elt_neighborhood.cc (revision 1911)
+++ tests/core/line_graph_elt_neighborhood.cc (working copy)
@@ -25,10 +25,8 @@
// reasons why the executable file might be covered by the GNU General
// Public License.
-/*! \file tests/core/line_graph_elt_neighborhood.cc
- *
- * \brief Tests on mln::line_graph_elt_neighborhood.
- */
+/// \file tests/core/line_graph_elt_neighborhood.cc
+/// \brief Tests on mln::line_graph_elt_neighborhood.
#include <vector>
@@ -49,8 +47,7 @@
| Graph. |
`--------*/
- /* The graph is as follows and its corresponding line graph are as
- follows:
+ /* The graph and its corresponding line graph are as follows:
0 1 2 3 4 0 1 2 3 4
.----------- .-----------
Index: tests/core/line_graph_elt_window.cc
--- tests/core/line_graph_elt_window.cc (revision 1911)
+++ tests/core/line_graph_elt_window.cc (working copy)
@@ -25,10 +25,8 @@
// reasons why the executable file might be covered by the GNU General
// Public License.
-/*! \file tests/core/line_graph_elt_window.cc
- *
- * \brief Tests on mln::line_graph_elt_window.
- */
+/// \file tests/core/line_graph_elt_window.cc
+/// \brief Tests on mln::line_graph_elt_window.
#include <vector>
@@ -49,8 +47,7 @@
| Graph. |
`--------*/
- /* The graph is as follows and its corresponding line graph are as
- follows:
+ /* The graph and its corresponding line graph are as follows:
0 1 2 3 4 0 1 2 3 4
.----------- .-----------
Index: tests/core/graph_elt_neighborhood.cc
--- tests/core/graph_elt_neighborhood.cc (revision 1911)
+++ tests/core/graph_elt_neighborhood.cc (working copy)
@@ -25,10 +25,8 @@
// reasons why the executable file might be covered by the GNU General
// Public License.
-/*! \file tests/core/graph_elt_neighborhood.cc
- *
- * \brief Tests on mln::graph_elt_neighborhood.
- */
+/// \file tests/core/graph_elt_neighborhood.cc
+/// \brief Tests on mln::graph_elt_neighborhood.
#include <iostream>
Index: tests/core/graph_elt_window.cc
--- tests/core/graph_elt_window.cc (revision 1911)
+++ tests/core/graph_elt_window.cc (working copy)
@@ -25,10 +25,8 @@
// reasons why the executable file might be covered by the GNU General
// Public License.
-/*! \file tests/core/graph_elt_window.cc
- *
- * \brief Tests on mln::graph_elt_window.
- */
+/// \file tests/core/graph_elt_window.cc
+/// \brief Tests on mln::graph_elt_window.
#include <iostream>
1
0
https://svn.lrde.epita.fr/svn/oln/trunk/milena
Index: ChangeLog
from Roland Levillain <roland(a)lrde.epita.fr>
Overhaul 1-D, 2-D and 3-D pixters.
* mln/core/macros.hh (mln_bkd_pixter_): New macro.
* mln/core/internal/pixel_iterator_base.hh
(mln::pixel_iterator_base_<I, E>::start)
(mln::pixel_iterator_base_<I, E>::invalidate)
(mln::pixel_iterator_base_<I, E>::is_valid):
Remove methods.
(mln::forward_pixel_iterator_base_<I, E>)
(mln::backward_pixel_iterator_base_<I, E>):
New classes.
* mln/core/pixter1d.hh
(mln::fwd_pixter1d<I>): Inherit from
mln::internal::forward_pixel_iterator_base_.
(mln::bkd_pixter1d<I>): New class.
* mln/core/pixter2d.hh
(mln::fwd_pixter2d<I>): Inherit from
mln::internal::forward_pixel_iterator_base_.
(mln::bkd_pixter2d<I>): Inherit from
mln::internal::backward_pixel_iterator_base_.
(mln::bkd_pixter2d<I>::start): Remove method.
(mln::fwd_pixter2d<I>::fwd_pixter2d)
(mln::bkd_pixter2d<I>::bkd_pixter2d):
Use initialization lists instead of assignments.
* mln/core/pixter3d.hh
(mln::fwd_pixter3d<I>): Inherit from
mln::internal::forward_pixel_iterator_base_.
(mln::bkd_pixter3d<I>): New class.
* mln/core/p_image2d_pixter.hh
(mln::p_image2d_fwd_pixter<P>): Inherit from
mln::internal::forward_pixel_iterator_base_.
(mln::p_image2d_bkd_pixter<P>): Inherit from
mln::internal::backward_pixel_iterator_base_.
* mln/core/image1d.hh (mln::trait::bkd_pixter< image1d<T> >::ret):
Set to bkd_pixter1d< const image1d<T> >.
* mln/core/image2d.hh: Add FIXMEs.
* mln/core/image3d.hh (mln::trait::bkd_pixter< image3d<T> >::ret):
Set to bkd_pixter3d< const image3d<T> >.
* tests/core/pixter1d.cc, tests/core/pixter2d.cc:
New tests.
* tests/core/image3d.cc: Rename as...
* tests/core/pixter3d.cc: ...this.
Exercise bkd_pixter3d.
* tests/core/Makefile.am (check_PROGRAMS): Remove image3d.
Add pixter1d, pixter2d and pixter3d.
(image3d_SOURCES): Remove.
(pixter1d_SOURCES, pixter2d_SOURCES, pixter3d_SOURCES): New.
mln/core/image1d.hh | 5 -
mln/core/image2d.hh | 2
mln/core/image3d.hh | 5 -
mln/core/internal/pixel_iterator_base.hh | 142 +++++++++++++++++++++++++------
mln/core/macros.hh | 2
mln/core/p_image2d_pixter.hh | 131 +++++++++++++++-------------
mln/core/pixter1d.hh | 81 +++++++++++++----
mln/core/pixter2d.hh | 88 ++++++++-----------
mln/core/pixter3d.hh | 118 +++++++++++++++++++++----
tests/core/Makefile.am | 8 +
tests/core/pixter1d.cc | 86 ++++++++++++++++++
tests/core/pixter2d.cc | 85 ++++++++++++++++++
tests/core/pixter3d.cc | 31 ++++--
13 files changed, 596 insertions(+), 188 deletions(-)
Index: mln/core/macros.hh
--- mln/core/macros.hh (revision 1910)
+++ mln/core/macros.hh (working copy)
@@ -286,6 +286,8 @@
# define mln_fwd_pixter_(I) mln::trait::fwd_pixter< I >::ret
# define mln_bkd_pixter(I) typename mln::trait::bkd_pixter< I >::ret
+# define mln_bkd_pixter_(I) mln::trait::bkd_pixter< I >::ret
+
# define mln_pixter(I) mln_fwd_pixter(I)
# define mln_pixter_(I) mln_fwd_pixter_(I)
Index: mln/core/internal/pixel_iterator_base.hh
--- mln/core/internal/pixel_iterator_base.hh (revision 1910)
+++ mln/core/internal/pixel_iterator_base.hh (working copy)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007 EPITA Research and Development Laboratory
+// 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
@@ -28,58 +28,102 @@
#ifndef MLN_CORE_INTERNAL_PIXEL_ITERATOR_BASE_HH
# define MLN_CORE_INTERNAL_PIXEL_ITERATOR_BASE_HH
-/*! \file mln/core/internal/pixel_iterator_base.hh
- *
- * \brief Base class to factor code for pixel iterator classes.
- */
+/// \file mln/core/internal/pixel_iterator_base.hh
+/// \brief Base classes factoring code for pixel iterator classes.
# include <mln/core/concept/pixel_iterator.hh>
# include <mln/core/internal/pixel_impl.hh>
# include <mln/core/trait/qlf_value.hh>
-
namespace mln
{
namespace internal
{
+ /*---------------------------------------.
+ | internal::pixel_iterator_base_<I, E>. |
+ `---------------------------------------*/
- /*! \internal A base class for pixel iterators.
- *
- */
+ /// \internal A base class for pixel iterators.
template <typename I, typename E>
class pixel_iterator_base_ : public Pixel_Iterator<E>,
public internal::pixel_impl_<I, E>
{
typedef internal::pixel_impl_<I, E> super_;
- public:
+ protected:
+ /// Constructor.
+ pixel_iterator_base_(I& image);
+ protected:
+ /// Beginning of the image.
+ mln_qlf_value(I)* boi_;
+ /// End of the image (past-the-end).
+ mln_qlf_value(I)* eoi_;
+ };
+
+
+ /*-----------------------------------------------.
+ | internal::forward_pixel_iterator_base_<I, E>. |
+ `-----------------------------------------------*/
+
+ /// \internal A base class for forward pixel iterators.
+ template <typename I, typename E>
+ class forward_pixel_iterator_base_ : public pixel_iterator_base_<I, E>
+ {
+ typedef pixel_iterator_base_<I, E> super_;
+
+ public:
+ /// Manipulation
+ /// \{
/// Start an iteration.
void start();
-
/// Invalidate the iterator.
void invalidate();
-
/// Test if the iterator is valid.
bool is_valid() const;
+ /// \}
protected:
+ /// Constructor.
+ forward_pixel_iterator_base_(I& image);
+ };
- /// Beginning of the image.
- mln_qlf_value(I)* boi_;
- /// End of the image (past-the-end).
- mln_qlf_value(I)* eoi_;
+ /*------------------------------------------------.
+ | internal::backward_pixel_iterator_base_<I, E>. |
+ `------------------------------------------------*/
+
+ /// \internal A base class for backward pixel iterators.
+ template <typename I, typename E>
+ class backward_pixel_iterator_base_ : public pixel_iterator_base_<I, E>
+ {
+ typedef pixel_iterator_base_<I, E> super_;
+
+ public:
+ /// Manipulation
+ /// \{
+ /// Start an iteration.
+ void start();
+ /// Invalidate the iterator.
+ void invalidate();
+ /// Test if the iterator is valid.
+ bool is_valid() const;
+ /// \}
+ protected:
/// Constructor.
- pixel_iterator_base_(I& image);
+ backward_pixel_iterator_base_(I& image);
};
#ifndef MLN_INCLUDE_ONLY
+ /*---------------------------------------.
+ | internal::pixel_iterator_base_<I, E>. |
+ `---------------------------------------*/
+
template <typename I, typename E>
inline
pixel_iterator_base_<I, E>::pixel_iterator_base_(I& image)
@@ -89,33 +133,79 @@
I& ima = this->image_;
boi_ = & ima( ima.domain().pmin() ) - 1;
eoi_ = & ima( ima.domain().pmax() ) + 1;
- invalidate();
+ exact(*this).invalidate();
+ }
+
+
+ /*-----------------------------------------------.
+ | internal::forward_pixel_iterator_base_<I, E>. |
+ `-----------------------------------------------*/
+
+ template <typename I, typename E>
+ inline
+ forward_pixel_iterator_base_<I, E>::forward_pixel_iterator_base_(I& image)
+ : super_(image)
+ {
+ }
+
+ template <typename I, typename E>
+ inline
+ void
+ forward_pixel_iterator_base_<I, E>::start()
+ {
+ this->value_ptr_ = this->boi_ + 1;
+ }
+
+ template <typename I, typename E>
+ inline
+ void
+ forward_pixel_iterator_base_<I, E>::invalidate()
+ {
+ this->value_ptr_ = this->eoi_;
+ }
+
+ template <typename I, typename E>
+ inline
+ bool
+ forward_pixel_iterator_base_<I, E>::is_valid() const
+ {
+ return this->value_ptr_ != this->eoi_;
+ }
+
+
+ /*------------------------------------------------.
+ | internal::backward_pixel_iterator_base_<I, E>. |
+ `------------------------------------------------*/
+
+ template <typename I, typename E>
+ inline
+ backward_pixel_iterator_base_<I, E>::backward_pixel_iterator_base_(I& image)
+ : super_(image)
+ {
}
- // FIXME: Remove cause dangerous when bkd!!!
template <typename I, typename E>
inline
void
- pixel_iterator_base_<I, E>::start()
+ backward_pixel_iterator_base_<I, E>::start()
{
- this->value_ptr_ = boi_ + 1;
+ this->value_ptr_ = this->eoi_ - 1;
}
template <typename I, typename E>
inline
void
- pixel_iterator_base_<I, E>::invalidate()
+ backward_pixel_iterator_base_<I, E>::invalidate()
{
- this->value_ptr_ = eoi_;
+ this->value_ptr_ = this->boi_;
}
- // FIXME: Remove casue not optimal!!!
template <typename I, typename E>
inline
bool
- pixel_iterator_base_<I, E>::is_valid() const
+ backward_pixel_iterator_base_<I, E>::is_valid() const
{
- return this->value_ptr_ != eoi_ && this->value_ptr_ != boi_;
+ return this->value_ptr_ != this->boi_;
}
#endif // ! MLN_INCLUDE_ONLY
Index: mln/core/pixter1d.hh
--- mln/core/pixter1d.hh (revision 1910)
+++ mln/core/pixter1d.hh (working copy)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007 EPITA Research and Development Laboratory
+// 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
@@ -28,51 +28,75 @@
#ifndef MLN_CORE_PIXTER1D_HH
# define MLN_CORE_PIXTER1D_HH
-/*! \file mln/core/pixter1d.hh
- *
- * \brief Pixel iterator class on a image 1d with border.
- */
+/// \file mln/core/pixter1d.hh
+/// \brief Pixel iterators on a 1-D image with border.
# include <mln/core/internal/pixel_iterator_base.hh>
# include <mln/core/point1d.hh>
# include <mln/geom/size1d.hh>
-
-
namespace mln
{
+ /*------------------.
+ | fwd_pixter1d<I>. |
+ `------------------*/
+
+ /// Forward pixel iterator on a 1-D image with border.
template <typename I>
- class fwd_pixter1d : public internal::pixel_iterator_base_< I, fwd_pixter1d<I> >
+ class fwd_pixter1d :
+ public internal::forward_pixel_iterator_base_< I, fwd_pixter1d<I> >
{
- typedef internal::pixel_iterator_base_< I, fwd_pixter1d<I> > super_;
+ typedef internal::forward_pixel_iterator_base_< I, fwd_pixter1d<I> > super_;
public:
-
/// Image type.
typedef I image;
- /*! \brief Constructor.
- *
- * \param[in] image Image to iterate over its pixels.
- */
+ /// \brief Constructor.
+ /// \param[in] image The image this pixel iterator is bound to.
fwd_pixter1d(I& image);
/// Go to the next pixel.
void next_();
-
};
- // FIXME: bkd_pixter1d
+ /*------------------.
+ | bkd_pixter1d<I>. |
+ `------------------*/
+
+ /// Backward pixel iterator on a 1-D image with border.
+ template <typename I>
+ class bkd_pixter1d :
+ public internal::backward_pixel_iterator_base_< I, bkd_pixter1d<I> >
+ {
+ typedef internal::backward_pixel_iterator_base_< I, bkd_pixter1d<I> > super_;
+
+ public:
+ /// Image type.
+ typedef I image;
+
+ /// \brief Constructor.
+ /// \param[in] image The image this pixel iterator is bound to.
+ bkd_pixter1d(I& image);
+
+ /// Go to the next pixel.
+ void next_();
+ };
+
#ifndef MLN_INCLUDE_ONLY
+ /*------------------.
+ | fwd_pixter1d<I>. |
+ `------------------*/
+
template <typename I>
inline
- fwd_pixter1d<I>::fwd_pixter1d(I& image) :
- super_(image)
+ fwd_pixter1d<I>::fwd_pixter1d(I& image)
+ : super_(image)
{
mln_precondition(image.has_data());
}
@@ -85,6 +109,27 @@
++this->value_ptr_;
}
+
+ /*------------------.
+ | bkd_pixter1d<I>. |
+ `------------------*/
+
+ template <typename I>
+ inline
+ bkd_pixter1d<I>::bkd_pixter1d(I& image)
+ : super_(image)
+ {
+ mln_precondition(image.has_data());
+ }
+
+ template <typename I>
+ inline
+ void
+ bkd_pixter1d<I>::next_()
+ {
+ --this->value_ptr_;
+ }
+
#endif // ! MLN_INCLUDE_ONLY
} // end of namespace mln
Index: mln/core/pixter2d.hh
--- mln/core/pixter2d.hh (revision 1910)
+++ mln/core/pixter2d.hh (working copy)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007 EPITA Research and Development Laboratory
+// 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
@@ -28,102 +28,97 @@
#ifndef MLN_CORE_PIXTER2D_HH
# define MLN_CORE_PIXTER2D_HH
-/*! \file mln/core/pixter2d.hh
- *
- * \brief Pixel iterator class on a image 2d with border.
- */
+/// \file mln/core/pixter2d.hh
+/// \brief Pixel iterators on a 2-D image with border.
# include <mln/core/internal/pixel_iterator_base.hh>
# include <mln/core/point2d.hh>
# include <mln/geom/size2d.hh>
-
-
namespace mln
{
+ /*------------------.
+ | fwd_pixter2d<I>. |
+ `------------------*/
+
+ /// Forward pixel iterator on a 2-D image with border.
template <typename I>
- class fwd_pixter2d : public internal::pixel_iterator_base_< I, fwd_pixter2d<I> >
+ class fwd_pixter2d
+ : public internal::forward_pixel_iterator_base_< I, fwd_pixter2d<I> >
{
- typedef internal::pixel_iterator_base_< I, fwd_pixter2d<I> > super_;
+ typedef internal::forward_pixel_iterator_base_< I, fwd_pixter2d<I> > super_;
public:
-
/// Image type.
typedef I image;
- /*! \brief Constructor.
- *
- * \param[in] image Image to iterate over its pixels.
- */
+ /// \brief Constructor.
+ /// \param[in] image The image this pixel iterator is bound to.
fwd_pixter2d(I& image);
/// Go to the next pixel.
void next_();
private:
-
/// Twice the size of the image border.
unsigned border_x2_;
-
/// Row offset.
unsigned row_offset_;
-
/// End of the current row.
mln_qlf_value(I)* eor_;
};
+ /*------------------.
+ | bkd_pixter2d<I>. |
+ `------------------*/
+ /// Backward pixel iterator on a 2-D image with border.
template <typename I>
- class bkd_pixter2d : public internal::pixel_iterator_base_< I, bkd_pixter2d<I> >
+ class bkd_pixter2d
+ : public internal::backward_pixel_iterator_base_< I, bkd_pixter2d<I> >
{
- typedef internal::pixel_iterator_base_< I, bkd_pixter2d<I> > super_;
+ typedef internal::backward_pixel_iterator_base_< I, bkd_pixter2d<I> > super_;
public:
-
/// Image type.
typedef I image;
- /*! \brief Constructor.
- *
- * \param[in] image Image to iterate over its pixels.
- */
+ /// \brief Constructor.
+ /// \param[in] image The image this pixel iterator is bound to.
bkd_pixter2d(I& image);
/// Go to the next pixel.
void next_();
- void start();
-
private:
/// Twice the size of the image border.
unsigned border_x2_;
-
/// Row offset.
unsigned row_offset_;
-
/// Beginning of the current row.
mln_qlf_value(I)* bor_;
};
-
#ifndef MLN_INCLUDE_ONLY
- // Fwd.
+ /*------------------.
+ | fwd_pixter2d<I>. |
+ `------------------*/
template <typename I>
inline
- fwd_pixter2d<I>::fwd_pixter2d(I& image) :
- super_(image)
+ fwd_pixter2d<I>::fwd_pixter2d(I& image)
+ : super_(image),
+ border_x2_(2 * image.border()),
+ row_offset_(image.bbox().ncols() + border_x2_),
+ eor_(& image.at(geom::min_row(image), geom::max_col(image)) + 1)
{
mln_precondition(image.has_data());
- border_x2_ = 2 * image.border();
- row_offset_ = geom::max_col(image) - geom::min_col(image) + 1 + border_x2_;
- eor_ = & image.at(geom::min_row(image), geom::max_col(image)) + 1;
}
template <typename I>
@@ -139,17 +134,20 @@
}
}
- // Bkd.
+
+ /*------------------.
+ | fwd_pixter2d<I>. |
+ `------------------*/
template <typename I>
inline
- bkd_pixter2d<I>::bkd_pixter2d(I& image) :
- super_(image)
+ bkd_pixter2d<I>::bkd_pixter2d(I& image)
+ : super_(image),
+ border_x2_(2 * image.border()),
+ row_offset_(image.bbox().ncols() + border_x2_),
+ bor_(& image.at(geom::max_row(image), geom::min_col(image)) - 1)
{
mln_precondition(image.has_data());
- border_x2_ = 2 * image.border();
- row_offset_ = geom::max_col(image) - geom::min_col(image) + 1 + border_x2_;
- bor_ = & image.at(geom::max_row(image), geom::min_col(image)) - 1;
}
template <typename I>
@@ -165,14 +163,6 @@
}
}
- template <typename I>
- inline
- void
- bkd_pixter2d<I>::start()
- {
- this->value_ptr_ = this->eoi_ - 1;
- }
-
#endif // ! MLN_INCLUDE_ONLY
} // end of namespace mln
Index: mln/core/pixter3d.hh
--- mln/core/pixter3d.hh (revision 1910)
+++ mln/core/pixter3d.hh (working copy)
@@ -28,70 +28,104 @@
#ifndef MLN_CORE_PIXTER3D_HH
# define MLN_CORE_PIXTER3D_HH
-/*! \file mln/core/pixter3d.hh
- *
- * \brief Pixel iterator class on a image 3d with border.
- */
+/// \file mln/core/pixter3d.hh
+/// \brief Pixel iterators on a 3-D image with border.
# include <mln/core/internal/pixel_iterator_base.hh>
# include <mln/core/point3d.hh>
# include <mln/geom/size3d.hh>
-
-
namespace mln
{
+ /*------------------.
+ | fwd_pixter3d<I>. |
+ `------------------*/
+
+ /// Forward pixel iterator on a 3-D image with border.
template <typename I>
class fwd_pixter3d
- : public internal::pixel_iterator_base_< I, fwd_pixter3d<I> >
+ : public internal::forward_pixel_iterator_base_< I, fwd_pixter3d<I> >
{
- typedef internal::pixel_iterator_base_< I, fwd_pixter3d<I> > super_;
+ typedef internal::forward_pixel_iterator_base_< I, fwd_pixter3d<I> > super_;
public:
-
/// Image type.
typedef I image;
- /*! \brief Constructor.
- *
- * \param[in] image Image to iterate over its pixels.
- */
+ /// \brief Constructor.
+ /// \param[in] image The image this pixel iterator is bound to.
fwd_pixter3d(I& image);
/// Go to the next pixel.
void next_();
private:
-
/// Twice the size of the image border.
const unsigned border_x2_;
-
/// Row offset.
const unsigned row_offset_;
-
/// End of the current row.
mln_qlf_value(I)* eor_;
/// Next slice offset.
const unsigned next_sli_offset_;
-
/// Next slice offset for row.
const unsigned next_srow_offset_;
-
/// Slice offset.
const unsigned sli_offset_;
-
/// End of the current slice.
mln_qlf_value(I)* eos_;
};
- // FIXME: bkd_pixter3d
+ /*------------------.
+ | bkd_pixter3d<I>. |
+ `------------------*/
+
+ /// Backward pixel iterator on a 3-D image with border.
+ template <typename I>
+ class bkd_pixter3d
+ : public internal::backward_pixel_iterator_base_< I, bkd_pixter3d<I> >
+ {
+ typedef internal::backward_pixel_iterator_base_< I, bkd_pixter3d<I> > super_;
+
+ public:
+ /// Image type.
+ typedef I image;
+
+ /// \brief Constructor.
+ /// \param[in] image The image this pixel iterator is bound to.
+ bkd_pixter3d(I& image);
+
+ /// Go to the next pixel.
+ void next_();
+
+ private:
+ /// Twice the size of the image border.
+ const unsigned border_x2_;
+ /// Row offset.
+ const unsigned row_offset_;
+ /// Beginning of the current row.
+ mln_qlf_value(I)* bor_;
+
+ /// Next slice offset.
+ const unsigned next_sli_offset_;
+ /// Next slice offset for row.
+ const unsigned next_srow_offset_;
+ /// Slice offset.
+ const unsigned sli_offset_;
+ /// Beginning of the current slice.
+ mln_qlf_value(I)* bos_;
+ };
#ifndef MLN_INCLUDE_ONLY
+ /*------------------.
+ | fwd_pixter3d<I>. |
+ `------------------*/
+
template <typename I>
inline
fwd_pixter3d<I>::fwd_pixter3d(I& image)
@@ -131,6 +165,50 @@
}
}
+
+ /*------------------.
+ | bkd_pixter3d<I>. |
+ `------------------*/
+
+ template <typename I>
+ inline
+ bkd_pixter3d<I>::bkd_pixter3d(I& image)
+ : super_(image),
+ border_x2_(2 * image.border()),
+ row_offset_(image.bbox().ncols() + border_x2_),
+ bor_(& image.at(geom::max_sli(image),
+ geom::max_row(image),
+ geom::min_col(image)) - 1),
+ next_sli_offset_(row_offset_ * border_x2_ + border_x2_),
+ next_srow_offset_(next_sli_offset_ + image.bbox().ncols()),
+ sli_offset_((image.bbox().ncols() + border_x2_) *
+ (image.bbox().nrows() + border_x2_)),
+ bos_(& image.at(geom::max_sli(image),
+ geom::min_row(image),
+ geom::min_col(image)) - 1)
+ {
+ mln_precondition(image.has_data());
+ }
+
+ template <typename I>
+ inline
+ void
+ bkd_pixter3d<I>::next_()
+ {
+ --this->value_ptr_;
+ if (this->value_ptr_ == bos_ && this->value_ptr_ != this->boi_)
+ {
+ this->value_ptr_ -= next_sli_offset_;
+ bos_ -= sli_offset_;
+ bor_ -= next_srow_offset_;
+ }
+ else if (this->value_ptr_ == bor_ && this->value_ptr_ != this->boi_)
+ {
+ this->value_ptr_ -= border_x2_;
+ bor_ -= row_offset_;
+ }
+ }
+
#endif // ! MLN_INCLUDE_ONLY
} // end of namespace mln
Index: mln/core/p_image2d_pixter.hh
--- mln/core/p_image2d_pixter.hh (revision 1910)
+++ mln/core/p_image2d_pixter.hh (working copy)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007 EPITA Research and Development Laboratory
+// Copyright (C) 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
@@ -28,49 +28,51 @@
#ifndef MLN_CORE_P_IMAGE2D_PIXTER_HH
# define MLN_CORE_P_IMAGE2D_PIXTER_HH
-/*! \file mln/core/p_image2d_pixter.hh
- *
- * \brief Pixel iterator class on a image 2d with border.
- */
+/// \file mln/core/p_image2d_pixter.hh
+/// \brief Pixel iterators on a mln::p_image2d.
# include <mln/core/internal/pixel_iterator_base.hh>
# include <mln/core/point2d.hh>
# include <mln/geom/size2d.hh>
-
-
namespace mln
{
+ /*--------------------------.
+ | p_image2d_fwd_pixter<P>. |
+ `--------------------------*/
+
template <typename P>
- class p_image2d_fwd_pixter : public internal::pixel_iterator_base_< typename p_image2d<P>::image_type, p_image2d_fwd_pixter<P> >
- {
- typedef internal::pixel_iterator_base_< typename p_image2d<P>::image_type, p_image2d_fwd_pixter<P> > super_;
+ class p_image2d_fwd_pixter
+ : public internal::forward_pixel_iterator_base_<
+ typename p_image2d<P>::image_type,
+ p_image2d_fwd_pixter<P>
+ >
+ {
+ typedef internal::forward_pixel_iterator_base_<
+ typename p_image2d<P>::image_type,
+ p_image2d_fwd_pixter<P>
+ > super_;
public:
-
/// Image type.
typedef typename p_image2d<P>::image_type image;
-
/// Point type.
typedef point2d point;
- /*! \brief Constructor.
- *
- * \param[in] image Image to iterate over its pixels.
- */
+ /// \brief Constructor.
+ /// \param[in] image The mln::p_image2d this pixel iterator is bound to.
p_image2d_fwd_pixter(p_image2d<P>& s);
- /// Reference of the corresponding point.
- const point to_point() const;
-
+ /// Start an iteration.
+ void start();
/// Go to the next pixel.
void next_();
- void start();
+ /// Reference of the corresponding point.
+ const point to_point() const;
private:
-
/// Row offset.
unsigned row_offset_;
/// End of the current row.
@@ -78,66 +80,74 @@
};
+ /*--------------------------.
+ | p_image2d_bkd_pixter<P>. |
+ `--------------------------*/
template <typename P>
- class p_image2d_bkd_pixter : public internal::pixel_iterator_base_< typename image2d<P>::image_type, p_image2d_bkd_pixter<P> >
- {
- typedef internal::pixel_iterator_base_< typename image2d<P>::image_type, p_image2d_bkd_pixter<P> > super_;
+ class p_image2d_bkd_pixter
+ : public internal::backward_pixel_iterator_base_<
+ typename image2d<P>::image_type,
+ p_image2d_bkd_pixter<P>
+ >
+ {
+ typedef internal::backward_pixel_iterator_base_<
+ typename image2d<P>::image_type,
+ p_image2d_bkd_pixter<P>
+ > super_;
public:
-
/// Image type.
typedef typename p_image2d<P>::image_type image;
-
/// Point type.
typedef point2d point;
- /*! \brief Constructor.
- *
- * \param[in] image Image to iterate over its pixels.
- */
+ /// \brief Constructor.
+ /// \param[in] image The mln::p_image2d this pixel iterator is bound to.
p_image2d_bkd_pixter(p_image2d<P>& s);
+ /// Start an iteration.
+ void start();
/// Go to the next pixel.
void next_();
- void start();
-
/// Reference of the corresponding point.
const point to_point() const;
private:
-
/// Row offset.
unsigned row_offset_;
-
/// Beginning of the current row.
mln_qlf_value(image)* bor_;
};
-
#ifndef MLN_INCLUDE_ONLY
- // Fwd.
+ /*--------------------------.
+ | p_image2d_fwd_pixter<P>. |
+ `--------------------------*/
template <typename P>
inline
- p_image2d_fwd_pixter<P>::p_image2d_fwd_pixter(p_image2d<P>& s) :
- super_(s.image_non_const())
+ p_image2d_fwd_pixter<P>::p_image2d_fwd_pixter(p_image2d<P>& s)
+ : super_(s.image_non_const())
{
mln_precondition(this->image_.has_data());
row_offset_ = geom::max_col(this->image_) - geom::min_col(this->image_) + 1;
- eor_ = & this->image_.at(geom::min_row(this->image_), geom::max_col(this->image_)) + 1;
+ eor_ = & this->image_.at(geom::min_row(this->image_),
+ geom::max_col(this->image_)) + 1;
}
template <typename P>
inline
- const typename p_image2d_fwd_pixter<P>::point
- p_image2d_fwd_pixter<P>::to_point() const
+ void
+ p_image2d_fwd_pixter<P>::start()
{
- return this->image_.point_at_offset(*this);
+ this->value_ptr_ = this->boi_ + 1;
+ while(this->is_valid() && !(*this->value_ptr_))
+ ++this->value_ptr_;
}
template <typename P>
@@ -150,35 +160,38 @@
++this->value_ptr_;
}
-
template <typename P>
inline
- void
- p_image2d_fwd_pixter<P>::start()
+ const typename p_image2d_fwd_pixter<P>::point
+ p_image2d_fwd_pixter<P>::to_point() const
{
- this->value_ptr_ = this->boi_ + 1;
- while(this->is_valid() && !(*this->value_ptr_))
- ++this->value_ptr_;
+ return this->image_.point_at_offset(*this);
}
- // Bkd.
+
+ /*--------------------------.
+ | p_image2d_bkd_pixter<P>. |
+ `--------------------------*/
template <typename P>
inline
- p_image2d_bkd_pixter<P>::p_image2d_bkd_pixter(p_image2d<P>& s) :
- super_(s.image_non_const())
+ p_image2d_bkd_pixter<P>::p_image2d_bkd_pixter(p_image2d<P>& s)
+ : super_(s.image_non_const())
{
mln_precondition(this->image_.has_data());
row_offset_ = geom::max_col(this->image_) - geom::min_col(this->image_) + 1;
- bor_ = & this->image_.at(geom::max_row(this->image_), geom::min_col(this->image_)) - 1;
+ bor_ = & this->image_.at(geom::max_row(this->image_),
+ geom::min_col(this->image_)) - 1;
}
template <typename P>
inline
- const typename p_image2d_bkd_pixter<P>::point
- p_image2d_bkd_pixter<P>::to_point() const
+ void
+ p_image2d_bkd_pixter<P>::start()
{
- return this->image_.point_at_offset(*this);
+ this->value_ptr_ = this->eoi_ - 1;
+ while(this->is_valid() && !(*this->value_ptr_))
+ --this->value_ptr_;
}
template <typename P>
@@ -193,12 +206,10 @@
template <typename P>
inline
- void
- p_image2d_bkd_pixter<P>::start()
+ const typename p_image2d_bkd_pixter<P>::point
+ p_image2d_bkd_pixter<P>::to_point() const
{
- this->value_ptr_ = this->eoi_ - 1;
- while(this->is_valid() && !(*this->value_ptr_))
- --this->value_ptr_;
+ return this->image_.point_at_offset(*this);
}
#endif // ! MLN_INCLUDE_ONLY
Index: mln/core/image1d.hh
--- mln/core/image1d.hh (revision 1910)
+++ mln/core/image1d.hh (working copy)
@@ -533,7 +533,7 @@
template <typename T>
struct bkd_pixter< image1d<T> >
{
- typedef mln::internal::fixme ret;
+ typedef bkd_pixter1d< const image1d<T> > ret;
};
// qixter
@@ -553,9 +553,12 @@
template <typename T, typename W>
struct bkd_qixter< image1d<T>, W >
{
+ // FIXME: Implement dpoints_bkd_pixter.
typedef mln::internal::fixme ret;
};
+ // FIXME: Nixters (see in image2d.hh)
+
} // end of namespace mln::trait
} // end of namespace mln
Index: mln/core/image2d.hh
--- mln/core/image2d.hh (revision 1910)
+++ mln/core/image2d.hh (working copy)
@@ -581,6 +581,7 @@
template <typename T, typename W>
struct bkd_qixter< image2d<T>, W >
{
+ // FIXME: Implement dpoints_bkd_pixter.
typedef mln::internal::fixme ret;
};
@@ -601,6 +602,7 @@
template <typename T, typename N>
struct bkd_nixter< image2d<T>, N >
{
+ // FIXME: Implement dpoints_bkd_pixter.
typedef mln::internal::fixme ret;
};
Index: mln/core/image3d.hh
--- mln/core/image3d.hh (revision 1910)
+++ mln/core/image3d.hh (working copy)
@@ -573,7 +573,7 @@
template <typename T>
struct bkd_pixter< image3d<T> >
{
- typedef mln::internal::fixme ret;
+ typedef bkd_pixter3d< const image3d<T> > ret;
};
// qixter
@@ -593,9 +593,12 @@
template <typename T, typename W>
struct bkd_qixter< image3d<T>, W >
{
+ // FIXME: Implement dpoints_bkd_pixter.
typedef mln::internal::fixme ret;
};
+ // FIXME: Nixters (see in image2d.hh)
+
} // end of namespace mln::trait
} // end of namespace mln
Index: tests/core/pixter1d.cc
--- tests/core/pixter1d.cc (revision 0)
+++ tests/core/pixter1d.cc (revision 0)
@@ -0,0 +1,86 @@
+// Copyright (C) 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/pixter1d.cc
+/// \brief Tests on 1-D image pixters.
+
+#include <mln/core/image1d.hh>
+
+#include <mln/debug/iota.hh>
+
+int main()
+{
+ using namespace mln;
+
+ {
+ box1d b(make::point1d(2), make::point1d(4));
+ image1d<int> ima(b, 2);
+
+ mln_pixter_(image1d<int>) p(ima);
+ for_all(p)
+ std::cout << p << std::endl;
+ }
+
+ {
+ box1d b(make::point1d(2), make::point1d(6));
+ image1d<int> ima(b, 1);
+
+ debug::iota(ima);
+
+ {
+ mln_fwd_piter_(image1d<int>) pi(ima.domain());
+ mln_fwd_pixter_(image1d<int>) p(ima);
+ pi.start();
+ p.start();
+ unsigned i = 0;
+ while (pi.is_valid())
+ {
+ mln_assertion(ima(pi) == p.val());
+ pi.next();
+ p.next();
+ ++i;
+ }
+ mln_assertion(i == b.npoints());
+ }
+
+ {
+ mln_bkd_piter_(image1d<int>) pi(ima.domain());
+ mln_bkd_pixter_(image1d<int>) p(ima);
+ pi.start();
+ p.start();
+ unsigned i = 0;
+ while (pi.is_valid())
+ {
+ mln_assertion(ima(pi) == p.val());
+ pi.next();
+ p.next();
+ ++i;
+ }
+ mln_assertion(i == b.npoints());
+ }
+ }
+}
Index: tests/core/pixter2d.cc
--- tests/core/pixter2d.cc (revision 0)
+++ tests/core/pixter2d.cc (revision 0)
@@ -0,0 +1,85 @@
+// Copyright (C) 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/pixter2d.cc
+/// \brief Tests on 2-D image pixters.
+
+#include <mln/core/image2d.hh>
+
+#include <mln/debug/iota.hh>
+
+int main()
+{
+ using namespace mln;
+
+ {
+ box2d b(make::point2d(2, 1), make::point2d(4, 3));
+ image2d<int> ima(b, 2);
+
+ mln_pixter_(image2d<int>) p(ima);
+ for_all(p)
+ std::cout << p << std::endl;
+ }
+
+ {
+ box2d b(make::point2d(2, 1), make::point2d(6, 3));
+ image2d<int> ima(b, 1);
+ debug::iota(ima);
+
+ {
+ mln_fwd_piter_(image2d<int>) pi(ima.domain());
+ mln_fwd_pixter_(image2d<int>) p(ima);
+ pi.start();
+ p.start();
+ unsigned i = 0;
+ while (pi.is_valid())
+ {
+ mln_assertion(ima(pi) == p.val());
+ pi.next();
+ p.next();
+ ++i;
+ }
+ mln_assertion(i == b.npoints());
+ }
+
+ {
+ mln_bkd_piter_(image2d<int>) pi(ima.domain());
+ mln_bkd_pixter_(image2d<int>) p(ima);
+ pi.start();
+ p.start();
+ unsigned i = 0;
+ while (pi.is_valid())
+ {
+ mln_assertion(ima(pi) == p.val());
+ pi.next();
+ p.next();
+ ++i;
+ }
+ mln_assertion(i == b.npoints());
+ }
+ }
+}
Index: tests/core/pixter3d.cc
--- tests/core/pixter3d.cc (revision 1910)
+++ tests/core/pixter3d.cc (working copy)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory
+// Copyright (C) 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
@@ -25,14 +25,10 @@
// reasons why the executable file might be covered by the GNU General
// Public License.
-/*! \file tests/level/image3d.cc
- *
- * \brief Tests on Image3d pixter
- */
-
+/// \file tests/level/pixter3d.cc
+/// \brief Tests on 3-D image pixters.
#include <mln/core/image3d.hh>
-#include <mln/core/image2d.hh>
#include <mln/debug/iota.hh>
@@ -40,8 +36,6 @@
{
using namespace mln;
-
- // Working test
{
box3d b(make::point3d(1,2, 1), make::point3d(2,4, 3));
image3d<int> ima(b, 2);
@@ -51,10 +45,9 @@
std::cout << p << std::endl;
}
-
{
box3d b(make::point3d(1,2, 1), make::point3d(3,6, 3));
- image3d<int> ima(b, 0);
+ image3d<int> ima(b, 1);
debug::iota(ima);
@@ -73,5 +66,21 @@
}
mln_assertion(i == b.npoints());
}
+
+ {
+ mln_bkd_piter_(image3d<int>) pi(ima.domain());
+ mln_bkd_pixter_(image3d<int>) p(ima);
+ pi.start();
+ p.start();
+ unsigned i = 0;
+ while (pi.is_valid())
+ {
+ mln_assertion(ima(pi) == p.val());
+ pi.next();
+ p.next();
+ ++i;
+ }
+ mln_assertion(i == b.npoints());
+ }
}
}
Index: tests/core/Makefile.am
--- tests/core/Makefile.am (revision 1910)
+++ tests/core/Makefile.am (working copy)
@@ -8,7 +8,6 @@
exact \
h_vec \
initialize \
- image3d \
graph_elt_neighborhood \
graph_elt_window \
graph_image \
@@ -26,6 +25,9 @@
p_queue \
p_queue_fast \
p_runs \
+ pixter1d \
+ pixter2d \
+ pixter3d \
point_set_compatibility \
pset_array \
rle_image \
@@ -38,7 +40,6 @@
exact_SOURCES = exact.cc
h_vec_SOURCES = h_vec.cc
initialize_SOURCES = initialize.cc
-image3d_SOURCES = image3d.cc
graph_elt_neighborhood_SOURCES = graph_elt_neighborhood.cc
graph_elt_window_SOURCES = graph_elt_window.cc
graph_image_SOURCES = graph_image.cc
@@ -56,6 +57,9 @@
p_queue_SOURCES = p_priority_queue_fast.cc
p_queue_fast_SOURCES = p_priority_queue_fast.cc
p_runs_SOURCES = p_runs.cc
+pixter1d_SOURCES = pixter1d.cc
+pixter2d_SOURCES = pixter2d.cc
+pixter3d_SOURCES = pixter3d.cc
point_set_compatibility_SOURCES = point_set_compatibility.cc
pset_array_SOURCES = pset_array.cc
rle_image_SOURCES = rle_image.cc
1
0
https://svn.lrde.epita.fr/svn/oln/trunk/milena
Attention � bien remplir les Makefile.am's lors de l'ajout de nouveaux
tests!
Index: ChangeLog
from Roland Levillain <roland(a)lrde.epita.fr>
Fix mln::fwd_pixter3d.
* mln/core/pixter3d.hh: s/slide/slice/.
Wrap long lines
(mln::fwd_pixter3d<I>::next_sli_offset_)
(mln::fwd_pixter3d<I>::next_srow_offset_):
Switch positions of members.
(mln::fwd_pixter3d<I>::fwd_pixter3d): Fix initializations of
members next_sli_offset_, next_srow_offset_ and eos_.
(mln::fwd_pixter3d<I>::next_): Catch up with these new definitions
of members.
* tests/core/image3d.cc: Check the number of iterations.
* tests/core/Makefile.am (image3d_SOURCES, pset_array_SOURCES):
New (missing variables).
mln/core/pixter3d.hh | 42 ++++++++++++++++++++++++------------------
tests/core/Makefile.am | 2 ++
tests/core/image3d.cc | 12 ++++++++----
3 files changed, 34 insertions(+), 22 deletions(-)
Index: mln/core/pixter3d.hh
--- mln/core/pixter3d.hh (revision 1909)
+++ mln/core/pixter3d.hh (working copy)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007 EPITA Research and Development Laboratory
+// 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
@@ -43,7 +43,8 @@
{
template <typename I>
- class fwd_pixter3d : public internal::pixel_iterator_base_< I, fwd_pixter3d<I> >
+ class fwd_pixter3d
+ : public internal::pixel_iterator_base_< I, fwd_pixter3d<I> >
{
typedef internal::pixel_iterator_base_< I, fwd_pixter3d<I> > super_;
@@ -72,16 +73,16 @@
/// End of the current row.
mln_qlf_value(I)* eor_;
- ///Next Slide offset for row.
- const unsigned next_srow_offset_;
-
- /// Next Slide offset.
+ /// Next slice offset.
const unsigned next_sli_offset_;
- /// Slide offset.
+ /// Next slice offset for row.
+ const unsigned next_srow_offset_;
+
+ /// Slice offset.
const unsigned sli_offset_;
- /// End of the current slide.
+ /// End of the current slice.
mln_qlf_value(I)* eos_;
};
@@ -97,11 +98,16 @@
: super_(image),
border_x2_ (2 * image.border()),
row_offset_ (image.bbox().ncols() + border_x2_),
- eor_ (& image.at(geom::min_sli(image), geom::min_row(image), geom::max_col(image)) + 1),
- next_srow_offset_ ((image.bbox().ncols() + border_x2_) * border_x2_ ),
- next_sli_offset_ (row_offset_ * border_x2_),
- sli_offset_ ((image.bbox().ncols() + border_x2_) * (image.bbox().nrows() + border_x2_)),
- eos_ (& image.at(geom::min_sli(image), geom::max_row(image) + 1, geom::min_col(image)))
+ eor_ (& image.at(geom::min_sli(image),
+ geom::min_row(image),
+ geom::max_col(image)) + 1),
+ next_sli_offset_ (row_offset_ * border_x2_ + border_x2_),
+ next_srow_offset_ (next_sli_offset_ + image.bbox().ncols()),
+ sli_offset_ ((image.bbox().ncols() + border_x2_) *
+ (image.bbox().nrows() + border_x2_)),
+ eos_ (& image.at(geom::min_sli(image),
+ geom::max_row(image),
+ geom::max_col(image)) + 1)
{
mln_precondition(image.has_data());
}
@@ -112,17 +118,17 @@
fwd_pixter3d<I>::next_()
{
++this->value_ptr_;
- if (this->value_ptr_ == eor_ && this->value_ptr_ != this->eoi_)
- {
- this->value_ptr_ += border_x2_;
- eor_ += row_offset_;
- }
if (this->value_ptr_ == eos_ && this->value_ptr_ != this->eoi_)
{
this->value_ptr_ += next_sli_offset_;
eos_ += sli_offset_;
eor_ += next_srow_offset_;
}
+ else if (this->value_ptr_ == eor_ && this->value_ptr_ != this->eoi_)
+ {
+ this->value_ptr_ += border_x2_;
+ eor_ += row_offset_;
+ }
}
#endif // ! MLN_INCLUDE_ONLY
Index: tests/core/image3d.cc
--- tests/core/image3d.cc (revision 1909)
+++ tests/core/image3d.cc (working copy)
@@ -56,18 +56,22 @@
box3d b(make::point3d(1,2, 1), make::point3d(3,6, 3));
image3d<int> ima(b, 0);
- mln_piter_(image3d<int>) pi(ima.domain());
- mln_pixter_(image3d<int>) p(ima);
-
debug::iota(ima);
+ {
+ mln_fwd_piter_(image3d<int>) pi(ima.domain());
+ mln_fwd_pixter_(image3d<int>) p(ima);
pi.start();
p.start();
+ unsigned i = 0;
while (pi.is_valid())
{
- assert(ima(pi) == p.val());
+ mln_assertion(ima(pi) == p.val());
pi.next();
p.next();
+ ++i;
+ }
+ mln_assertion(i == b.npoints());
}
}
}
Index: tests/core/Makefile.am
--- tests/core/Makefile.am (revision 1909)
+++ tests/core/Makefile.am (working copy)
@@ -38,6 +38,7 @@
exact_SOURCES = exact.cc
h_vec_SOURCES = h_vec.cc
initialize_SOURCES = initialize.cc
+image3d_SOURCES = image3d.cc
graph_elt_neighborhood_SOURCES = graph_elt_neighborhood.cc
graph_elt_window_SOURCES = graph_elt_window.cc
graph_image_SOURCES = graph_image.cc
@@ -56,6 +57,7 @@
p_queue_fast_SOURCES = p_priority_queue_fast.cc
p_runs_SOURCES = p_runs.cc
point_set_compatibility_SOURCES = point_set_compatibility.cc
+pset_array_SOURCES = pset_array.cc
rle_image_SOURCES = rle_image.cc
sparse_image_SOURCES = sparse_image.cc
t_image_SOURCES = t_image.cc
1
0
https://svn.lrde.epita.fr/svn/oln/trunk/milena
Index: ChangeLog
from Roland Levillain <roland(a)lrde.epita.fr>
Misc. clean-up in line graph-related entities.
* mln/core/line_graph_elt_window.hh: Don't insert the reference
piter itself into the set of window sites.
* mln/core/line_graph_window_piter.hh,
* mln/core/line_graph_elt_neighborhood.hh,
* tests/core/line_graph_image.cc:
Typo, aesthetics changes.
mln/core/line_graph_elt_neighborhood.hh | 9 ++++-----
mln/core/line_graph_elt_window.hh | 13 +++++++++----
tests/core/line_graph_image.cc | 2 +-
3 files changed, 14 insertions(+), 10 deletions(-)
Index: mln/core/line_graph_elt_window.hh
--- mln/core/line_graph_elt_window.hh (revision 1908)
+++ mln/core/line_graph_elt_window.hh (working copy)
@@ -40,6 +40,10 @@
- mln::line_graph_elt_window
- mln::line_graph_elt_neighborhood. */
+/* FIXME: Due to the poor interface of mln::p_line_graph and
+ mln::util::graph, we show to much implementation details here.
+ Enrich their interfaces to avoid that. */
+
# include <mln/core/concept/window.hh>
# include <mln/core/line_graph_psite.hh>
# include <mln/core/line_graph_window_piter.hh>
@@ -86,6 +90,7 @@
/// Services for iterators.
/// \{
+ /// Compute the set of sites for this window around \a piter.
template <typename Piter>
void compute_sites_(Point_Iterator<Piter>& piter) const;
/// \}
@@ -132,17 +137,17 @@
/* FIXME: Move this computation out of the window. In fact,
this should be a service of the graph, also proposed by the
p_line_graph. */
- // Add the reference piter itself.
- sites.insert(piter.p_ref().id());
// Ajacent edges connected through node 1.
- // FIXME: Far too low-level.
+ /* We don't need to explicitely insert the reference piter (edge
+ id) itself into SITES, since it is part of the set of edges
+ adjacent to NODE1 and NODE2, and will therefore be
+ automatically added. */
util::node_id id1 = piter.p_ref().first_id();
const util::node<P>& node1 = piter.plg().gr_->node(id1);
for (std::vector<util::edge_id>::const_iterator e =
node1.edges.begin(); e != node1.edges.end(); ++e)
sites.insert(*e);
// Ajacent edges connected through node 2.
- // FIXME: Likewise.
util::node_id id2 = piter.p_ref().second_id();
const util::node<P>& node2 = piter.plg().gr_->node(id2);
for (std::vector<util::edge_id>::const_iterator e =
Index: mln/core/line_graph_window_piter.hh
Index: mln/core/line_graph_elt_neighborhood.hh
--- mln/core/line_graph_elt_neighborhood.hh (revision 1908)
+++ mln/core/line_graph_elt_neighborhood.hh (working copy)
@@ -93,6 +93,7 @@
/// Services for iterators.
/// \{
+ /// Compute the set of sites for this neighborhood around \a piter.
template <typename Piter>
void compute_sites_(Point_Iterator<Piter>& piter) const;
/// \}
@@ -112,21 +113,19 @@
util::edge_id ref_edge_id = piter.p_ref().id();
sites_t& sites = piter.sites();
sites.clear();
- /* FIXME: Move this computation out of the window. In fact,
+ /* FIXME: Move this computation out of the neighborhood. In fact,
this should be a service of the graph, also proposed by the
p_line_graph. */
// Ajacent edges connected through node 1.
- // FIXME: Far too low-level.
util::node_id id1 = piter.p_ref().first_id();
const util::node<P>& node1 = piter.plg().gr_->node(id1);
for (std::vector<util::edge_id>::const_iterator e =
node1.edges.begin(); e != node1.edges.end(); ++e)
- /* We explicitely enforce that the reference piter edge id is
- not inserted into SITES. */
+ // We explicitly enforce that the reference piter edge id is
+ // *not* inserted into SITES.
if (*e != ref_edge_id)
sites.insert(*e);
// Ajacent edges connected through node 2.
- // FIXME: Likewise.
util::node_id id2 = piter.p_ref().second_id();
const util::node<P>& node2 = piter.plg().gr_->node(id2);
for (std::vector<util::edge_id>::const_iterator e =
Index: tests/core/line_graph_image.cc
--- tests/core/line_graph_image.cc (revision 1908)
+++ tests/core/line_graph_image.cc (working copy)
@@ -110,7 +110,7 @@
mln_qiter_(win_t) q(win, p);
for_all (p)
{
- std::cout << "neighbors of " << p << " (" << ima(p) << "), "
+ std::cout << "sites adjacent to " << p << " (" << ima(p) << "), "
<< "including the site itself:" << std::endl;
for_all (q)
std::cout << " " << q << " (level = " << ima(q) << ")"
1
0
30 Apr '08
URL: https://svn.lrde.epita.fr/svn/oln/trunk/milena
ChangeLog:
2008-04-30 Etienne FOLIO <folio(a)lrde.epita.fr>
DT in canevas word plus some addons in original psn.
* sandbox/folio/canevas_dt.hh: Canevas for DT algorithm.
* sandbox/folio/dt.cc: Main test file.
* sandbox/folio/dt.hh: DT using canevas
(two algorithms currently identical).
* sandbox/folio/dt.spe.hh: DT using canevas spe file.
* sandbox/folio/psn.cc: Some addons (max value...).
---
canevas_dt.hh | 231 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
dt.cc | 59 ++++++++++++++
dt.hh | 101 +++++++++++++++++++++++++
dt.spe.hh | 123 ++++++++++++++++++++++++++++++
psn.cc | 119 ++++++++++++-----------------
5 files changed, 563 insertions(+), 70 deletions(-)
Index: trunk/milena/sandbox/folio/psn.cc
===================================================================
--- trunk/milena/sandbox/folio/psn.cc (revision 1907)
+++ trunk/milena/sandbox/folio/psn.cc (revision 1908)
@@ -33,9 +33,12 @@
# include <cmath>
# include <mln/core/concept/image.hh>
+# include <mln/make/w_window.hh>
# include <mln/core/concept/neighborhood.hh>
# include <mln/literal/zero.hh>
+# include <iostream>
+
namespace mln
{
@@ -45,14 +48,15 @@
/*! Propagation using a single neighborhood (PSN).
*
* \param[in] input_ The input image.
- * \param[in] chamfer The chamfer window to use for distance calcul.
- * \return A pair <distance map, closest point map>.
+ * \param[in] nbh The chamfer window to use for distance calcul.
+ * \param[in] max Max value of the output image.
+ * \return A distance map.
*
* \pre \p img has to be initialized.
*/
template<typename I, typename N>
mln_ch_value(I, unsigned)
- psn(const Image<I>& input_, const N& nbh);
+ psn(const Image<I>& input_, const N& nbh, unsigned max);
# ifndef MLN_INCLUDE_ONLY
@@ -60,31 +64,6 @@
namespace impl
{
-
- template <typename BP>
- class compare
- {
- public:
- bool
- operator()(const BP& lhs, const BP& rhs) const
- {
- return lhs.second > rhs.second;
- }
- };
-
- template <typename D>
- unsigned
- sq(const D& dp)
- {
- unsigned res = 0;
-
- for (unsigned i = 0; i < D::dim; ++i)
- res += std::abs(dp[i]); // FIXME: dp[i] * dp[i];
-
- return res;
- }
-
-
} // end of namespace mln::dt::impl
@@ -94,72 +73,72 @@
template<typename I, typename N>
inline
mln_ch_value(I, unsigned)
- psn(const Image<I>& input_, const N& nbh)
+ psn(const Image<I>& input_, const N& nbh, unsigned max)
{
+ // Preconditions.
const I& input = exact(input_);
mln_precondition(input.has_data());
- mln_ch_value(I, unsigned) D;
- initialize(D, input);
+ // Types.
+ typedef mln_point(I) point;
- static const unsigned M = 666; // FIXME
+ // Initialization of output.
+ mln_ch_value(I, unsigned) output;
+ initialize(output, input);
// Initialization.
- typedef mln_point(I) point;
- typedef mln_dpoint(I) dpoint;
- typedef std::pair<point, dpoint> BP;
+ // {
- std::map<unsigned, std::queue<BP> > bucket;
+ std::map<unsigned, std::queue<point> > bucket;
unsigned bucket_size = 0;
mln_fwd_piter(I) p(input.domain());
for_all(p)
if (input(p))
{
- D(p) = literal::zero;
- bucket[0].push(BP(p, literal::zero));
+ output(p) = literal::zero;
+ bucket[0].push(p);
++bucket_size;
}
else
- D(p) = M;
+ output(p) = max;
unsigned d = 0;
+ // }
+
while (bucket_size != 0)
{
- std::queue<BP>& bucket_d = bucket[d];
-
+ std::queue<point> bucket_d = bucket[d];
while (! bucket_d.empty())
{
- point p = bucket_d.front().first;
- dpoint dp = bucket_d.front().second;
-
+ point p = bucket_d.front();
bucket_d.pop();
--bucket_size;
- if (D(p) == d)
+ if (output(p) == d)
{
- mln_niter(N) n_(nbh, p);
+ mln_qiter(N) n(nbh, p);
- for_all(n_)
- if (D.has(n_))
+ for_all(n)
+ if (output.has(n))
{
- dpoint n = n_ - p;
- unsigned newD = impl::sq(dp + n);
+ unsigned newOut = output(p) + n.w();
- if (newD < D(p + n)) // p + n = p + n_ - p = n_
+ if (newOut < output(n))
{
- D(n_) = newD;
- bucket[newD].push(BP(p + n, dp + n));
+ output(n) = newOut;
+ bucket[newOut].push(n);
++bucket_size;
}
}
}
}
+ bucket.erase(d);
++d;
}
- return D;
+ return output;
}
# endif // ! MLN_INCLUDE_ONLY
@@ -190,27 +169,27 @@
{
using namespace mln;
-// image2d<bool> ima(5,5);
-// bool vals[] = { 1, 1, 1, 0, 0,
-// 0, 0, 1, 0, 0,
-// 0, 0, 1, 0, 0,
-// 0, 0, 0, 0, 0,
-// 0, 0, 0, 0, 0 };
-
- image2d<bool> ima(3,3);
- bool vals[] = { 1, 0, 0,
- 0, 0, 0,
- 0, 0, 0};
+ image2d<bool> ima(5,5);
+ bool vals[] = { 1, 0, 0, 1, 1,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 1, 0,
+ 0, 0, 0, 0, 0};
level::fill(ima, vals);
- image2d<bool> msk(3,3);
- bool rest[] = { 1, 0, 1,
- 1, 0, 1,
- 1, 1, 1};
+ image2d<bool> msk(5,5);
+ bool rest[] = { 1, 0, 1, 1, 1,
+ 1, 0, 1, 1, 1,
+ 1, 1, 0, 0, 0,
+ 1, 1, 0, 1, 1,
+ 1, 1, 1, 1, 1};
level::fill(msk, rest);
+ int ws[] = { 2, 1, 2,
+ 1, 0, 1,
+ 2, 1, 2 };
image2d<unsigned> out;
- out = dt::psn(ima | pw::value(msk), c4());
+ out = dt::psn(ima | pw::value(msk), make::w_window2d(ws), 50);
debug::println(ima | pw::value(msk));
debug::println(out);
Index: trunk/milena/sandbox/folio/dt.hh
===================================================================
--- trunk/milena/sandbox/folio/dt.hh (revision 0)
+++ trunk/milena/sandbox/folio/dt.hh (revision 1908)
@@ -0,0 +1,101 @@
+/*!
+ * \file psn.cc
+ * \author ornthalas <ornthalas(a)gmail.com>
+ */
+
+#ifndef DT_HH
+# define DT_HH
+
+// The 'fastest' specialization is in:
+# include "dt.spe.hh"
+
+namespace mln
+{
+
+ namespace dt
+ {
+
+ template<typename I, typename N, typename L>
+ inline
+ mln_ch_value(I, L)
+ dt(const Image<I>& input_, const N& nbh, unsigned max);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ namespace impl
+ {
+
+ // Generic functor.
+
+ template <typename I_, typename N_, typename L_>
+ struct dt_functor
+ {
+ typedef I_ I;
+ typedef N_ N;
+ typedef L_ L;
+
+ const I& input;
+ const N& nbh;
+ unsigned max;
+
+ dt_functor(const I_& input, const N_& nbh, const unsigned max)
+ : input(input),
+ nbh(nbh),
+ max(max)
+ {}
+
+ void init() {}
+ };
+
+
+ // Generic implementation.
+
+ namespace generic
+ {
+
+ template<typename I, typename N, typename L>
+ inline
+ mln_ch_value(I, L)
+ dt_(const Image<I>& input, const N& nbh, unsigned max)
+ {
+ trace::entering("dt::impl::generic::dt_");
+
+ typedef dt_functor<I, N, L> F;
+ F f(input, nbh, max);
+ canvas::dt<F> run(f);
+
+ trace::exiting("dt::impl::generic::dt_");
+ return run.output;
+ }
+
+ } // end of namespace mln::dt::impl::generic
+
+ } // end of namespace mln::dt::impl
+
+
+ // Facade.
+
+ template<typename I, typename N, typename L>
+ inline
+ mln_ch_value(I, L)
+ dt(const Image<I>& input, const N& nbh, unsigned max)
+ {
+ trace::entering("dt::dt");
+ mln_precondition(exact(input).has_data());
+
+ mln_ch_value(I, L) output =
+ impl::dt_(mln_trait_image_speed(I)(),
+ exact(input), nbh, max);
+
+ trace::exiting("dt::dt");
+ return output;
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::dt
+
+} // end of namespace mln
+
+#endif // !DT_HH
Index: trunk/milena/sandbox/folio/canevas_dt.hh
===================================================================
--- trunk/milena/sandbox/folio/canevas_dt.hh (revision 0)
+++ trunk/milena/sandbox/folio/canevas_dt.hh (revision 1908)
@@ -0,0 +1,231 @@
+/*!
+ * \file canevas_dt.hh
+ * \author ornthalas <ornthalas(a)gmail.com>
+ */
+
+#ifndef CANEVAS_DT_HH
+# define CANEVAS_DT_HH
+
+# include <queue>
+# include <map>
+# include <mln/core/concept/image.hh>
+# include <mln/make/w_window.hh>
+# include <mln/literal/zero.hh>
+
+# include <mln/core/concept/neighborhood.hh>
+
+namespace mln
+{
+
+ namespace canvas
+ {
+
+ // General version.
+
+ template <typename F>
+ struct dt
+ {
+ // Functor.
+ F& f;
+
+ typedef typename F::I I;
+ typedef typename F::N N;
+ typedef typename F::L L;
+ typedef mln_point(I) point;
+
+ mln_ch_value(I, L) output;
+
+ // Ctor.
+ dt(F& f);
+
+ void init();
+ void run();
+
+ std::map<unsigned, std::queue<point> > bucket;
+ unsigned bucket_size;
+
+ unsigned current_distance;
+ };
+
+ template <typename F>
+ struct dt_fastest
+ {
+ // Functor.
+ F& f;
+
+ typedef typename F::I I;
+ typedef typename F::N N;
+ typedef typename F::L L;
+ typedef mln_point(I) point;
+
+ mln_ch_value(I, L) output;
+
+ // Ctor.
+ dt_fastest(F& f);
+
+ void init();
+ void run();
+
+ std::map<unsigned, std::queue<point> > bucket;
+ unsigned bucket_size;
+
+ unsigned current_distance;
+ };
+
+# ifndef MLN_INCLUDE_ONLY
+
+ /*-------------.
+ | canvas::dt. |
+ `-------------*/
+
+ template <typename F>
+ dt<F>::dt(F& f)
+ : f(f),
+ bucket_size(0),
+ current_distance(0)
+ {
+ trace::entering("canvas::dt");
+
+ this->init();
+ this->run();
+
+ trace::exiting("canvas::dt");
+ }
+
+ template <typename F>
+ void
+ dt<F>::init()
+ {
+ this->f.init();
+ initialize(this->output, this->f.input);
+
+ mln_fwd_piter(I) p(this->f.input.domain());
+ for_all(p)
+ if (this->f.input(p))
+ {
+ this->output(p) = literal::zero;
+ this->bucket[0].push(p);
+ ++this->bucket_size;
+ }
+ else
+ this->output(p) = this->max;
+ }
+
+ template <typename F>
+ void
+ dt<F>::run()
+ {
+ while (this->bucket_size != 0)
+ {
+ std::queue<point> bucket_d = this->bucket[this->current_distance];
+ while (! bucket_d.empty())
+ {
+ point p = bucket_d.front();
+ bucket_d.pop();
+ --bucket_size;
+
+ if (this->output(p) == this->current_distance)
+ {
+ mln_qiter(N) n(this->nbh, p);
+
+ for_all(n)
+ if (this->output.has(n))
+ {
+ unsigned new_out = this->output(p) + n.w();
+
+ if (new_out < this->output(n))
+ {
+ this->output(n) = new_out;
+ this->bucket[new_out].push(n);
+ ++this->bucket_size;
+ }
+ }
+ }
+ }
+ this->bucket.erase(this->current_distance);
+ ++this->current_distance;
+ }
+ }
+
+ /*---------------------.
+ | canvas::dt_fastest. |
+ `---------------------*/
+ template <typename F>
+ dt_fastest<F>::dt_fastest(F& f)
+ : f(f),
+ bucket_size(0),
+ current_distance(0)
+ {
+ trace::entering("canvas::dt");
+
+ this->init();
+ this->run();
+
+ trace::exiting("canvas::dt");
+ }
+
+ template <typename F>
+ void
+ dt_fastest<F>::init()
+ {
+ this->f.init();
+ initialize(this->output, this->f.input);
+
+ mln_fwd_piter(I) p(this->f.input.domain());
+ for_all(p)
+ if (this->f.input(p))
+ {
+ this->output(p) = literal::zero;
+ this->bucket[0].push(p);
+ ++this->bucket_size;
+ }
+ else
+ this->output(p) = this->max;
+ }
+
+ template <typename F>
+ void
+ dt_fastest<F>::run()
+ {
+ while (this->bucket_size != 0)
+ {
+ std::queue<point> bucket_d = this->bucket[this->current_distance];
+ while (! bucket_d.empty())
+ {
+ point p = bucket_d.front();
+ bucket_d.pop();
+ --bucket_size;
+
+ if (this->output(p) == this->current_distance)
+ {
+ mln_qiter(N) n(this->nbh, p);
+
+ for_all(n)
+ if (this->output.has(n))
+ {
+ unsigned new_out = this->output(p) + n.w();
+
+ if (new_out < this->output(n))
+ {
+ this->output(n) = new_out;
+ this->bucket[new_out].push(n);
+ ++this->bucket_size;
+ }
+ }
+ }
+ }
+ this->bucket.erase(this->current_distance);
+ ++this->current_distance;
+ }
+ }
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+
+ } // end of namespace mln::canvas
+
+} // end of namespace mln
+
+
+#endif // ! MLN_CANVAS_DT_HH
Index: trunk/milena/sandbox/folio/dt.cc
===================================================================
--- trunk/milena/sandbox/folio/dt.cc (revision 0)
+++ trunk/milena/sandbox/folio/dt.cc (revision 1908)
@@ -0,0 +1,59 @@
+/*!
+ * \file dt.cc
+ * \author ornthalas <ornthalas(a)gmail.com>
+ */
+
+#include <iostream>
+#include <mln/core/image2d.hh>
+#include <mln/debug/println.hh>
+#include <mln/make/win_chamfer.hh>
+#include <mln/level/fill.hh>
+#include <mln/core/neighb2d.hh>
+
+#include <mln/io/pbm/load.hh>
+#include <mln/io/pgm/save.hh>
+#include <mln/level/stretch.hh>
+#include <mln/value/int_u8.hh>
+
+#include <mln/core/sub_image.hh>
+#include <mln/core/image_if.hh>
+#include <mln/pw/value.hh>
+
+#include "dt.hh"
+
+int main()
+{
+ using namespace mln;
+
+ image2d<bool> ima(5,5);
+ bool vals[] = { 1, 0, 0, 1, 1,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 1, 0,
+ 0, 0, 0, 0, 0};
+ level::fill(ima, vals);
+
+ image2d<bool> msk(5,5);
+ bool rest[] = { 1, 0, 1, 1, 1,
+ 1, 0, 1, 1, 1,
+ 1, 1, 0, 0, 0,
+ 1, 1, 0, 1, 1,
+ 1, 1, 1, 1, 1};
+ level::fill(msk, rest);
+
+ int ws[] = { 2, 1, 2,
+ 1, 0, 1,
+ 2, 1, 2 };
+ image2d<unsigned> out;
+ out = dt::dt(ima | pw::value(msk), make::w_window2d(ws), 50);
+
+ debug::println(ima | pw::value(msk));
+ debug::println(out);
+
+// image2d<bool> ima = io::pbm::load("../../img/c01.pbm");
+
+// image2d<value::int_u8> out2(out.domain());
+// level::stretch(out, out2);
+
+// io::pgm::save(out2, "out.pgm");
+}
Index: trunk/milena/sandbox/folio/dt.spe.hh
===================================================================
--- trunk/milena/sandbox/folio/dt.spe.hh (revision 0)
+++ trunk/milena/sandbox/folio/dt.spe.hh (revision 1908)
@@ -0,0 +1,123 @@
+/*!
+ * \file test_psn.spe.hh
+ * \author ornthalas <ornthalas(a)gmail.com>
+ */
+
+#ifndef DT_SPE_HH
+# define DT_SPE_HH
+
+# ifndef DT_HH
+# error "Forbidden inclusion of *.spe.hh"
+# endif // ! DT_HH
+
+# include "canevas_dt.hh"
+
+namespace mln
+{
+
+ namespace dt
+ {
+
+ template<typename I, typename N, typename L>
+ inline
+ mln_ch_value(I, L)
+ dt(const Image<I>& input_, const N& nbh, unsigned max);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ namespace impl
+ {
+
+
+ // Fwd decl of the Generic version.
+
+ namespace generic
+ {
+
+ template<typename I, typename N, typename L>
+ inline
+ mln_ch_value(I, L)
+ dt_(const Image<I>& input_, const N& nbh, unsigned max);
+
+ } // end of namespace mln::dt::impl::generic
+
+
+ // Fastest functor.
+
+ template <typename I_, typename N_, typename L_>
+ struct dt_fasfunctor
+ {
+ typedef I_ I;
+ typedef N_ N;
+ typedef L_ L;
+
+ const I& input;
+ const N& nbh;
+ unsigned max;
+
+ dt_fasfunctor(const I_& input, const N_& nbh, const unsigned max)
+ : input(input),
+ nbh(nbh),
+ max(max)
+ {}
+
+ void init() {}
+ };
+
+
+ // Fastest implementation.
+
+ namespace fastest
+ {
+
+ template<typename I, typename N, typename L>
+ inline
+ mln_ch_value(I, L)
+ dt_(const I& input, const N& nbh, unsigned max)
+ {
+ trace::entering("dt::impl::dt_fas");
+
+ typedef dt_fasfunctor<I,N,L> F;
+ F f(input, nbh, max);
+ canvas::dt_fastest<F> run(f);
+
+ trace::exiting("dt::impl::dt_fas");
+ return run.output;
+ }
+
+ } // end of namespace mln::dt::impl::fastest
+
+
+ // Disjunction between "fastest" and "not fastest".
+
+ template<typename I, typename N, typename L>
+ inline
+ mln_ch_value(I, L)
+ dt_(trait::image::speed::any,
+ const I& input, const N& nbh, unsigned max)
+ {
+ return generic::dt_(input, nbh, max);
+ }
+
+ template<typename I, typename N, typename L>
+ inline
+ mln_ch_value(I, L)
+ dt_(trait::image::speed::fastest,
+ const I& input, const N& nbh, unsigned max)
+ {
+ return fastest::dt_(input, nbh, max);
+ }
+
+
+ } // end of namespace mln::dt::impl
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::dt
+
+} // end of namespace mln
+
+
+#endif // !DT_SPE_HH
1
0
https://svn.lrde.epita.fr/svn/oln/trunk/milena
Index: ChangeLog
from Nicolas Ballas <ballas(a)lrde.epita.fr>
Run image encoded by values: fix some mistakes.
* tests/core/value_enc_image.cc: Update.
* mln/core/value_enc_image.hh: Fix mistakes.
mln/core/value_enc_image.hh | 7 +++----
tests/core/value_enc_image.cc | 34 ++++++++++++++++++++++++++++++++--
2 files changed, 35 insertions(+), 6 deletions(-)
Index: tests/core/value_enc_image.cc
--- tests/core/value_enc_image.cc (revision 1906)
+++ tests/core/value_enc_image.cc (working copy)
@@ -32,16 +32,46 @@
#include <mln/core/image2d.hh>
#include <mln/core/value_enc_image.hh>
+#include <iostream>
int main()
{
using namespace mln;
- /// Basic tests
+ /// Basic test
{
typedef value_enc_image<point2d, int> ima_type;
+ typedef p_runs_<point2d> runs;
- ima_type ima();
+ p_runs_<point2d> pruns0;
+ p_runs_<point2d> pruns1;
+ p_runs_<point2d> pruns2;
+
+ pruns0.insert(p_run<point2d>(make::point2d(0, 0), 2));
+ pruns1.insert(p_run<point2d>(make::point2d(2, 4), 7));
+ pruns1.insert(p_run<point2d>(make::point2d(18, 42), 5));
+ pruns1.insert(p_run<point2d>(make::point2d(50, 76), 2));
+ pruns1.insert(p_run<point2d>(make::point2d(17,40), 6));
+ pruns2.insert(p_run<point2d>(make::point2d(10,10), 5));
+
+ ima_type ima;
+ ima.insert(pruns0, 0);
+ ima.insert(pruns2, 2);
+ ima.insert(pruns1, 1);
+
+ mln_piter_(ima_type) piter (ima.domain());
+ int i = 0;
+ int nb = 0;
+ for_all(piter)
+ {
+ assert(ima(piter) == i);
+
+ ++nb;
+ if (nb == 2)
+ i = 2;
+ if (nb == 7)
+ i = 1;
+ }
}
}
Index: mln/core/value_enc_image.hh
--- mln/core/value_enc_image.hh (revision 1906)
+++ mln/core/value_enc_image.hh (working copy)
@@ -72,7 +72,7 @@
template <typename P, typename T>
struct image_< value_enc_image<P,T> > :
- default_image_< T, rle_image<P,T> >
+ default_image_< T, value_enc_image<P,T> >
{
typedef trait::image::category::primary category;
@@ -98,7 +98,7 @@
*/
template <typename P, typename T>
class value_enc_image :
- public internal::image_primary_< pset_array_psite< runs_psite<P> >,
+ public internal::image_primary_< pset_array< p_runs_<P> >,
value_enc_image<P, T> >
{
public:
@@ -116,7 +116,6 @@
/// Skeleton.
typedef value_enc_image< tag::psite_<P>, tag::value_<T> > skeleton;
-
value_enc_image();
/// Add a new range to the image.
@@ -202,7 +201,7 @@
bool
value_enc_image<P, T>::has(const typename value_enc_image<P, T>::psite& site) const
{
- return this->data_.domain_.has(site);
+ return this->data_->domain_.has(site);
}
template <typename P, typename T>
1
0
https://svn.lrde.epita.fr/svn/oln/trunk/milena
Index: ChangeLog
from Nicolas Ballas <ballas(a)lrde.epita.fr>
Add run image type encoded by image type.
* tests/core/value_enc_image.cc: tests.
* mln/core/pset_array.hh: Fix a mistake.
* mln/core/value_enc_image.hh: New image type.
mln/core/pset_array.hh | 4
mln/core/value_enc_image.hh | 243 ++++++++++++++++++++++++++++++++++++++++++
tests/core/value_enc_image.cc | 47 ++++++++
3 files changed, 292 insertions(+), 2 deletions(-)
Index: tests/core/value_enc_image.cc
--- tests/core/value_enc_image.cc (revision 0)
+++ tests/core/value_enc_image.cc (revision 0)
@@ -0,0 +1,47 @@
+// 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/core/rle_image.cc
+ *
+ * \brief Test on mln::core::value_enc_image.hh.
+ */
+
+#include <mln/core/image2d.hh>
+#include <mln/core/value_enc_image.hh>
+
+
+int main()
+{
+ using namespace mln;
+
+ /// Basic tests
+ {
+ typedef value_enc_image<point2d, int> ima_type;
+
+ ima_type ima();
+ }
+}
Index: mln/core/pset_array.hh
--- mln/core/pset_array.hh (revision 1905)
+++ mln/core/pset_array.hh (working copy)
@@ -129,8 +129,8 @@
bool
pset_array<Pset>::has(const typename pset_array<Pset>::psite& ps) const
{
- mln_precondition(ps.to_index() < con_.size());
- return con_[ps.to_index()].has(ps.to_psite());
+ return ps.to_index() < con_.size() &&
+ con_[ps.to_index()].has(ps.to_psite());
}
template <typename Pset>
Index: mln/core/value_enc_image.hh
--- mln/core/value_enc_image.hh (revision 0)
+++ mln/core/value_enc_image.hh (revision 0)
@@ -0,0 +1,243 @@
+// 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
+// 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_VALUE_ENC_IMAGE_CC_
+# define MLN_CORE_VALUE_ENC_IMAGE_CC_
+
+/*! \file mln/core/value_enc_image.hh
+ *
+ * \brief FIXME
+ */
+
+# include <mln/core/internal/image_primary.hh>
+
+# include <mln/core/pset_array.hh>
+# include <mln/core/pset_array_psite.hh>
+# include <mln/core/p_runs.hh>
+
+# include <vector>
+
+namespace mln
+{
+
+ // Fwd decl.
+ template <typename P, typename T> struct value_enc_image;
+
+
+ namespace internal
+ {
+
+ /// \internal Data structure for \c mln::rle_image<P,T>.
+ template <typename P, typename T>
+ struct data_< value_enc_image<P, T> >
+ {
+ data_();
+
+ /// Image values.
+ std::vector<T> values_;
+
+ /// domain of the image
+ pset_array< p_runs_<P> > domain_;
+ };
+
+ } // end of namespace mln::internal
+
+
+ namespace trait
+ {
+
+ template <typename P, typename T>
+ struct image_< value_enc_image<P,T> > :
+ default_image_< T, rle_image<P,T> >
+ {
+ typedef trait::image::category::primary category;
+
+ typedef trait::image::access::browsing access;
+
+ // FIXME: Put the right dimension.
+ 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::linear data;
+ typedef trait::image::io::read_only io;
+ typedef trait::image::speed::slow speed;
+ };
+
+ } // end of namespace mln::trait
+
+
+ /*! \brief Value encoded image.
+ * FIXME
+ */
+ template <typename P, typename T>
+ class value_enc_image :
+ public internal::image_primary_< pset_array_psite< runs_psite<P> >,
+ value_enc_image<P, T> >
+ {
+ public:
+
+ /// Value related typedefs
+ typedef T value;
+ typedef T& lvalue;
+ typedef const T rvalue;
+ typedef mln::value::set<T> vset;
+
+ /// Domain related typedefs
+ typedef pset_array_psite< runs_psite<P> > psite;
+ typedef pset_array< p_runs_<P> > pset;
+
+ /// Skeleton.
+ typedef value_enc_image< tag::psite_<P>, tag::value_<T> > skeleton;
+
+
+ value_enc_image();
+
+ /// Add a new range to the image.
+ void insert(const p_runs_<P>& pr, T value);
+
+ /*! \brief Tell if the image has the given point site.
+ *
+ * \return True if the image has the point site, else false.
+ */
+ bool has(const psite& ps) const;
+
+ /// Read-only access to the image value located at the site \site.
+ rvalue operator() (const psite& site) const;
+
+ /// Read-write access to the image value located at the site \site.
+ lvalue operator() (const psite& site);
+
+ /// Test if this image has been initialized.
+ bool has_data() const;
+
+ /// Give the set of values of the image.
+ const vset& values() const;
+
+ /// Give the definition domain.
+ const pset& domain() const;
+
+ };
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ namespace internal
+ {
+
+ // internal::data_< value_enc_image<P, T> >
+
+ template <typename P, typename T>
+ inline
+ data_< value_enc_image<P,T> >::data_()
+ {
+ }
+
+ } // end of namespace mln::internal
+
+
+ template <typename P, typename T>
+ inline
+ value_enc_image<P, T>::value_enc_image()
+ {
+ this->data_ = new internal::data_< value_enc_image<P,T> >();
+ }
+
+ template <typename P, typename T>
+ inline
+ bool
+ value_enc_image<P, T>::has_data() const
+ {
+ return this->data_->values_.size() != 0;
+ }
+
+ template <typename P, typename T>
+ inline
+ const typename value_enc_image<P, T>::vset&
+ value_enc_image<P, T>::values() const
+ {
+ return vset::the();
+ }
+
+ template <typename P, typename T>
+ inline
+ void
+ value_enc_image<P, T>::insert(const p_runs_<P>& pr, T value)
+ {
+ if (!this->has_data())
+ this->data_ = new internal::data_< value_enc_image<P,T> >();
+
+ this->data_->domain_.insert(pr);
+ this->data_->values_.push_back(value);
+ }
+
+ template <typename P, typename T>
+ inline
+ bool
+ value_enc_image<P, T>::has(const typename value_enc_image<P, T>::psite& site) const
+ {
+ return this->data_.domain_.has(site);
+ }
+
+ template <typename P, typename T>
+ inline
+ typename value_enc_image<P, T>::rvalue
+ value_enc_image<P, T>::operator() (const typename value_enc_image<P, T>::psite& site)
+ const
+ {
+ mln_precondition(this->has(site));
+
+ return this->data_->values_[site.to_index()];
+ }
+
+ template <typename P, typename T>
+ inline
+ typename value_enc_image<P, T>::lvalue
+ value_enc_image<P, T>::operator() (const typename value_enc_image<P, T>::psite& site)
+ {
+ mln_precondition(this->has(site));
+
+ return this->data_->values_[site.to_index()];
+ }
+
+ template <typename P, typename T>
+ inline
+ const typename value_enc_image<P, T>::pset&
+ value_enc_image<P, T>::domain() const
+ {
+ return this->data_->domain_;
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+
+} // end of namespace mln
+
+
+#endif // ! MLN_CORE_VALUE_ENC_IMAGE_CC_
1
0
29 Apr '08
https://svn.lrde.epita.fr/svn/oln/trunk/milena
Index: ChangeLog
from Roland Levillain <roland(a)lrde.epita.fr>
Speed up iterations on graph windows and neighborhoods.
* mln/core/internal/graph_vicinity_piter.hh
(mln::internal::graph_vicinity_piter_<P, E>::graph_vicinity_piter_):
Make this ctor protected.
No longer invalidate the iterator.
(mln::internal::graph_vicinity_piter_<P, E>::is_valid)
(mln::internal::graph_vicinity_piter_<P, E>::invalidate)
(mln::internal::graph_vicinity_piter_<P, E>::adjacent_to_p_ref_)
(mln::internal::graph_vicinity_piter_<P, E>::adjacent_or_equal_to_p_ref_)
(mln::internal::graph_vicinity_piter_<P, E>::update_):
Remove.
(mln::internal::graph_vicinity_piter_<P, E>::p_ref)
(mln::internal::graph_vicinity_piter_<P, E>::pg)
(mln::internal::graph_vicinity_piter_<P, E>::sites):
New accessors.
(mln::internal::graph_vicinity_piter_<P, E>::saved_p_ref_)
(mln::internal::graph_vicinity_piter_<P, E>::p_ref_):
New members.
* mln/core/graph_window_piter.hh
(mln::graph_window_fwd_piter<P>::is_valid)
(mln::graph_window_fwd_piter<P>::invalidate)
(mln::graph_window_fwd_piter<P>::update)
(mln::graph_window_bkd_piter<P>::is_valid)
(mln::graph_window_bkd_piter<P>::invalidate)
(mln::graph_window_bkd_piter<P>::update):
New methods.
(mln::graph_window_fwd_piter<P>::first_)
(mln::graph_window_fwd_piter<P>::step_)
(mln::graph_window_bkd_piter<P>::first_)
(mln::graph_window_bkd_piter<P>::step_):
Remove methods.
(mln::graph_window_fwd_piter<P>::i_)
(mln::graph_window_bkd_piter<P>::i_):
New members.
(mln::graph_window_fwd_piter<P>::graph_window_fwd_piter)
(mln::graph_window_bkd_piter<P>::graph_window_bkd_piter):
Invalidate member i_.
(mln::graph_window_fwd_piter<P>::start)
(mln::graph_window_fwd_piter<P>::next)
(mln::graph_window_bkd_piter<P>::start)
(mln::graph_window_bkd_piter<P>::next):
Change the algorithms used in these routines, so that they use a
list of computed sites (super member sites_) instead of iterating
over the whole set of vertices.
* mln/core/graph_neighborhood_piter.hh:
(mln::graph_neighborhood_fwd_piter<P>::is_valid)
(mln::graph_neighborhood_fwd_piter<P>::invalidate)
(mln::graph_neighborhood_fwd_piter<P>::update)
(mln::graph_neighborhood_bkd_piter<P>::is_valid)
(mln::graph_neighborhood_bkd_piter<P>::invalidate)
(mln::graph_neighborhood_bkd_piter<P>::update):
New methods.
(mln::graph_neighborhood_fwd_piter<P>::first_)
(mln::graph_neighborhood_fwd_piter<P>::step_)
(mln::graph_neighborhood_bkd_piter<P>::first_)
(mln::graph_neighborhood_bkd_piter<P>::step_):
Remove methods.
(mln::graph_neighborhood_fwd_piter<P>::i_)
(mln::graph_neighborhood_bkd_piter<P>::i_):
New members.
(mln::graph_neighborhood_fwd_piter<P>::graph_neighborhood_fwd_piter)
(mln::graph_neighborhood_bkd_piter<P>::graph_neighborhood_bkd_piter):
Invalidate member i_.
(mln::graph_neighborhood_fwd_piter<P>::start)
(mln::graph_neighborhood_fwd_piter<P>::next)
(mln::graph_neighborhood_bkd_piter<P>::start)
(mln::graph_neighborhood_bkd_piter<P>::next):
Change the algorithms used in these routines, so that they use a
list of computed sites (super member sites_) instead of iterating
over the whole set of vertices.
* mln/core/graph_elt_window.hh: Catch up with the new
interface of piters on line graph windows.
(mln::graph_elt_window<P>::sites_t): New typedef.
(mln::graph_elt_window<P>::graph_elt_window): Remove useless ctor.
(mln::graph_elt_window<P>::start)
(mln::graph_elt_window<P>::next_):
Remove methods.
(mln::graph_elt_window<P>::compute_sites_):
New method.
* mln/core/graph_elt_neighborhood.hh: Catch up with the new
interface of piters on line graph neighborhoods.
(mln::graph_elt_neighborhood::neighbors_t):
New typedef.
(mln::graph_elt_neighborhood::start)
(mln::graph_elt_neighborhood::next_):
Remove methods.
(mln::graph_elt_neighborhood<P>::compute_sites_):
New method.
graph_elt_neighborhood.hh | 54 +++++++------
graph_elt_window.hh | 62 +++++++--------
graph_neighborhood_piter.hh | 153 ++++++++++++++++++++++++++-------------
graph_window_piter.hh | 151 +++++++++++++++++++++++++-------------
internal/graph_vicinity_piter.hh | 109 +++++++++++----------------
5 files changed, 306 insertions(+), 223 deletions(-)
Index: mln/core/internal/graph_vicinity_piter.hh
--- mln/core/internal/graph_vicinity_piter.hh (revision 1904)
+++ mln/core/internal/graph_vicinity_piter.hh (working copy)
@@ -32,6 +32,11 @@
/// \brief Factored implementation for point iterators on a graph windows
/// and graph neighborhoods, called "vicinities".
+/* FIXME: Factor those classes:
+
+ - mln::internal::graph_vicinity_piter.hh
+ - mln::internal::line_graph_vicinity_piter.hh */
+
# include <mln/core/concept/point_iterator.hh>
# include <mln/core/p_graph.hh>
# include <mln/core/graph_psite.hh>
@@ -72,28 +77,10 @@
// FIXME: Dummy value.
typedef void mesh;
- public:
- /// Construction.
- /// \{
- template <typename Pref>
- graph_vicinity_piter_(const Point_Site<Pref>& p_ref);
- /// \}
-
- /// Manipulation.
- /// \{
- /// Test if the iterator is valid.
- bool is_valid() const;
- /// Invalidate the iterator.
- void invalidate();
-
- /// Is the piter adjacent to the reference point?
- bool adjacent_to_p_ref_() const;
- /// Is the piter adjacent or equal to the reference point?
- bool adjacent_or_equal_to_p_ref_() const;
- /// Update the internal data of the iterator.
- void update_();
- /// \}
+ // The type of the set of vicinity sites (adjacent vertex ids).
+ typedef std::set<util::node_id> sites_t;
+ public:
/// Conversion and accessors.
/// \{
/// Reference to the corresponding point.
@@ -103,10 +90,24 @@
/// Convert the iterator into a line graph psite.
operator psite() const;
+ /// Return the reference psite.
+ const psite& p_ref() const;
+ /// Return the mln::p_graph corresponding to this piter.
+ const p_graph<P>& pg() const;
+ /// Return the set of sites (adjacent vertex ids).
+ sites_t& sites();
+
/// Read-only access to the \a i-th coordinate.
coord operator[](unsigned i) const;
/// \}
+ protected:
+ /// Construction.
+ /// \{
+ template <typename Pref>
+ graph_vicinity_piter_(const Point_Site<Pref>& p_ref);
+ /// \}
+
/// Internals, used by the vicinity.
/// \{
public:
@@ -120,7 +121,11 @@
/// piter).
const psite& p_ref_;
- private:
+ /// The last reference psite whose ajacent psites have been computed.
+ psite saved_p_ref_;
+ /// The set of edge ids adjacent to the reference psite.
+ sites_t sites_;
+
/// The psite corresponding to this iterator.
psite psite_;
/// The point corresponding to this iterator.
@@ -140,78 +145,54 @@
psite_(),
p_()
{
- // Invalidate id_.
- invalidate();
- }
-
- template <typename P, typename E>
- inline
- bool
- graph_vicinity_piter_<P, E>::is_valid() const
- {
- /* FIXME: We depend too much on the implementation of
- util::graph here. The util::graph should provide the service
- to abstract these manipulations. */
- return p_ref_.is_valid() && id_ < p_ref_.pg().npoints();
- }
-
- template <typename P, typename E>
- inline
- void
- graph_vicinity_piter_<P, E>::invalidate()
- {
- id_ = -1;
}
template <typename P, typename E>
inline
- bool
- graph_vicinity_piter_<P, E>::adjacent_to_p_ref_() const
+ const P&
+ graph_vicinity_piter_<P, E>::to_point() const
{
- return p_ref_.pg().adjacent(p_ref_.id(), id_);
+ return p_;
}
template <typename P, typename E>
inline
- bool
- graph_vicinity_piter_<P, E>::adjacent_or_equal_to_p_ref_() const
+ const graph_psite<P>&
+ graph_vicinity_piter_<P, E>::to_psite() const
{
- return p_ref_.pg().adjacent_or_equal(p_ref_.id(), id_);
+ return psite_;
}
template <typename P, typename E>
inline
- void
- graph_vicinity_piter_<P, E>::update_()
+ graph_vicinity_piter_<P, E>::operator graph_psite<P>() const
{
- // Update psite_.
- psite_ = graph_psite<P>(p_ref_.pg(), id_);
- // Update p_.
- p_ = p_ref_.pg().point_from_id(id_);
+ mln_precondition(exact(*this).is_valid());
+ return psite_;
}
template <typename P, typename E>
inline
- const P&
- graph_vicinity_piter_<P, E>::to_point() const
+ const graph_psite<P>&
+ graph_vicinity_piter_<P, E>::p_ref() const
{
- return p_;
+ return p_ref_;
}
template <typename P, typename E>
inline
- const graph_psite<P>&
- graph_vicinity_piter_<P, E>::to_psite() const
+ const p_graph<P>&
+ graph_vicinity_piter_<P, E>::pg() const
{
- return psite_;
+ return p_ref_.pg();
}
template <typename P, typename E>
inline
- graph_vicinity_piter_<P, E>::operator graph_psite<P>() const
+ std::set<util::node_id>&
+ graph_vicinity_piter_<P, E>::sites()
{
- mln_precondition(is_valid());
- return psite_;
+ return sites_;
}
template <typename P, typename E>
Index: mln/core/graph_window_piter.hh
--- mln/core/graph_window_piter.hh (revision 1904)
+++ mln/core/graph_window_piter.hh (working copy)
@@ -31,17 +31,6 @@
/// \file mln/core/graph_window_piter.hh
/// \brief Definition of a point iterator on a graph window.
-/* FIXME: Factor those classes:
-
- - mln::graph_window_fwd_piter
- - mln::graph_neighborhood_fwd_piter
- - mln::line_graph_window_fwd_piter
- - mln::line_graph_neighborhood_fwd_piter.
- - mln::graph_window_bkd_piter
- - mln::graph_neighborhood_bkd_piter
- - mln::line_graph_window_bkd_piter
- - mln::line_graph_neighborhood_bkd_piter. */
-
# include <mln/core/internal/graph_vicinity_piter.hh>
/* FIXME: Due to the poor interface of mln::p_graph and
@@ -72,23 +61,25 @@
/// Manipulation.
/// \{
+ /// Test if the iterator is valid.
+ bool is_valid() const;
+ /// Invalidate the iterator.
+ void invalidate();
/// Start an iteration.
void start();
+
/// Go to the next point.
void next_();
- /// \}
-
- /// Internals, used by the window.
- /// \{
- /// Set the iterator to the first site of the graph.
- void first_();
- /// Advance the position of the iterator by one step.
- void step_();
+ /// Update the internal data of the iterator.
+ void update_();
/// \}
private:
/// The window.
const W& win_;
+
+ /// An iterator on the set of adjacent vertices.
+ typename super_::sites_t::const_iterator i_;
};
@@ -113,23 +104,25 @@
/// Manipulation.
/// \{
+ /// Test if the iterator is valid.
+ bool is_valid() const;
+ /// Invalidate the iterator.
+ void invalidate();
/// Start an iteration.
void start();
+
/// Go to the next point.
void next_();
- /// \}
-
- /// Internals, used by the window.
- /// \{
- /// Set the iterator to the first site of the graph.
- void first_();
- /// Advance the position of the iterator by one step.
- void step_();
+ /// Update the internal data of the iterator.
+ void update_();
/// \}
private:
/// The window.
const W& win_;
+
+ /// An iterator on the set of adjacent vertices.
+ typename super_::sites_t::const_reverse_iterator i_;
};
@@ -148,42 +141,70 @@
: super_(p_ref),
win_(exact(win))
{
+ // Invalidate i_.
+ invalidate();
+ }
+
+ template <typename P, typename W>
+ inline
+ bool
+ graph_window_fwd_piter<P, W>::is_valid() const
+ {
+ return
+ // The reference point must be valid...
+ this->p_ref_.is_valid()
+ // ...and must not have changed since the window has been computed...
+ && this->p_ref_ == this->saved_p_ref_
+ // ...and the iterator i_ must point a valid value.
+ && i_ != this->sites_.end();
}
template <typename P, typename W>
inline
void
- graph_window_fwd_piter<P, W>::start()
+ graph_window_fwd_piter<P, W>::invalidate()
{
- this->win_.start(*this);
- if (this->is_valid())
- this->update_();
+ i_ = this->sites_.end();
}
template <typename P, typename W>
inline
void
- graph_window_fwd_piter<P, W>::next_()
+ graph_window_fwd_piter<P, W>::start()
{
- this->win_.next_(*this);
- if (this->is_valid())
- this->update_();
+ mln_precondition(this->p_ref_.is_valid());
+ // Update the sites, if needed.
+ if (!this->saved_p_ref_.is_valid() || this->p_ref_ != this->saved_p_ref_)
+ {
+ this->saved_p_ref_ = this->p_ref_;
+ win_.compute_sites_(*this);
+ }
+ i_ = this->sites_.begin();
+ // FIXME: We might move the is_valid condition within update_.
+ if (is_valid())
+ update_();
}
template <typename P, typename W>
inline
void
- graph_window_fwd_piter<P, W>::first_()
+ graph_window_fwd_piter<P, W>::next_()
{
- this->id_ = 0;
+ // Ensure the p_ref_ has not changed.
+ mln_precondition(this->p_ref_ == this->saved_p_ref_);
+ ++i_;
+ // FIXME: We might move the is_valid condition within update_.
+ if (is_valid())
+ update_();
}
template <typename P, typename W>
inline
void
- graph_window_fwd_piter<P, W>::step_()
+ graph_window_fwd_piter<P, W>::update_()
{
- ++this->id_;
+ // Update psite_.
+ this->psite_ = graph_psite<P>(this->pg(), *i_);
}
@@ -199,42 +220,70 @@
: super_(p_ref),
win_(exact(win))
{
+ // Invalidate i_.
+ invalidate();
+ }
+
+ template <typename P, typename W>
+ inline
+ bool
+ graph_window_bkd_piter<P, W>::is_valid() const
+ {
+ return
+ // The reference point must be valid...
+ this->p_ref_.is_valid()
+ // ...and must not have changed since the window has been computed...
+ && this->p_ref_ == this->saved_p_ref_
+ // ...and the iterator i_ must point a valid value.
+ && i_ != this->sites_.rend();
}
template <typename P, typename W>
inline
void
- graph_window_bkd_piter<P, W>::start()
+ graph_window_bkd_piter<P, W>::invalidate()
{
- this->win_.start(*this);
- if (this->is_valid())
- this->update_();
+ i_ = this->sites_.rend();
}
template <typename P, typename W>
inline
void
- graph_window_bkd_piter<P, W>::next_()
+ graph_window_bkd_piter<P, W>::start()
+ {
+ mln_precondition(this->p_ref_.is_valid());
+ // Update the sites, if needed.
+ if (!this->saved_p_ref_.is_valid() || this->p_ref_ != this->saved_p_ref_)
{
- this->win_.next_(*this);
- if (this->is_valid())
- this->update_();
+ this->saved_p_ref_ = this->p_ref_;
+ win_.compute_sites_(*this);
+ }
+ i_ = this->sites_.rbegin();
+ // FIXME: We might move the is_valid condition within update_.
+ if (is_valid())
+ update_();
}
template <typename P, typename W>
inline
void
- graph_window_bkd_piter<P, W>::first_()
+ graph_window_bkd_piter<P, W>::next_()
{
- this->id_ = this->p_ref_.pg().gr_->nnodes() - 1;
+ // Ensure the p_ref_ has not changed.
+ mln_precondition(this->p_ref_ == this->saved_p_ref_);
+ ++i_;
+ // FIXME: We might move the is_valid condition within update_.
+ if (is_valid())
+ update_();
}
template <typename P, typename W>
inline
void
- graph_window_bkd_piter<P, W>::step_()
+ graph_window_bkd_piter<P, W>::update_()
{
- --this->id_;
+ // Update psite_.
+ this->psite_ = graph_psite<P>(this->pg(), *i_);
}
# endif // ! MLN_INCLUDE_ONLY
Index: mln/core/graph_neighborhood_piter.hh
--- mln/core/graph_neighborhood_piter.hh (revision 1904)
+++ mln/core/graph_neighborhood_piter.hh (working copy)
@@ -31,17 +31,6 @@
/// \file mln/core/graph_neighborhood_piter.hh
/// \brief Definition of a point iterator on a graph neighborhood.
-/* FIXME: Factor those classes:
-
- - mln::graph_window_fwd_piter
- - mln::graph_neighborhood_fwd_piter
- - mln::line_graph_window_fwd_piter
- - mln::line_graph_neighborhood_fwd_piter.
- - mln::graph_window_bkd_piter
- - mln::graph_neighborhood_bkd_piter
- - mln::line_graph_window_bkd_piter
- - mln::line_graph_neighborhood_bkd_piter. */
-
# include <mln/core/internal/graph_vicinity_piter.hh>
/* FIXME: Due to the poor interface of mln::p_graph and
@@ -73,23 +62,25 @@
/// Manipulation.
/// \{
+ /// Test if the iterator is valid.
+ bool is_valid() const;
+ /// Invalidate the iterator.
+ void invalidate();
/// Start an iteration.
void start();
+
/// Go to the next point.
void next_();
- /// \}
-
- /// Internals, used by the neighborhood.
- /// \{
- /// Set the iterator to the first site of the graph.
- void first_();
- /// Advance the position of the iterator by one step.
- void step_();
+ /// Update the internal data of the iterator.
+ void update_();
/// \}
private:
/// The neighborhood.
const N& nbh_;
+
+ /// An iterator on the set of adjacent edges.
+ typename super_::sites_t::const_iterator i_;
};
@@ -115,23 +106,25 @@
/// Manipulation.
/// \{
+ /// Test if the iterator is valid.
+ bool is_valid() const;
+ /// Invalidate the iterator.
+ void invalidate();
/// Start an iteration.
void start();
+
/// Go to the next point.
void next_();
- /// \}
-
- /// Internals, used by the neighborhood.
- /// \{
- /// Set the iterator to the first site of the graph.
- void first_();
- /// Advance the position of the iterator by one step.
- void step_();
+ /// Update the internal data of the iterator.
+ void update_();
/// \}
private:
/// The neighborhood.
const N& nbh_;
+
+ /// An iterator on the set of adjacent edges.
+ typename super_::sites_t::const_reverse_iterator i_;
};
@@ -150,42 +143,71 @@
: super_(p_ref),
nbh_(exact(nbh))
{
+ // Invalidate i_.
+ invalidate();
+ }
+
+ template <typename P, typename N>
+ inline
+ bool
+ graph_neighborhood_fwd_piter<P, N>::is_valid() const
+ {
+ return
+ // The reference point must be valid...
+ this->p_ref_.is_valid()
+ // ...and must not have changed since the neighborhood has been
+ // computed...
+ && this->p_ref_ == this->saved_p_ref_
+ // ...and the iterator i_ must point a valid value.
+ && i_ != this->sites_.end();
}
template <typename P, typename N>
inline
void
- graph_neighborhood_fwd_piter<P, N>::start()
+ graph_neighborhood_fwd_piter<P, N>::invalidate()
{
- this->nbh_.start(*this);
- if (this->is_valid())
- this->update_();
+ i_ = this->sites_.end();
}
template <typename P, typename N>
inline
void
- graph_neighborhood_fwd_piter<P, N>::next_()
+ graph_neighborhood_fwd_piter<P, N>::start()
{
- this->nbh_.next_(*this);
- if (this->is_valid())
- this->update_();
+ mln_precondition(this->p_ref_.is_valid());
+ // Update the neighbors, if needed.
+ if (!this->saved_p_ref_.is_valid() || this->p_ref_ != this->saved_p_ref_)
+ {
+ this->saved_p_ref_ = this->p_ref_;
+ nbh_.compute_sites_(*this);
+ }
+ i_ = this->sites_.begin();
+ // FIXME: We might move the is_valid condition within update_.
+ if (is_valid())
+ update_();
}
template <typename P, typename N>
inline
void
- graph_neighborhood_fwd_piter<P, N>::first_()
+ graph_neighborhood_fwd_piter<P, N>::next_()
{
- this->id_ = 0;
+ // Ensure the p_ref_ has not changed.
+ mln_precondition(this->p_ref_ == this->saved_p_ref_);
+ ++i_;
+ // FIXME: We might move the is_valid condition within update_.
+ if (is_valid())
+ update_();
}
template <typename P, typename N>
inline
void
- graph_neighborhood_fwd_piter<P, N>::step_()
+ graph_neighborhood_fwd_piter<P, N>::update_()
{
- ++this->id_;
+ // Update psite_.
+ this->psite_ = graph_psite<P>(this->pg(), *i_);
}
@@ -201,42 +223,71 @@
: super_(p_ref),
nbh_(exact(nbh))
{
+ // Invalidate i_.
+ invalidate();
+ }
+
+ template <typename P, typename N>
+ inline
+ bool
+ graph_neighborhood_bkd_piter<P, N>::is_valid() const
+ {
+ return
+ // The reference point must be valid...
+ this->p_ref_.is_valid()
+ // ...and must not have changed since the neighborhood has been
+ // computed...
+ && this->p_ref_ == this->saved_p_ref_
+ // ...and the iterator i_ must point a valid value.
+ && i_ != this->sites_.rend();
}
template <typename P, typename N>
inline
void
- graph_neighborhood_bkd_piter<P, N>::start()
+ graph_neighborhood_bkd_piter<P, N>::invalidate()
{
- this->nbh_.start(*this);
- if (this->is_valid())
- this->update_();
+ i_ = this->sites_.rend();
}
template <typename P, typename N>
inline
void
- graph_neighborhood_bkd_piter<P, N>::next_()
+ graph_neighborhood_bkd_piter<P, N>::start()
+ {
+ mln_precondition(this->p_ref_.is_valid());
+ // Update the neighbors, if needed.
+ if (!this->saved_p_ref_.is_valid() || this->p_ref_ != this->saved_p_ref_)
{
- this->nbh_.next_(*this);
- if (this->is_valid())
- this->update_();
+ this->saved_p_ref_ = this->p_ref_;
+ nbh_.compute_sites_(*this);
+ }
+ i_ = this->sites_.rbegin();
+ // FIXME: We might move the is_valid condition within update_.
+ if (is_valid())
+ update_();
}
template <typename P, typename N>
inline
void
- graph_neighborhood_bkd_piter<P, N>::first_()
+ graph_neighborhood_bkd_piter<P, N>::next_()
{
- this->id_ = this->p_ref_.pg().gr_->nnodes() - 1;
+ // Ensure the p_ref_ has not changed.
+ mln_precondition(this->p_ref_ == this->saved_p_ref_);
+ ++i_;
+ // FIXME: We might move the is_valid condition within update_.
+ if (is_valid())
+ update_();
}
template <typename P, typename N>
inline
void
- graph_neighborhood_bkd_piter<P, N>::step_()
+ graph_neighborhood_bkd_piter<P, N>::update_()
{
- --this->id_;
+ // Update psite_.
+ this->psite_ = graph_psite<P>(this->pg(), *i_);
}
# endif // ! MLN_INCLUDE_ONLY
Index: mln/core/graph_elt_window.hh
--- mln/core/graph_elt_window.hh (revision 1904)
+++ mln/core/graph_elt_window.hh (working copy)
@@ -40,6 +40,10 @@
- mln::line_graph_elt_window
- mln::line_graph_elt_neighborhood. */
+/* FIXME: Due to the poor interface of mln::p_line_graph and
+ mln::util::graph, we show to much implementation details here.
+ Enrich their interfaces to avoid that. */
+
# include <mln/core/concept/window.hh>
# include <mln/core/graph_psite.hh>
# include <mln/core/graph_window_piter.hh>
@@ -65,6 +69,9 @@
typedef P point;
/// The type of psite corresponding to the window.
typedef graph_psite<P> psite;
+ // The type of the set of window sites (node ids adjacent to the
+ // reference psite).
+ typedef std::set<util::node_id> sites_t;
// FIXME: This is a dummy value.
typedef void dpoint;
@@ -81,17 +88,11 @@
typedef fwd_qiter qiter;
/// \}
- /// Construct an elementary graph window.
- graph_elt_window();
-
/// Services for iterators.
/// \{
- /// Move \a piter to the beginning of the iteration on this window.
+ /// Compute the set of sites for this window around \a piter.
template <typename Piter>
- void start(Point_Iterator<Piter>& piter) const;
- /// Move \a piter to the next site on this window.
- template <typename Piter>
- void next_(Point_Iterator<Piter>& piter) const;
+ void compute_sites_(Point_Iterator<Piter>& piter) const;
/// \}
/// Interface of the concept Window.
@@ -125,37 +126,32 @@
# ifndef MLN_INCLUDE_ONLY
template <typename P>
- inline
- graph_elt_window<P>::graph_elt_window()
- {
- }
-
- template <typename P>
template <typename Piter>
inline
void
- graph_elt_window<P>::start(Point_Iterator<Piter>& piter_) const
+ graph_elt_window<P>::compute_sites_(Point_Iterator<Piter>& piter_) const
{
Piter& piter = exact(piter_);
- piter.first_();
- if (!piter.adjacent_or_equal_to_p_ref_())
- next_(piter);
+ util::node_id ref_node_id = piter.p_ref().id();
+ const util::node<P>& ref_node = piter.pg().gr_->node(ref_node_id);
+ sites_t& sites = piter.sites();
+ sites.clear();
+ /* FIXME: Move this computation out of the window. In fact,
+ this should be a service of the graph, also proposed by the
+ p_line_graph. */
+ // Adjacent vertices.
+ /* We don't need to explicitely insert the reference piter (node
+ id) itself into SITES, since it is part of the set of nodes
+ adjacent to NODE1 and NODE2, and will therefore be
+ automatically added. */
+ for (std::vector<util::edge_id>::const_iterator e = ref_node.edges.begin();
+ e != ref_node.edges.end(); ++e)
+ {
+ util::node_id n1 = piter.pg().gr_->edges()[*e]->n1();
+ sites.insert(n1);
+ util::node_id n2 = piter.pg().gr_->edges()[*e]->n2();
+ sites.insert(n2);
}
-
- template <typename P>
- template <typename Piter>
- inline
- void
- graph_elt_window<P>::next_(Point_Iterator<Piter>& piter_) const
- {
- Piter& piter = exact(piter_);
- /* FIXME: This is inefficient. The graph structure should be able
- to produce the set of adjacent nodes fast. Boost Graphs
- probably provides adequates structures to fetch these
- neighbors in constant time. */
- do
- piter.step_();
- while (piter.is_valid() && !piter.adjacent_or_equal_to_p_ref_());
}
template <typename P>
Index: mln/core/graph_elt_neighborhood.hh
--- mln/core/graph_elt_neighborhood.hh (revision 1904)
+++ mln/core/graph_elt_neighborhood.hh (working copy)
@@ -40,6 +40,10 @@
- mln::line_graph_elt_window
- mln::line_graph_elt_neighborhood. */
+/* FIXME: Due to the poor interface of mln::p_line_graph and
+ mln::util::graph, we show to much implementation details here.
+ Enrich their interfaces to avoid that. */
+
# include <mln/core/concept/neighborhood.hh>
# include <mln/core/graph_psite.hh>
# include <mln/core/graph_neighborhood_piter.hh>
@@ -66,6 +70,9 @@
typedef P point;
/// The type of psite corresponding to the neighborhood.
typedef graph_psite<P> psite;
+ // The type of the set of neighbors (node ids adjacent to the
+ // reference psite).
+ typedef std::set<util::node_id> sites_t;
// FIXME: This is a dummy value.
typedef void dpoint;
@@ -84,12 +91,9 @@
/// Services for iterators.
/// \{
- /// Move \a piter to the beginning of the iteration on this neighborhood.
- template <typename Piter>
- void start(Point_Iterator<Piter>& piter) const;
- /// Move \a piter to the next site on this neighborhood.
+ /// Compute the set of sites for this neighborhood around \a piter.
template <typename Piter>
- void next_(Point_Iterator<Piter>& piter) const;
+ void compute_sites_(Point_Iterator<Piter>& piter) const;
/// \}
};
@@ -100,28 +104,30 @@
template <typename Piter>
inline
void
- graph_elt_neighborhood<P>::start(Point_Iterator<Piter>& piter_) const
+ graph_elt_neighborhood<P>::compute_sites_(Point_Iterator<Piter>& piter_) const
{
Piter& piter = exact(piter_);
- piter.first_();
- if (!piter.adjacent_to_p_ref_())
- next_(piter);
- }
-
- template <typename P>
- template <typename Piter>
- inline
- void
- graph_elt_neighborhood<P>::next_(Point_Iterator<Piter>& piter_) const
+ util::node_id ref_node_id = piter.p_ref().id();
+ const util::node<P>& ref_node = piter.pg().gr_->node(ref_node_id);
+ sites_t& sites = piter.sites();
+ sites.clear();
+ /* FIXME: Move this computation out of the neighborhood. In fact,
+ this should be a service of the graph, also proposed by the
+ p_line_graph. */
+ // Adjacent vertices.
+ for (std::vector<util::edge_id>::const_iterator e = ref_node.edges.begin();
+ e != ref_node.edges.end(); ++e)
{
- Piter& piter = exact(piter_);
- /* FIXME: This is inefficient. The graph structure should be able
- to produce the set of adjacent nodes fast. Boost Graphs
- probably provides adequates structures to fetch these
- neighbors in constant time. */
- do
- piter.step_();
- while (piter.is_valid() && !piter.adjacent_to_p_ref_());
+ util::node_id n1 = piter.pg().gr_->edges()[*e]->n1();
+ // We explicitly enforce that the reference piter node id is
+ // *not* inserted into SITES.
+ if (n1 != ref_node_id)
+ sites.insert(n1);
+ util::node_id n2 = piter.pg().gr_->edges()[*e]->n2();
+ // Likewise.
+ if (n2 != ref_node_id)
+ sites.insert(n2);
+ }
}
# endif // ! MLN_INCLUDE_ONLY
1
0