Olena-patches
Threads by month
- ----- 2026 -----
- January
- ----- 2025 -----
- December
- 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
19 Oct '09
* mln/world/inter_pixel/neighb2d.hh
(mln::world::inter_pixel::e2c, mln::world::inter_pixel::e2e):
Here.
Wrap long lines.
---
milena/ChangeLog | 9 +++++++++
milena/mln/world/inter_pixel/neighb2d.hh | 10 ++++++----
2 files changed, 15 insertions(+), 4 deletions(-)
diff --git a/milena/ChangeLog b/milena/ChangeLog
index eb1d50a..db4d604 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -1,5 +1,14 @@
2009-09-23 Roland Levillain <roland(a)lrde.epita.fr>
+ Fix documentation in mln/world/inter_pixel/neighb2d.hh.
+
+ * mln/world/inter_pixel/neighb2d.hh
+ (mln::world::inter_pixel::e2c, mln::world::inter_pixel::e2e):
+ Here.
+ Wrap long lines.
+
+2009-09-23 Roland Levillain <roland(a)lrde.epita.fr>
+
Include headers missing from mln/world/inter_pixel/compute.hh.
* mln/world/inter_pixel/compute.hh: Include
diff --git a/milena/mln/world/inter_pixel/neighb2d.hh b/milena/mln/world/inter_pixel/neighb2d.hh
index c39bd2f..21233ef 100644
--- a/milena/mln/world/inter_pixel/neighb2d.hh
+++ b/milena/mln/world/inter_pixel/neighb2d.hh
@@ -47,10 +47,10 @@ namespace mln
/// Double neighborhood used for inter-pixel images.
typedef neighb< win::multiple<window2d, dim2::is_row_odd> > dbl_neighb2d;
- /// C4 neighborhood on pixels centered on an edge.
+ // Edge to neighborhood pixels.
const dbl_neighb2d& e2c();
- /// C8 neighborhood on edges centered on an edge.
+ // Edge to neighboring edges.
const dbl_neighb2d& e2e();
@@ -66,7 +66,8 @@ namespace mln
1, 0, 1,
0, 0, 0 };
- static dbl_neighb2d nbh = make::double_neighb2d(dim2::is_row_odd(), e2c_h, e2c_v);
+ static dbl_neighb2d nbh =
+ make::double_neighb2d(dim2::is_row_odd(), e2c_h, e2c_v);
return nbh;
}
@@ -86,7 +87,8 @@ namespace mln
0, 1, 0, 1, 0,
0, 0, 0, 0, 0 };
- static dbl_neighb2d nbh = make::double_neighb2d(dim2::is_row_odd(), e2e_h, e2e_v);
+ static dbl_neighb2d nbh =
+ make::double_neighb2d(dim2::is_row_odd(), e2e_h, e2e_v);
return nbh;
}
--
1.6.4.4
1
0
* abraham/README: New.
---
milena/sandbox/ChangeLog | 6 ++++++
milena/sandbox/abraham/README | 11 +++++++++++
2 files changed, 17 insertions(+), 0 deletions(-)
create mode 100644 milena/sandbox/abraham/README
diff --git a/milena/sandbox/ChangeLog b/milena/sandbox/ChangeLog
index cb4de1e..a069dc9 100644
--- a/milena/sandbox/ChangeLog
+++ b/milena/sandbox/ChangeLog
@@ -1,3 +1,9 @@
+2009-09-24 Roland Levillain <roland(a)lrde.epita.fr>
+
+ Annotate Alexandre's sandbox.
+
+ * abraham/README: New.
+
2009-09-22 Guillaume Lazzara <lazzara(a)lrde.epita.fr>
Fix invalid output domain in hq*x algorithms.
diff --git a/milena/sandbox/abraham/README b/milena/sandbox/abraham/README
new file mode 100644
index 0000000..a7372d7
--- /dev/null
+++ b/milena/sandbox/abraham/README
@@ -0,0 +1,11 @@
+These files have been integrated into Milena:
+
+ mln/morpho/topo_wst.hh
+ -> ../../mln/morpho/watershed/topological.hh
+
+ tests/morpho/test_watershed_topo.cc
+ -> ../../tests/morpho/watershed/topological.cc
+
+The versions contained in this sandbox should be considered obsolete
+and should not be used nor modified anymore. Actually, removing them
+might be a good option.
--
1.6.4.4
1
0
[PATCH 1/7] Include headers missing from mln/world/inter_pixel/compute.hh.
by Roland Levillain 19 Oct '09
by Roland Levillain 19 Oct '09
19 Oct '09
* mln/world/inter_pixel/compute.hh: Include
mln/core/image/dmorph/image_if.hh and mln/trait/ch_value.hh.
---
milena/ChangeLog | 7 +++++++
milena/mln/world/inter_pixel/compute.hh | 4 ++++
2 files changed, 11 insertions(+), 0 deletions(-)
diff --git a/milena/ChangeLog b/milena/ChangeLog
index 58b58ff..eb1d50a 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -1,3 +1,10 @@
+2009-09-23 Roland Levillain <roland(a)lrde.epita.fr>
+
+ Include headers missing from mln/world/inter_pixel/compute.hh.
+
+ * mln/world/inter_pixel/compute.hh: Include
+ mln/core/image/dmorph/image_if.hh and mln/trait/ch_value.hh.
+
2009-09-24 Roland Levillain <roland(a)lrde.epita.fr>
Improve the integration of the topological watershed transform.
diff --git a/milena/mln/world/inter_pixel/compute.hh b/milena/mln/world/inter_pixel/compute.hh
index 35a94e2..0d7ad12 100644
--- a/milena/mln/world/inter_pixel/compute.hh
+++ b/milena/mln/world/inter_pixel/compute.hh
@@ -32,6 +32,10 @@
# include <mln/core/concept/image.hh>
# include <mln/core/concept/function.hh>
+
+# include <mln/core/image/dmorph/image_if.hh>
+# include <mln/trait/ch_value.hh>
+
# include <mln/world/inter_pixel/is_separator.hh>
# include <mln/world/inter_pixel/separator_to_pixels.hh>
--
1.6.4.4
1
0
[PATCH 4/7] Stop using cplx2d.hh in the constrained connectivity prototype.
by Roland Levillain 19 Oct '09
by Roland Levillain 19 Oct '09
19 Oct '09
* roland/constrained-connectivity.cc: Here.
Use Milena's mln::world::inter_pixel instead.
Adjust.
* roland/theo: Remove symlink.
---
milena/sandbox/ChangeLog | 9 +++++
milena/sandbox/roland/constrained-connectivity.cc | 40 +++++++++++++--------
milena/sandbox/roland/theo | 1 -
3 files changed, 34 insertions(+), 16 deletions(-)
delete mode 120000 milena/sandbox/roland/theo
diff --git a/milena/sandbox/ChangeLog b/milena/sandbox/ChangeLog
index a069dc9..52e6334 100644
--- a/milena/sandbox/ChangeLog
+++ b/milena/sandbox/ChangeLog
@@ -1,5 +1,14 @@
2009-09-24 Roland Levillain <roland(a)lrde.epita.fr>
+ Stop using cplx2d.hh in the constrained connectivity prototype.
+
+ * roland/constrained-connectivity.cc: Here.
+ Use Milena's mln::world::inter_pixel instead.
+ Adjust.
+ * roland/theo: Remove symlink.
+
+2009-09-24 Roland Levillain <roland(a)lrde.epita.fr>
+
Annotate Alexandre's sandbox.
* abraham/README: New.
diff --git a/milena/sandbox/roland/constrained-connectivity.cc b/milena/sandbox/roland/constrained-connectivity.cc
index af5e49a..fb14d2c 100644
--- a/milena/sandbox/roland/constrained-connectivity.cc
+++ b/milena/sandbox/roland/constrained-connectivity.cc
@@ -45,7 +45,7 @@
\li Assign values of a gradient to the edges (e.g., |v1 - v2|).
\li Compute a topological watershed transform on this gradient.
\li Thresholding the values of this watershed gives
- alpha-connected component (alpha-cc) described by Pierre Soille.
+ alpha-connected components (alpha-cc) described by Pierre Soille.
Part 2.
\li For each edge of the watershed (line graph-based) image,
@@ -58,7 +58,7 @@
values from the image of max values.
\li Thresholding the watershed image (using a parameter alpha)
<em>and</em> the height image (using a parameter omega) gives
- the (alpha, omega)-connected component (alpha-omega cc)
+ the (alpha, omega)-connected components (alpha-omega cc)
described by Pierre Soille. */
#include <cstdio>
@@ -71,8 +71,10 @@
#include <mln/pw/all.hh>
-// From Théo's sandbox.
-#include <theo/cplx2d.hh>
+#include <mln/fun/vv2v/diff_abs.hh>
+#include <mln/world/inter_pixel/immerse.hh>
+#include <mln/world/inter_pixel/compute.hh>
+#include <mln/world/inter_pixel/neighb2d.hh>
// From Alexandre Abraham's sandbox.
#include <alexandre/topo_wst.hh>
@@ -84,6 +86,8 @@
#include <mln/io/pgm/load.hh>
#include <mln/debug/println.hh>
+#include <mln/core/var.hh>
+
int main(int argc, char* argv[])
{
@@ -101,8 +105,8 @@ int main(int argc, char* argv[])
io::pgm::load(input, argv[1]);
// Double its resolution.
- image2d<int_u8> f(input.nrows() * 2, input.ncols() * 2);
- mln_piter_(image2d<int_u8>) p_ima(f.domain());
+ image2d<int_u8> f_(input.nrows() * 2, input.ncols() * 2);
+ mln_piter_(image2d<int_u8>) p_ima(f_.domain());
for_all(p_ima)
{
/* This conversion from a ``piter'' type to point2d is required,
@@ -111,17 +115,22 @@ int main(int argc, char* argv[])
etc.). */
point2d p_ima_ = p_ima;
point2d p_f(p_ima_.row() / 2, p_ima_.col() / 2);
- f(p_ima) = input(p_f);
+ f_(p_ima) = input(p_f);
}
- debug::println(f);
+ debug::println("f_:", f_);
+
+ image_if<image2d<int_u8>, world::inter_pixel::is_pixel> f =
+ world::inter_pixel::immerse(f_);
+ debug::println("f:", f);
// Compute the associated line graph gradient.
- mln_VAR(g, cplx2d::f_to_g(f) );
+ mln_VAR(g, world::inter_pixel::compute (f, fun::vv2v::diff_abs<int_u8>()));
+
debug::println("g:", g);
// Compute a topological watershed transform on this gradient.
- typedef morpho::topo_wst<g_t, cplx2d::dbl_neighb2d> tree_t;
- tree_t tree(g, cplx2d::e2e());
+ typedef morpho::topo_wst<g_t, world::inter_pixel::dbl_neighb2d> tree_t;
+ tree_t tree(g, world::inter_pixel::e2e());
tree.go();
mln_VAR(w, morpho::topo_watershed(tree));
debug::println("w:", w);
@@ -158,7 +167,7 @@ int main(int argc, char* argv[])
morpho::tree::data. */
typedef p_array<tree_t::site> sites_t;
sites_t sites = data::sort_psites_decreasing(w);
- morpho::tree::data<w_t, sites_t> t(w, sites, cplx2d::e2e());
+ morpho::tree::data<w_t, sites_t> t(w, sites, world::inter_pixel::e2e());
// Create initial images for min and max values on sites (not components).
mln_ch_value_(w_t, accu::stat::min<int_u8>) init_min_val;
@@ -174,15 +183,16 @@ int main(int argc, char* argv[])
vertices/pixels). We have to convert the coordinates of V to its
equivalent in F's domain to get the values on vertices. */
mln_piter_(w_t) e(w.domain());
- mln_niter_(cplx2d::dbl_neighb2d) v_g(cplx2d::e2p(), e);
+ mln_niter_(world::inter_pixel::dbl_neighb2d)
+ v_g(world::inter_pixel::e2c(), e);
for_all(e)
for_all(v_g)
{
// Same remark as above avour piter to point2d conversions.
point2d v_g_ = v_g;
point2d v_f(v_g_.row() / 2, v_g_.col() / 2);
- init_min_val(e).take(f(v_f));
- init_max_val(e).take(f(v_f));
+ init_min_val(e).take(f_(v_f));
+ init_max_val(e).take(f_(v_f));
}
// Attribute images of min and max values on components.
accu::stat::min<int_u8> min_accu;
diff --git a/milena/sandbox/roland/theo b/milena/sandbox/roland/theo
deleted file mode 120000
index 7612684..0000000
--- a/milena/sandbox/roland/theo
+++ /dev/null
@@ -1 +0,0 @@
-../theo/esiee/laurent/ismm09
\ No newline at end of file
--
1.6.4.4
1
0
* mln/world/inter_pixel/neighb2d.hh
(mln::world::inter_pixel::c2c)
(mln::world::inter_pixel::c2e)
(mln::world::inter_pixel::e2c):
Rename as...
(mln::world::inter_pixel::v2v)
(mln::world::inter_pixel::v2e)
(mln::world::inter_pixel::e2v):
...this.
* mln/world/inter_pixel/dim2/make_edge_image.hh
(mln::world::inter_pixel::dim2::make_edge_image): Adjust.
---
milena/ChangeLog | 16 ++++++++++
.../mln/world/inter_pixel/dim2/make_edge_image.hh | 2 +-
milena/mln/world/inter_pixel/neighb2d.hh | 31 ++++++++++---------
3 files changed, 33 insertions(+), 16 deletions(-)
diff --git a/milena/ChangeLog b/milena/ChangeLog
index 1d88171..c3cf6b5 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -1,3 +1,19 @@
+2009-09-24 Roland Levillain <roland(a)lrde.epita.fr>
+
+ Rename 2D inter-pixel neighborhoods.
+
+ * mln/world/inter_pixel/neighb2d.hh
+ (mln::world::inter_pixel::c2c)
+ (mln::world::inter_pixel::c2e)
+ (mln::world::inter_pixel::e2c):
+ Rename as...
+ (mln::world::inter_pixel::v2v)
+ (mln::world::inter_pixel::v2e)
+ (mln::world::inter_pixel::e2v):
+ ...this.
+ * mln/world/inter_pixel/dim2/make_edge_image.hh
+ (mln::world::inter_pixel::dim2::make_edge_image): Adjust.
+
2009-09-23 Roland Levillain <roland(a)lrde.epita.fr>
Complete mln/world/inter_pixel/neighb2d.hh.
diff --git a/milena/mln/world/inter_pixel/dim2/make_edge_image.hh b/milena/mln/world/inter_pixel/dim2/make_edge_image.hh
index 21e6bf8..8012b60 100644
--- a/milena/mln/world/inter_pixel/dim2/make_edge_image.hh
+++ b/milena/mln/world/inter_pixel/dim2/make_edge_image.hh
@@ -68,7 +68,7 @@ namespace mln
edges_ext_t edges_ext = extend(edges, input);
mln_piter(edges_ext_t) p(edges_ext.domain());
- dbl_neighb2d nbh = e2c();
+ dbl_neighb2d nbh = e2v();
mln_niter(dbl_neighb2d) n(nbh, p);
mln_value(I) vs[2];
diff --git a/milena/mln/world/inter_pixel/neighb2d.hh b/milena/mln/world/inter_pixel/neighb2d.hh
index 048eb9b..d262c3e 100644
--- a/milena/mln/world/inter_pixel/neighb2d.hh
+++ b/milena/mln/world/inter_pixel/neighb2d.hh
@@ -27,8 +27,7 @@
# define MLN_WORLD_INTER_PIXEL_NEIGHB2D_HH
/// \file
-///
-/// \brief Common neighborhood on inter-pixel images.
+/// \brief Common neighborhoods on inter-pixel images.
# include <mln/core/alias/neighb2d.hh>
# include <mln/make/double_neighb2d.hh>
@@ -47,22 +46,24 @@ namespace mln
/// Double neighborhood used for inter-pixel images.
typedef neighb< win::multiple<window2d, dim2::is_row_odd> > dbl_neighb2d;
- // Pixel to neighboring pixels.
- const neighb2d& c2c();
- // Pixel to neighboring edges.
- const neighb2d& c2e();
+ /// Vertex (pixel) to neighboring vertices (pixels).
+ const neighb2d& v2v();
- // Edge to neighborhood pixels.
- const dbl_neighb2d& e2c();
+ /// Vertex (pixel) to neighboring edges (inter-pixels).
+ const neighb2d& v2e();
- // Edge to neighboring edges.
+ /// Edge (inter-pixel) to neighborhood vertices (pixels).
+ const dbl_neighb2d& e2v();
+
+ /// Edge (inter-pixel) to neighboring edges (inter-pixels).
const dbl_neighb2d& e2e();
+
# ifndef MLN_INCLUDE_ONLY
- const neighb2d& c2c()
+ const neighb2d& v2v()
{
static neighb2d it;
if (it.size() == 0)
@@ -77,23 +78,23 @@ namespace mln
return it;
}
- const neighb2d& c2e()
+ const neighb2d& v2e()
{
return c4();
}
- const dbl_neighb2d& e2c()
+ const dbl_neighb2d& e2v()
{
- static const bool e2c_h[] = { 0, 1, 0,
+ static const bool e2v_h[] = { 0, 1, 0,
0, 0, 0,
0, 1, 0 };
- static const bool e2c_v[] = { 0, 0, 0,
+ static const bool e2v_v[] = { 0, 0, 0,
1, 0, 1,
0, 0, 0 };
static dbl_neighb2d nbh =
- make::double_neighb2d(dim2::is_row_odd(), e2c_h, e2c_v);
+ make::double_neighb2d(dim2::is_row_odd(), e2v_h, e2v_v);
return nbh;
}
--
1.6.4.4
1
0
* mln/world/inter_pixel/neighb2d.hh
(mln::world::inter_pixel::c2c, mln::world::inter_pixel::c2e):
New functions.
---
milena/ChangeLog | 8 ++++++++
milena/mln/world/inter_pixel/neighb2d.hh | 26 ++++++++++++++++++++++++++
2 files changed, 34 insertions(+), 0 deletions(-)
diff --git a/milena/ChangeLog b/milena/ChangeLog
index db4d604..1d88171 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -1,5 +1,13 @@
2009-09-23 Roland Levillain <roland(a)lrde.epita.fr>
+ Complete mln/world/inter_pixel/neighb2d.hh.
+
+ * mln/world/inter_pixel/neighb2d.hh
+ (mln::world::inter_pixel::c2c, mln::world::inter_pixel::c2e):
+ New functions.
+
+2009-09-23 Roland Levillain <roland(a)lrde.epita.fr>
+
Fix documentation in mln/world/inter_pixel/neighb2d.hh.
* mln/world/inter_pixel/neighb2d.hh
diff --git a/milena/mln/world/inter_pixel/neighb2d.hh b/milena/mln/world/inter_pixel/neighb2d.hh
index 21233ef..048eb9b 100644
--- a/milena/mln/world/inter_pixel/neighb2d.hh
+++ b/milena/mln/world/inter_pixel/neighb2d.hh
@@ -47,6 +47,12 @@ namespace mln
/// Double neighborhood used for inter-pixel images.
typedef neighb< win::multiple<window2d, dim2::is_row_odd> > dbl_neighb2d;
+ // Pixel to neighboring pixels.
+ const neighb2d& c2c();
+
+ // Pixel to neighboring edges.
+ const neighb2d& c2e();
+
// Edge to neighborhood pixels.
const dbl_neighb2d& e2c();
@@ -56,6 +62,26 @@ namespace mln
# ifndef MLN_INCLUDE_ONLY
+ const neighb2d& c2c()
+ {
+ static neighb2d it;
+ if (it.size() == 0)
+ {
+ static const bool vals[] = { 0, 0, 1, 0, 0,
+ 0, 0, 0, 0, 0,
+ 1, 0, 0, 0, 1,
+ 0, 0, 0, 0, 0,
+ 0, 0, 1, 0, 0 };
+ convert::from_to(vals, it);
+ }
+ return it;
+ }
+
+ const neighb2d& c2e()
+ {
+ return c4();
+ }
+
const dbl_neighb2d& e2c()
{
static const bool e2c_h[] = { 0, 1, 0,
--
1.6.4.4
1
0
URL: https://svn.lrde.epita.fr/svn/oln/trunk
ChangeLog:
2009-10-16 Edwin Carlinet <carlinet(a)lrde.epita.fr>
Update configure.ac with AVS IO tests Makefile.
* configure.ac: Update.
---
configure.ac | 1 +
1 file changed, 1 insertion(+)
Index: trunk/configure.ac
===================================================================
--- trunk/configure.ac (revision 4637)
+++ trunk/configure.ac (revision 4638)
@@ -320,6 +320,7 @@
milena/tests/io/dicom/Makefile
milena/tests/io/dump/Makefile
milena/tests/io/fits/Makefile
+ milena/tests/io/fld/Makefile
milena/tests/io/magick/Makefile
milena/tests/io/off/Makefile
milena/tests/io/pbm/Makefile
1
0
URL: https://svn.lrde.epita.fr/svn/oln/trunk/milena
ChangeLog:
2009-10-16 Edwin Carlinet <carlinet(a)lrde.epita.fr>
Add AVS field file support.
* mln/io/all.hh: Update.
* mln/io/fld/all.hh: New.
* mln/io/fld/header.hh: New.
* mln/io/fld/load.hh: New.
* mln/io/fld/load_header.hh: New.
* mln/io/fld/max_components.hh: New.
* mln/io/fld/save.hh: New.
* mln/io/fld/write_header.hh: New.
* mln/io/fld: New.
* tests/io/Makefile.am: Add rules.
* tests/io/fld/Makefile.am: New.
* tests/io/fld/fld1d.cc: New.
* tests/io/fld/fld2d.cc: New.
* tests/io/fld/fld3d.cc: New.
* tests/io/fld: New.
---
mln/io/all.hh | 1
mln/io/fld/all.hh | 49 ++++++++
mln/io/fld/header.hh | 94 ++++++++++++++++
mln/io/fld/load.hh | 242 +++++++++++++++++++++++++++++++++++++++++++
mln/io/fld/load_header.hh | 220 +++++++++++++++++++++++++++++++++++++++
mln/io/fld/max_components.hh | 102 ++++++++++++++++++
mln/io/fld/save.hh | 173 ++++++++++++++++++++++++++++++
mln/io/fld/write_header.hh | 129 ++++++++++++++++++++++
tests/io/Makefile.am | 3
tests/io/fld/Makefile.am | 31 +++++
tests/io/fld/fld1d.cc | 57 ++++++++++
tests/io/fld/fld2d.cc | 108 +++++++++++++++++++
tests/io/fld/fld3d.cc | 59 ++++++++++
13 files changed, 1267 insertions(+), 1 deletion(-)
Index: trunk/milena/mln/io/fld/write_header.hh
===================================================================
--- trunk/milena/mln/io/fld/write_header.hh (revision 0)
+++ trunk/milena/mln/io/fld/write_header.hh (revision 4637)
@@ -0,0 +1,129 @@
+// Copyright (C) 2008, 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef MLN_IO_FLD_WRITE_HEADER_HH
+# define MLN_IO_FLD_WRITE_HEADER_HH
+
+///
+/// \brief Write AVS headers in a file.
+///
+///
+///
+
+
+# include <mln/io/fld/header.hh>
+# include <iostream>
+
+namespace mln
+{
+
+ namespace io
+ {
+
+ namespace fld
+ {
+ /// Write the AVS header in a file.
+ ///
+ /// \param file The file to write.
+ /// \param h The AVS header.
+ ///
+ void write_header(std::ostream& file, const fld_header& h);
+
+# ifndef MLN_INCLUDE_ONLY
+
+ inline
+ void
+ write_header(std::ostream& file, const fld_header& h)
+ {
+ file << "# AVS field file" << std::endl;
+ file << "# Generated by Milena 1.0 http://olena.lrde.epita.fr" << std::endl;
+ file << "# EPITA Research and Development Laboratory (LRDE)" << std::endl;
+
+ file << "ndim=" << h.ndim << std::endl;
+ for (int i = 0; i < h.ndim; i++)
+ file << "dim" << (i + 1) << "=" << h.dim[i] << std::endl;
+ file << "nspace=" << h.nspace << std::endl
+ << "veclen=" << h.veclen << std::endl;
+
+ switch (h.data)
+ {
+ case data_type::BYTE :
+ file << "data=byte" << std::endl;
+ break;
+ case data_type::SHORT :
+ file << "data=short" << std::endl;
+ break;
+ case data_type::INTEGER :
+ file << "data=integer" << std::endl;
+ break;
+ case data_type::FLOAT :
+ file << "data=float" << std::endl;
+ break;
+ case data_type::DOUBLE :
+ file << "data=double" << std::endl;
+ break;
+ default:
+ std::cerr << "Data type not supported: abort().";
+ abort();
+ }
+
+ switch (h.field)
+ {
+ case field_type::UNIFORM :
+ file << "field=uniform" << std::endl;
+ break;
+ case field_type::IRREGULAR :
+ file << "field=irregular" << std::endl;
+ break;
+ case field_type::RECTILINEAR :
+ file << "field=rectilinear" << std::endl;
+ break;
+ default:
+ std::cerr << "Field type not suported: abort().";
+ abort();
+ }
+
+ file << "min_ext=";
+ for (int i = 0; i < h.nspace; i++)
+ file << h.min_ext[i] << " ";
+ file << std::endl;
+
+ file << "max_ext=";
+ for (int i = 0; i < h.nspace; i++)
+ file << h.max_ext[i] << " ";
+ file << std::endl;
+
+ file << "\f\f";
+ }
+
+#endif // !MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::io::fld
+
+ } // end of namespace mln::io
+
+} // end of namespace mln
+
+#endif // !MLN_IO_FLD_WRITE_HEADER_HH
Index: trunk/milena/mln/io/fld/load_header.hh
===================================================================
--- trunk/milena/mln/io/fld/load_header.hh (revision 0)
+++ trunk/milena/mln/io/fld/load_header.hh (revision 4637)
@@ -0,0 +1,220 @@
+// Copyright (C) 2008, 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef MLN_IO_FLD_LOAD_HEADER_HH
+# define MLN_IO_FLD_LOAD_HEADER_HH
+
+///
+/// \brief Read AVS header from a file.
+///
+///
+
+# include <mln/io/fld/header.hh>
+# include <cstdlib>
+# include <locale>
+# include <iostream>
+# include <sstream>
+# include <string>
+
+namespace mln
+{
+
+ namespace io
+ {
+
+ namespace fld
+ {
+
+ /// Read the header form an AVS field file.
+ ///
+ /// \param ins The file to read.
+ ///
+ /// \return The header.
+ ///
+ fld_header read_header(std::istream& ins);
+
+# ifndef MLN_INCLUDE_ONLY
+
+ namespace internal
+ {
+ void
+ abort_fld_reader(const char* msg, unsigned line = 0)
+ {
+ std::cerr << "AVS field file reader: " << msg << " on line " << line << std::endl;
+ abort();
+ }
+
+ }
+
+ inline
+ fld_header
+ read_header(std::istream& file)
+ {
+ std::stringstream ins;
+ std::string line_str, lhs, rhs;
+ fld_header header;
+ unsigned line;
+
+ std::getline(file, line_str);
+ line = 1;
+ if (line_str.compare(0, 5, "# AVS"))
+ internal::abort_fld_reader("Invalid format", line);
+
+ while (file.good() && file.peek() != '\f')
+ {
+ std::getline(file, line_str);
+ ++line;
+
+ ins.clear();
+ ins.str(line_str);
+ rhs.clear();
+ lhs.clear();
+
+ { // Parse the line
+ char c = ins.get();
+ while (isspace(c))
+ ins.get(c);
+ if (c == '#') // Comments
+ continue;
+ while (isalnum(c) || c == '_')
+ {
+ lhs.push_back(c);
+ ins.get(c);
+ }
+ while (isspace(c))
+ ins.get(c);
+ if (c != '=')
+ internal::abort_fld_reader("Parse error", line);
+ while (isspace(ins.peek()))
+ ins.ignore();
+ }
+
+ if (lhs == "ndim")
+ {
+ ins >> header.ndim;
+ if (header.ndim < 1)
+ internal::abort_fld_reader("Invalid dimension", line);
+ header.dim = new int[header.ndim];
+ std::fill(header.dim, header.dim + header.ndim, -1);
+ }
+ else if (lhs.compare(0, 3, "dim") == 0)
+ {
+ std::stringstream ss(lhs.substr(3));
+ int dim;
+ ss >> dim;
+ if (dim < 1 || dim > header.ndim)
+ internal::abort_fld_reader("Invalid dimension", line);
+ if (!ss.eof())
+ internal::abort_fld_reader("Parse error", line);
+ ins >> header.dim[dim - 1];
+ if (header.dim[dim - 1] < 1)
+ internal::abort_fld_reader("Invalid dimension", line);
+ }
+ else if (lhs == "nspace")
+ {
+ ins >> header.nspace;
+ if (header.nspace < 1)
+ internal::abort_fld_reader("Invalid space dimension", line);
+ header.min_ext = new float[header.nspace];
+ header.max_ext = new float[header.nspace];
+ }
+ else if (lhs == "veclen")
+ {
+ ins >> header.veclen;
+ if (header.veclen == -1)
+ internal::abort_fld_reader("Invalid vector length", line);
+ }
+ else if (lhs == "data")
+ {
+ ins >> rhs;
+ if (rhs == "byte")
+ header.data = data_type::BYTE;
+ else if (rhs == "short")
+ header.data = data_type::SHORT;
+ else if (rhs == "integer")
+ header.data = data_type::INTEGER;
+ else if (rhs == "float")
+ header.data = data_type::FLOAT;
+ else if (rhs == "double")
+ header.data = data_type::DOUBLE;
+ else
+ internal::abort_fld_reader("Invalid data type", line);
+ }
+ else if (lhs == "field")
+ {
+ ins >> rhs;
+ if (rhs != "uniform")
+ internal::abort_fld_reader("Unhandled field type", line);
+ header.field = field_type::UNIFORM;
+ }
+ else if (lhs == "min_ext")
+ {
+ for (int i = 0; i < header.ndim; ++i)
+ {
+ ins >> header.min_ext[i];
+ if (ins.peek() == ',')
+ ins.ignore();
+ }
+ }
+ else if (lhs == "max_ext")
+ {
+ for (int i = 0; i < header.ndim; ++i)
+ {
+ ins >> header.max_ext[i];
+ if (ins.peek() == ',')
+ ins.ignore();
+ }
+ }
+ else
+ internal::abort_fld_reader("Parse error", line);
+
+ rhs.clear();
+ ins >> rhs;
+ if (!rhs.empty() && rhs[0] != '#')
+ internal::abort_fld_reader("Parse error", line);
+ }
+
+ file.ignore();
+ if (file.get() != '\f')
+ internal::abort_fld_reader("Parse error", line);
+
+ if (header.ndim == -1 || header.nspace == -1 || header.veclen == -1 ||
+ header.data == data_type::UNKNOWN || header.field == field_type::UNKNOWN)
+ internal::abort_fld_reader("Invalid format", line);
+ for (int i = 0; i < header.ndim; ++i)
+ if (header.dim[i] == -1)
+ internal::abort_fld_reader("Invalid format", line);
+ return header;
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::io::fld
+
+ } // end of namespace mln::io
+
+} // end of namespace mln
+
+#endif // !MLN_IO_FLD_LOAD_HEADER_HH
Index: trunk/milena/mln/io/fld/all.hh
===================================================================
--- trunk/milena/mln/io/fld/all.hh (revision 0)
+++ trunk/milena/mln/io/fld/all.hh (revision 4637)
@@ -0,0 +1,49 @@
+// Copyright (C) 2007, 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef MLN_IO_FLD_ALL_HH
+# define MLN_IO_FLD_ALL_HH
+
+/// \file
+/// \brief Inclusion of all AVS field file I/O routines.
+
+
+namespace mln
+{
+
+ namespace io
+ {
+ /// Namespace of pgm input/output handling.
+ namespace fld {}
+ }
+
+}
+
+# include <mln/io/fld/load_header.hh>
+# include <mln/io/fld/write_header.hh>
+# include <mln/io/fld/load.hh>
+# include <mln/io/fld/save.hh>
+
+#endif // ! MLN_IO_FLD_ALL_HH
Index: trunk/milena/mln/io/fld/header.hh
===================================================================
--- trunk/milena/mln/io/fld/header.hh (revision 0)
+++ trunk/milena/mln/io/fld/header.hh (revision 4637)
@@ -0,0 +1,94 @@
+// Copyright (C) 2008, 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef MLN_IO_FLD_HEADER_HH
+# define MLN_IO_FLD_HEADER_HH
+
+namespace mln
+{
+
+ namespace io
+ {
+
+ namespace fld
+ {
+
+
+ struct data_type { enum E { UNKNOWN, BYTE, SHORT, INTEGER, FLOAT, DOUBLE }; };
+ struct field_type { enum E { UNKNOWN, UNIFORM, RECTILINEAR, IRREGULAR }; };
+
+ ///
+ /// \brief Define the header structure of an AVS field data file.
+ ///
+ struct fld_header
+ {
+ int ndim; // The number of computational dimensions in the field.
+ int* dim; // The dimension size of each axis.
+ int nspace; // The number of physical coordinates per field element.
+ int veclen; // The number of data values for each field element.
+ data_type::E data; // The primitive data type of all the data values.
+ field_type::E field; // The field type.
+ float* min_ext; // The minimum coordinate value that any member data point occupies in space.
+ float* max_ext; // The maximum coordinate value that any member data point occupies in space.
+ // std::vector<std::string> label; // Not handled.
+ // std::vector<std::string> unit; // Not handled.
+ // void* min_val; // The minimum data value in the field. (Not used)
+ // void* max_val; // The maximum data value in the field. (Not used)
+ // struct {...} variable; // Not handled.
+ // struct {...} coord; // Not handled.
+
+ fld_header();
+ ~fld_header();
+ };
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ fld_header::fld_header()
+ : ndim (-1),
+ dim (0),
+ nspace (-1),
+ veclen (-1),
+ data (data_type::UNKNOWN),
+ field (field_type::UNKNOWN)
+ {
+ }
+
+ fld_header::~fld_header()
+ {
+ delete [] dim;
+ delete [] max_ext;
+ delete [] min_ext;
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::io::fld
+
+ } // end of namespace mln::io
+
+} // end of namespace mln
+
+#endif // !MLN_IO_FLD_HEADER_HH
Index: trunk/milena/mln/io/fld/max_components.hh
===================================================================
--- trunk/milena/mln/io/fld/max_components.hh (revision 0)
+++ trunk/milena/mln/io/fld/max_components.hh (revision 4637)
@@ -0,0 +1,102 @@
+// Copyright (C) 2008, 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef MLN_IO_FLD_MAX_COMPONENTS_HH
+# define MLN_IO_FLD_MAX_COMPONENTS_HH
+
+# include <mln/algebra/vec.hh>
+# include <mln/value/rgb.hh>
+# include <mln/io/fld/header.hh>
+
+namespace mln
+{
+
+ namespace io
+ {
+
+ namespace fld
+ {
+
+ template <typename V>
+ inline
+ unsigned int max_component(const V&);
+
+ template <unsigned n, typename V>
+ inline
+ unsigned int max_component(const algebra::vec<n, V>& v);
+
+ template <unsigned n>
+ inline
+ unsigned int max_component(const value::rgb<n>&);
+
+ inline
+ unsigned int max_component(const fld::data_type::E& t);
+
+# ifndef MLN_INCLUDE_ONLY
+
+ template <typename V>
+ inline
+ unsigned int max_component(const V&)
+ {
+ return mln_max(V);
+ }
+
+
+ template <unsigned n, typename V>
+ inline
+ unsigned int max_component(const algebra::vec<n, V>& v)
+ {
+ return mln_max(V);
+ }
+
+ template <unsigned n>
+ inline
+ unsigned int max_component(const value::rgb<n>&)
+ {
+ return mln_max(mln::value::int_u<n>);
+ }
+
+ inline
+ unsigned int max_component(const fld::data_type::E& t)
+ {
+ switch (t)
+ {
+ case data_type::BYTE: return mln_max(unsigned char);
+ case data_type::SHORT: return mln_max(unsigned short);
+ case data_type::INTEGER: return mln_max(unsigned);
+ case data_type::FLOAT: return mln_max(float);
+ case data_type::DOUBLE: return mln_max(double);
+ default: return 0;
+ }
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+ }
+
+ }
+
+}
+
+#endif // !MLN_IO_FLD_MAX_COMPONENTS_HH
Index: trunk/milena/mln/io/fld/save.hh
===================================================================
--- trunk/milena/mln/io/fld/save.hh (revision 0)
+++ trunk/milena/mln/io/fld/save.hh (revision 4637)
@@ -0,0 +1,173 @@
+// Copyright (C) 2008, 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef MLN_IO_FLD_SAVE_HH
+# define MLN_IO_FLD_SAVE_HH
+/// \file
+/// \brief Save an image to AVS field file format.
+///
+/// \todo Handle not high speed images.
+
+# include <mln/core/concept/image.hh>
+# include <mln/core/concept/gpoint.hh>
+# include <mln/io/fld/header.hh>
+# include <mln/io/fld/write_header.hh>
+# include <mln/io/fld/max_components.hh>
+
+# include <mln/algebra/vec.hh>
+
+# include <mln/geom/nsites.hh>
+# include <fstream>
+# include <iostream>
+
+namespace mln
+{
+
+ namespace io
+ {
+
+ namespace fld
+ {
+
+ template <typename I>
+ void save(const Image<I>& ima_, const char* filename);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ namespace internal
+ {
+ template <typename I>
+ inline
+ void save_data_contiguous(std::ofstream& file, const I& ima)
+ {
+ typedef mln_site(I) P;
+ typedef mln_value(I) V;
+ enum { dim = P::dim };
+
+ P pmin = ima.domain().pmin();
+ P pmax = ima.domain().pmax();
+
+ std::size_t len = pmax[dim - 1] - pmin[dim - 1] + 1;
+ std::size_t n = len * sizeof(V);
+ P p = pmin;
+ if (dim == 1)
+ {
+ file.write((char*)(&ima(p)), n);
+ return;
+ }
+
+ while (true)
+ {
+ file.write((char*)(&ima(p)), n);
+ ++p[dim - 2];
+
+ for (int i = dim - 2; p[i] > pmax[i]; --i)
+ {
+ if (i == 0)
+ return;
+ p[i] = pmin[i];
+ ++p[i - 1];
+ }
+ }
+ }
+
+ template <typename I>
+ inline
+ fld::fld_header make_header(const I& ima)
+ {
+ fld_header hdr;
+ typedef mln_site(I) P;
+ typedef mln_value(I) V;
+ enum { dim = P::dim };
+
+ hdr.ndim = dim;
+ hdr.nspace = dim;
+ hdr.veclen = mln_dim(V);
+ hdr.dim = new int[dim];
+ hdr.min_ext = new float[dim];
+ hdr.max_ext = new float[dim];
+
+ box<P> bbox = geom::bbox(ima);
+ P pmin = bbox.pmin();
+ P pmax = bbox.pmax();
+
+ for (unsigned i = 0; i < dim; i++)
+ {
+ hdr.dim[i] = pmax[i] - pmin[i] + 1;
+ hdr.min_ext[i] = pmin[i];
+ hdr.max_ext[i] = pmax[i];
+ }
+
+ unsigned max_c = max_component(V ());
+ if (max_c == max_component(data_type::BYTE))
+ hdr.data = data_type::BYTE;
+ else if (max_c == max_component(data_type::SHORT))
+ hdr.data = data_type::SHORT;
+ else if (max_c == max_component(data_type::INTEGER))
+ hdr.data = data_type::INTEGER;
+ else if (max_c == max_component(data_type::FLOAT))
+ hdr.data = data_type::FLOAT;
+ else if (max_c == max_component(data_type::DOUBLE))
+ hdr.data = data_type::DOUBLE;
+ else
+ hdr.data = data_type::UNKNOWN;
+
+ hdr.field = field_type::UNIFORM;
+
+ return hdr;
+ }
+
+ } // end of namespace mln::io::fld::internal
+
+ template <typename I>
+ void save(const Image<I>& ima_, const char* filename)
+ {
+ trace::entering("mln::io::fld::save");
+ // For the moment, just the fast version.
+ mlc_is(mln_trait_image_speed(I), trait::image::speed::fastest)::check();
+
+ const I& ima = exact(ima_);
+ mln_precondition(ima.is_valid());
+
+ std::ofstream file(filename);
+ fld_header hdr = internal::make_header(ima);
+
+ write_header(file, hdr);
+ internal::save_data_contiguous(file, ima);
+
+ file.close();
+ trace::exiting("mln::io::fld::save");
+ }
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::io::fld
+
+ } // end of namespace mln::io
+
+} // end of namespace mln
+#endif // !MLN_IO_FLD_SAVE_HH
Index: trunk/milena/mln/io/fld/load.hh
===================================================================
--- trunk/milena/mln/io/fld/load.hh (revision 0)
+++ trunk/milena/mln/io/fld/load.hh (revision 4637)
@@ -0,0 +1,242 @@
+// Copyright (C) 2008, 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef MLN_IO_FLD_LOAD_HH
+# define MLN_IO_FLD_LOAD_HH
+
+/// \file
+///
+/// \brief Load an image from an AVS field file.
+///
+/// \note The current loader does not follow the whole specifications
+/// of the format. Actually, it has the following restrictions:
+/// - the dimension of the field and the space must be the same.
+/// - the number of dimension is limited to 1D, 2D and 3D.
+/// - the data format must be native (float, integer...) (XDR extension is not supported)
+/// - the field must uniform (regular grid).
+/// - dim1, dim2... dimn are parsed but ignored.
+/// - min_ext and max_ext (pmin and pmax of the bbox) are not computed and are compulsory.
+/// - label and unit keyword are not supported.
+/// - external data source ('coord', and 'variable') is not supported.
+///
+/// FIXME: pnm::load uses special implementation if sizeof(int_u8) != 1 ?? what ??
+
+# include <mln/core/concept/image.hh>
+# include <mln/io/fld/header.hh>
+# include <mln/io/fld/load_header.hh>
+# include <mln/io/fld/max_components.hh>
+
+# include <mln/algebra/vec.hh>
+# include <mln/value/rgb.hh>
+# include <mln/value/int_u8.hh>
+
+# include <mln/geom/nsites.hh>
+
+# include <fstream>
+# include <iostream>
+
+namespace mln
+{
+
+ namespace io
+ {
+
+ namespace fld
+ {
+
+ /// Load an image from an AVS field file.
+ ///
+ /// \param[in,out] ima_ The image to load.
+ /// \param[in] filename The path to the AVS file.
+ ///
+ template <typename I>
+ inline
+ void
+ load(Image<I>& ima_, const char* filename);
+
+# ifndef MLN_INCLUDE_ONLY
+
+ namespace internal
+ {
+
+ void
+ abort_load(const char* msg, const char* filename)
+ {
+ std::cerr << "Error: file '" << filename << "'"
+ << "cannot be loaded." << std::endl
+ << "Error description: " << msg << std::endl;
+ abort();
+ }
+
+ // Read a Milena rgb value (sizeof(int_u8) != 1).
+ template <unsigned int n>
+ inline
+ void read_value(std::ifstream& file, value::rgb<n>& v)
+ {
+ typedef typename value::int_u<n>::enc E;
+
+ E c;
+ file.read((char*)(&c), sizeof(E));
+ v.red() = c;
+ file.read((char*)(&c), sizeof(E));
+ v.green() = c;
+ file.read((char*)(&c), sizeof(E));
+ v.blue() = c;
+ }
+
+ // Read a Milena scalar value (sizeof(int_u8) != 1).
+ template <class V>
+ inline
+ void read_value(std::ifstream& file, value::Scalar<V>& v)
+ {
+ typedef typename V::enc E;
+
+ E c;
+ file.read((char*)(&c), sizeof(E));
+ exact(v) = c;
+ }
+
+ // Read a builtin scalar value.
+ template <typename V>
+ inline
+ void read_value(std::ifstream& file, V& v)
+ {
+ V c;
+ file.read((char*)(&c), sizeof(V));
+ v = c;
+ }
+
+ // used when (sizeof(int_u8) != 1)
+ template <typename I>
+ inline
+ void load_raw_uncontiguous(std::ifstream& file, I& ima)
+ {
+ mln_piter(I) p(ima.domain());
+ read_value(file, ima(p));
+ }
+
+ // used in g++ > 2.95
+ template <typename I>
+ inline
+ void load_raw_contiguous(std::ifstream& file, I& ima)
+ {
+ mln_site(I) pmin = ima.domain().pmin();
+ mln_site(I) pmax = ima.domain().pmax();
+
+ typedef mln_site(I) P;
+ enum { dim = P::dim };
+
+ // The first array index varies most quickly (FORTRAN-style).
+ typedef mln_value(I) V;
+
+
+ std::size_t len = pmax[dim - 1] - pmin[dim - 1] + 1;
+ std::size_t n = len * sizeof(V);
+
+ P p = pmin;
+ if (dim == 1)
+ {
+ file.read((char*)(&ima(p)), n);
+ return;
+ }
+
+ while (true)
+ {
+ file.read((char*)(&ima(p)), n);
+ ++p[dim - 2];
+
+ for (int i = dim - 2; p[i] > pmax[i]; --i)
+ {
+ if (i == 0)
+ return;
+ p[i] = pmin[i];
+ ++p[i - 1];
+ }
+ }
+ }
+
+ template <typename I>
+ inline
+ void load_raw(std::ifstream& file, I& ima)
+ {
+ if (sizeof(value::int_u8) == 1)
+ load_raw_contiguous(file, ima);
+ else
+ load_raw_uncontiguous(file, ima);
+ }
+
+ } // end of mln::io::internal
+
+ template <typename I>
+ inline
+ void
+ load(Image<I>& ima_, const char* filename)
+ {
+ trace::entering("mln::io::fld::load");
+
+ std::ifstream file(filename);
+ if (! file)
+ internal::abort_load("Fail to open the file.", filename);
+
+ typedef mln_value(I) V;
+ typedef mln_site(I) P;
+
+ I& ima = exact(ima_);
+ fld_header hder = fld::read_header(file);
+ int nspace = P::dim;
+ int veclen = mln_dim(V);
+
+ if (nspace != hder.nspace)
+ internal::abort_load("The dimension of the input does not match the one from the file.", filename);
+ if (nspace > 3)
+ internal::abort_load("The loader does not handle image dimension greater than three.", filename);
+ if (veclen != hder.veclen)
+ internal::abort_load("The dimension of the value does not match the one from the file.", filename);
+ if (max_component(V ()) != max_component(hder.data))
+ internal::abort_load("The data type of the input mismatches the one from the file.", filename);
+
+ box<mln_site(I)> bbox;
+ for (int i = 0; i < hder.ndim; ++i)
+ {
+ bbox.pmin()[i] = hder.min_ext[i];
+ bbox.pmax()[i] = hder.max_ext[i];
+ }
+
+ ima.init_(bbox);
+ internal::load_raw(file, ima);
+
+ file.close();
+ trace::exiting("mln::io::fld::load");
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::io::fld
+
+ } // end of namespace mln::io
+
+} // end of namespace mln
+
+#endif // !MLN_IO_FLD_LOAD_HH
Index: trunk/milena/mln/io/all.hh
===================================================================
--- trunk/milena/mln/io/all.hh (revision 4636)
+++ trunk/milena/mln/io/all.hh (revision 4637)
@@ -57,6 +57,7 @@
# include <mln/io/ppm/all.hh>
# include <mln/io/txt/all.hh>
# include <mln/io/off/all.hh>
+# include <mln/io/fld/all.hh>
/*--------------------------------------------------.
Index: trunk/milena/tests/io/fld/fld2d.cc
===================================================================
--- trunk/milena/tests/io/fld/fld2d.cc (revision 0)
+++ trunk/milena/tests/io/fld/fld2d.cc (revision 4637)
@@ -0,0 +1,108 @@
+// Copyright (C) 2008, 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+///
+/// \brief Test fld IO on 2D images.
+///
+
+#include <mln/core/image/image2d.hh>
+
+#include <mln/io/pgm/load.hh>
+#include <mln/io/ppm/load.hh>
+#include <mln/io/fld/load.hh>
+#include <mln/io/fld/save.hh>
+#include <mln/value/int_u8.hh>
+#include <mln/value/int_u16.hh>
+#include <mln/data/compare.hh>
+#include "tests/data.hh"
+
+#include <stdio.h>
+#include <float.h>
+#include <time.h>
+
+int main()
+{
+ using namespace mln;
+ using value::int_u8;
+ using value::int_u16;
+
+ // Test on int_u8.
+ // Veclen = 1, data = byte
+ {
+ image2d<int_u8> ori, test;
+ io::pgm::load(ori, MLN_IMG_DIR "/lena.pgm");
+
+ io::fld::save(ori, "out.fld");
+ io::fld::load(test, "out.fld");
+
+ // Clean output.
+ std::remove("out.fld");
+
+ mln_assertion(ori == test);
+ }
+
+ // Test on RGB 16
+ // Veclen = 3, data = short
+ {
+ image2d<int_u16> ori, test;
+ io::ppm::load(ori, MLN_IMG_DIR "/lena_16.ppm");
+
+ io::fld::save(ori, "out.fld");
+ io::fld::load(test, "out.fld");
+
+ // Clean output.
+ std::remove("out.fld");
+
+ mln_assertion(ori == test);
+ }
+
+ // Test on 32-bits data type
+ // Veclen = 1, data = float
+ {
+ image2d<float> ori, test;
+ box<point2d> domain(8, 9);
+
+ srand(time(NULL));
+ ori.init_(domain);
+ {
+ mln_piter_(image2d<float>) p(domain);
+ for_all(p)
+ ori(p) = random() / RAND_MAX;
+ }
+
+ io::fld::save(ori, "out.fld");
+ io::fld::load(test, "out.fld");
+
+ // Clean output.
+ std::remove("out.fld");
+
+ {
+ mln_piter_(image2d<float>) p(domain);
+ for_all(p)
+ mln_assertion(fabs(ori(p) - test(p)) < FLT_EPSILON);
+ }
+ }
+
+}
Index: trunk/milena/tests/io/fld/fld3d.cc
===================================================================
--- trunk/milena/tests/io/fld/fld3d.cc (revision 0)
+++ trunk/milena/tests/io/fld/fld3d.cc (revision 4637)
@@ -0,0 +1,59 @@
+// Copyright (C) 2008, 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+///
+/// \brief Test AVS field file IO with 3D image.
+///
+///
+///
+
+#include <mln/core/image/image3d.hh>
+#include <mln/io/fld/load.hh>
+#include <mln/io/fld/save.hh>
+#include <mln/value/int_u8.hh>
+#include <mln/debug/iota.hh>
+#include <mln/debug/println.hh>
+#include <mln/data/compare.hh>
+
+
+int main()
+{
+ using namespace mln;
+ using value::int_u8;
+
+
+ image3d<int_u8> ori, test;
+ box<point3d> b(8, 9, 10);
+ ori.init_(b);
+ debug::iota(ori);
+
+ io::fld::save(ori, "out.fld");
+ io::fld::load(test, "out.fld");
+
+ // Clean output.
+ std::remove("out.fld");
+
+ mln_assertion(ori == test);
+}
Index: trunk/milena/tests/io/fld/Makefile.am
===================================================================
--- trunk/milena/tests/io/fld/Makefile.am (revision 0)
+++ trunk/milena/tests/io/fld/Makefile.am (revision 4637)
@@ -0,0 +1,31 @@
+# Copyright (C) 2007, 2009 EPITA Research and Development Laboratory (LRDE).
+#
+# This file is part of Olena.
+#
+# Olena is free software: you can redistribute it and/or modify it under
+# the terms of the GNU General Public License as published by the Free
+# Software Foundation, version 2 of the License.
+#
+# Olena is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Olena. If not, see <http://www.gnu.org/licenses/>.
+#
+
+## Process this file through Automake to create Makefile.in.
+
+include $(top_srcdir)/milena/tests/tests.mk
+
+check_PROGRAMS = \
+ fld2d \
+ fld1d \
+ fld3d
+
+fld2d_SOURCES = fld2d.cc
+fld3d_SOURCES = fld3d.cc
+fld1d_SOURCES = fld1d.cc
+
+TESTS = $(check_PROGRAMS)
\ No newline at end of file
Index: trunk/milena/tests/io/fld/fld1d.cc
===================================================================
--- trunk/milena/tests/io/fld/fld1d.cc (revision 0)
+++ trunk/milena/tests/io/fld/fld1d.cc (revision 4637)
@@ -0,0 +1,57 @@
+// Copyright (C) 2008, 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+///
+/// \brief Test AVS field file IO with 1D image.
+///
+///
+///
+
+#include <mln/core/image/image1d.hh>
+#include <mln/io/fld/load.hh>
+#include <mln/io/fld/save.hh>
+#include <mln/value/int_u8.hh>
+#include <mln/debug/iota.hh>
+#include <mln/data/compare.hh>
+
+int main()
+{
+ using namespace mln;
+ using value::int_u8;
+
+
+ image1d<int_u8> ori, test;
+ box<point1d> b(9);
+ ori.init_(b);
+ debug::iota(ori);
+
+ io::fld::save(ori, "out.fld");
+ io::fld::load(test, "out.fld");
+
+ // Clean output.
+ std::remove("out.fld");
+
+ mln_assertion(ori == test);
+}
Index: trunk/milena/tests/io/Makefile.am
===================================================================
--- trunk/milena/tests/io/Makefile.am (revision 4636)
+++ trunk/milena/tests/io/Makefile.am (revision 4637)
@@ -33,7 +33,8 @@
pgms \
pnm \
ppm \
- ppms
+ ppms \
+ fld
## ------------------------------------------------- ##
## I/O routines depending on a third-party library. ##
1
0
https://svn.lrde.epita.fr/svn/oln/trunk/milena
Index: ChangeLog
from Thierry Geraud <thierry.geraud(a)lrde.epita.fr>
Some fixes.
* mln/data/transform.spe.hh: Layout.
* mln/data/transform_inplace.hh (transform_tests): Rename as...
(transform_inplace_tests): ...this; it is a naming bug fix.
* mln/convert/to.hh: Remove trace and add a tech note about it.
convert/to.hh | 6 ++++--
data/transform.spe.hh | 1 -
data/transform_inplace.hh | 20 ++++++++++----------
3 files changed, 14 insertions(+), 13 deletions(-)
Index: mln/data/transform.spe.hh
--- mln/data/transform.spe.hh (revision 4635)
+++ mln/data/transform.spe.hh (working copy)
@@ -233,7 +233,6 @@
{
trace::entering("data::impl::transform_fast");
-
const I& input = exact(input_);
const F& f = exact(f_);
data::internal::transform_tests(input, f);
Index: mln/data/transform_inplace.hh
--- mln/data/transform_inplace.hh (revision 4635)
+++ mln/data/transform_inplace.hh (working copy)
@@ -106,9 +106,9 @@
template <typename I1, typename I2, typename F>
inline
- void transform_tests(const Image<I1>& ima,
+ void transform_inplace_tests(Image<I1>& ima,
const Image<I2>& aux,
- const Function_v2v<F>& f)
+ const Function_vv2v<F>& f)
{
// Properties checks.
mlc_or(mlc_is(mln_trait_image_pw_io(I1),
@@ -156,7 +156,7 @@
I& ima = exact(ima_);
const F& f = exact(f_);
- data::internal::transform_inplace_tests(ima, f);
+ internal::transform_inplace_tests(ima, f);
mln_piter(I) p(ima.domain());
for_all(p)
@@ -185,7 +185,7 @@
const I2& aux = exact(aux_);
const F& f = exact(f_);
- data::internal::transform_inplace_tests(ima, aux, f);
+ internal::transform_inplace_tests(ima, aux, f);
mln_piter(I1) p(ima.domain());
for_all(p)
@@ -211,7 +211,7 @@
I& input = exact(input_);
const F& f = exact(f_);
- data::internal::transform_inplace_tests(input, f);
+ internal::transform_inplace_tests(input, f);
value::lut_vec<mln_vset(I), mln_result(F)>
lut(input.values_eligible(), f);
@@ -236,7 +236,7 @@
I& input = exact(input_);
const F& f = exact(f_);
- data::internal::transform_inplace_tests(input, f);
+ internal::transform_inplace_tests(input, f);
value::lut_vec<mln_vset(I), mln_result(F)>
lut(input.taken_values(), f);
@@ -259,7 +259,7 @@
I& input = exact(input_);
const F& f = exact(f_);
- data::internal::transform_inplace_tests(input, f);
+ internal::transform_inplace_tests(input, f);
opt::value(input) = f(opt::value(input));
@@ -275,7 +275,7 @@
I& ima = exact(ima_);
const F& f = exact(f_);
- data::internal::transform_inplace_tests(ima, f);
+ internal::transform_inplace_tests(ima, f);
mln_pixter(I) p(ima);
for_all(p)
@@ -295,7 +295,7 @@
I& input = exact(input_);
const F& f = exact(f_);
- data::internal::transform_inplace_tests(input, f);
+ internal::transform_inplace_tests(input, f);
value::lut_vec<mln_vset(I), mln_result(F)>
lut(input.values_eligible(), f);
@@ -322,7 +322,7 @@
const I2& aux = exact(aux_);
const F& f = exact(f_);
- data::internal::transform_inplace_tests(ima, aux, f);
+ internal::transform_inplace_tests(ima, aux, f);
mln_pixter(I1) pi(ima);
mln_pixter(const I2) pa(aux);
Index: mln/convert/to.hh
--- mln/convert/to.hh (revision 4635)
+++ mln/convert/to.hh (working copy)
@@ -62,14 +62,16 @@
T
to(const O& from)
{
+ // Technical note:
+ // No trace should be produced by this routine since it can be
+ // applied on large sets of data.
+
mlc_equal(T, mln_exact(T))::check();
mlc_equal(O, mln_exact(O))::check();
- trace::entering("convert::to");
T tmp;
from_to(from, tmp);
- trace::exiting("convert::to");
return tmp;
}
1
0
https://svn.lrde.epita.fr/svn/oln/trunk/milena/sandbox
Index: ChangeLog
from Thierry Geraud <thierry.geraud(a)lrde.epita.fr>
Add a 1st version of some morpho geodesic ops.
* theo/mln/morpho: New directory.
* theo/mln/morpho/geodesic: New directory.
* theo/mln/morpho/geodesic/dilation.hh: New.
* theo/mln/morpho/geodesic/dilation_permissive.hh: New.
* theo/mln/morpho/geodesic/dilation.cc: New.
* theo/mln/morpho/geodesic/dilation_permissive_n.cc: New.
* theo/mln/morpho/geodesic/dilation_permissive_bench.cc: New.
* theo/mln/morpho/geodesic/dilation_permissive.cc: New.
dilation.cc | 31 ++
dilation.hh | 88 ++++++++
dilation_permissive.cc | 47 ++++
dilation_permissive.hh | 446 +++++++++++++++++++++++++++++++++++++++++++
dilation_permissive_bench.cc | 60 +++++
dilation_permissive_n.cc | 35 +++
6 files changed, 707 insertions(+)
Index: theo/mln/morpho/geodesic/dilation.hh
--- theo/mln/morpho/geodesic/dilation.hh (revision 0)
+++ theo/mln/morpho/geodesic/dilation.hh (revision 0)
@@ -0,0 +1,88 @@
+// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef MLN_MORPHO_GEODESIC_DILATION_HH
+# define MLN_MORPHO_GEODESIC_DILATION_HH
+
+/// \file
+///
+/// Morphological geodesic dilation; strict version.
+
+// # include <mln/morpho/geodesic/dilation_permissive.hh>
+# include "dilation_permissive.hh"
+
+
+namespace mln
+{
+
+ namespace morpho
+ {
+
+ namespace geodesic
+ {
+
+ /// Morphological geodesic dilation of size n; strict version.
+ template <typename I, typename J, typename N>
+ mln_concrete(I)
+ dilation(const Image<I>& f, const Image<J>& g,
+ const Neighborhood<N>& nbh,
+ unsigned n = 1);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ template <typename I, typename J, typename N>
+ inline
+ mln_concrete(I)
+ dilation(const Image<I>& f, const Image<J>& g,
+ const Neighborhood<N>& nbh,
+ unsigned n)
+ {
+ trace::entering("morpho::geodesic::dilation");
+
+ mln_precondition(n != 0);
+ internal::dilation_permissive_tests(f, g, nbh);
+ mln_precondition(f <= g);
+
+ mln_concrete(I) output;
+ output = internal::dilation_permissive_dispatch(f, g, nbh, n);
+
+ mln_precondition(output >= f);
+ mln_precondition(output <= g);
+
+ trace::exiting("morpho::geodesic::dilation");
+ return output;
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::geodesic
+
+ } // end of namespace mln::morpho
+
+} // end of namespace mln
+
+
+#endif // ! MLN_MORPHO_GEODESIC_DILATION_HH
Index: theo/mln/morpho/geodesic/dilation_permissive.hh
--- theo/mln/morpho/geodesic/dilation_permissive.hh (revision 0)
+++ theo/mln/morpho/geodesic/dilation_permissive.hh (revision 0)
@@ -0,0 +1,446 @@
+// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef MLN_MORPHO_GEODESIC_DILATION_PERMISSIVE_HH
+# define MLN_MORPHO_GEODESIC_DILATION_PERMISSIVE_HH
+
+/// \file
+///
+/// Morphological geodesic dilation; permissive version.
+
+# include <mln/morpho/includes.hh>
+# include <mln/morpho/elementary/dilation.hh>
+# include <mln/logical/and.hh>
+# include <mln/data/transform_inplace.hh>
+# include <mln/fun/vv2v/max.hh>
+# include <mln/border/equalize.hh>
+
+
+namespace mln
+{
+
+ namespace morpho
+ {
+
+ namespace geodesic
+ {
+
+ /// Morphological geodesic dilation of size n; permissive version.
+ template <typename I, typename J, typename N>
+ mln_concrete(I)
+ dilation_permissive(const Image<I>& f, const Image<J>& g,
+ const Neighborhood<N>& nbh,
+ unsigned n = 1);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ // Tests.
+
+ namespace internal
+ {
+
+ template <typename I, typename J, typename N>
+ inline
+ void
+ dilation_permissive_tests(const Image<I>& f_, const Image<J>& g_,
+ const Neighborhood<N>& nbh_)
+ {
+ const I& f = exact(f_);
+ const J& g = exact(g_);
+ const N& nbh = exact(nbh_);
+
+ mln_precondition(f.is_valid());
+ mln_precondition(g.is_valid());
+ mln_precondition(nbh.is_valid());
+
+ mln_precondition(f.domain() == g.domain());
+
+ (void) f;
+ (void) g;
+ (void) nbh;
+ }
+
+ } // end of namespace morpho::geodesic::internal
+
+
+ // Implementations.
+
+ namespace impl
+ {
+
+
+ template <typename I, typename J, typename N>
+ inline
+ mln_concrete(I)
+ dilation_strict_1_set_formula(const Image<I>& f, const Image<J>& g,
+ const Neighborhood<N>& nbh)
+ {
+ trace::entering("morpho::geodesic::impl::dilation_strict_1_set_formula");
+
+ internal::dilation_permissive_tests(f, g, nbh);
+
+ mln_concrete(I) output = morpho::elementary::dilation(f, nbh);
+ logical::and_inplace(output, g);
+
+ trace::exiting("morpho::geodesic::impl::dilation_strict_1_set_formula");
+ return output;
+ }
+
+
+ template <typename I, typename J, typename N>
+ inline
+ mln_concrete(I)
+ dilation_strict_1_function_formula(const Image<I>& f, const Image<J>& g,
+ const Neighborhood<N>& nbh)
+ {
+ trace::entering("morpho::geodesic::impl::dilation_strict_1_function_formula");
+
+ internal::dilation_permissive_tests(f, g, nbh);
+
+ mln_concrete(I) output = morpho::elementary::dilation(f, nbh);
+ fun::vv2v::max<mln_value(I)> max_;
+ data::transform_inplace(output, g, max_);
+
+ trace::exiting("morpho::geodesic::impl::dilation_strict_1_function_formula");
+ return output;
+ }
+
+
+ template <typename I, typename J, typename N>
+ inline
+ mln_concrete(I)
+ dilation_permissive_n(const Image<I>& f, const Image<J>& g,
+ const Neighborhood<N>& nbh,
+ unsigned n)
+ {
+ trace::entering("morpho::geodesic::impl::dilation_permissive_n");
+
+ mln_precondition(n != 0);
+ internal::dilation_permissive_tests(f, g, nbh);
+
+ mln_concrete(I) work = duplicate(f);
+ for (unsigned i = 0; i < n; ++i)
+ work = dilation_permissive(work, g, nbh, 1);
+
+ trace::exiting("morpho::geodesic::impl::dilation_permissive_n");
+ return work;
+ }
+
+
+ template <typename I, typename J, typename N>
+ inline
+ mln_concrete(I)
+ dilation_permissive_1_set_generic(const Image<I>& f_, const Image<J>& g_,
+ const Neighborhood<N>& nbh_)
+ {
+ trace::entering("morpho::geodesic::impl::dilation_permissive_1_set_generic");
+
+ const I& f = exact(f_);
+ const J& g = exact(g_);
+ const N& nbh = exact(nbh_);
+
+ internal::dilation_permissive_tests(f, g, nbh);
+
+ mln_piter(I) p(f.domain());
+ mln_niter(N) n(nbh, p);
+
+ // We dilate from the inner boundary of f.
+
+ mln_concrete(I) output = duplicate(f);
+ for_all(p)
+ {
+ if (! f(p))
+ continue;
+ for_all(n) if (f.domain().has(n))
+ {
+ if (output(n)) // already at true
+ continue;
+ if (g(n)) // conditioning
+ output(n) = true;
+ }
+ }
+
+ trace::exiting("morpho::geodesic::impl::dilation_permissive_1_set_generic");
+ return output;
+ }
+
+
+ template <typename I, typename J, typename N>
+ inline
+ mln_concrete(I)
+ dilation_permissive_1_set_fastest(const Image<I>& f_, const Image<J>& g_,
+ const Neighborhood<N>& nbh_)
+ {
+ trace::entering("morpho::geodesic::impl::dilation_permissive_1_set_fastest");
+
+ const I& f = exact(f_);
+ const J& g = exact(g_);
+ const N& nbh = exact(nbh_);
+
+ internal::dilation_permissive_tests(f, g, nbh);
+
+ border::equalize(f, g, nbh.delta());
+ typedef mln_concrete(I) O;
+ O output = duplicate(f);
+ border::fill(output, true);
+
+ util::array<int> dp = offsets_wrt(f, nbh);
+ const unsigned n_nbhs = dp.nelements();
+
+ mln_box_runstart_piter(I) s(f.domain());
+ s.start();
+ const unsigned len = s.run_length();
+
+ // We dilate from the inner boundary of f.
+
+ for (; s.is_valid(); s.next())
+ {
+ unsigned p = f.index_of_point(s);
+ for (unsigned i = 0; i < len; ++i, ++p)
+ {
+ if (! f.element(p))
+ continue;
+ for (unsigned j = 0; j < n_nbhs; ++j)
+ {
+ unsigned n = p + dp[j];
+ if (output.element(n)) // already at true
+ continue;
+ if (g.element(n)) // conditioning
+ output.element(n) = true;
+ }
+ }
+ }
+
+ trace::exiting("morpho::geodesic::impl::dilation_permissive_1_set_fastest");
+ return output;
+ }
+
+
+ template <typename I, typename J, typename N>
+ inline
+ mln_concrete(I)
+ dilation_permissive_1_set_generic_alt(const Image<I>& f_, const Image<J>& g_,
+ const Neighborhood<N>& nbh_)
+ {
+ trace::entering("morpho::geodesic::impl::dilation_permissive_1_set_generic_alt");
+
+ const I& f = exact(f_);
+ const J& g = exact(g_);
+ const N& nbh = exact(nbh_);
+
+ internal::dilation_permissive_tests(f, g, nbh);
+
+ mln_piter(I) p(f.domain());
+ mln_niter(N) n(nbh, p);
+
+ // We browse the "(not f) and g" domain.
+
+ mln_concrete(I) output = duplicate(f);
+ for_all(p)
+ {
+ if (f(p) // output(p) is already at true...
+ || ! g(p) // ...or conditioning by g not satisfied
+ )
+ continue;
+ for_all(n) if (f.domain().has(n))
+ if (f(n)) // p is in the outer boundary of f
+ {
+ output(p) = true;
+ break; // we are done for p
+ }
+ }
+
+ trace::exiting("morpho::geodesic::impl::dilation_permissive_1_set_generic_alt");
+ return output;
+ }
+
+
+
+ template <typename I, typename J, typename N>
+ inline
+ mln_concrete(I)
+ dilation_permissive_1_set_fastest_alt(const Image<I>& f_, const Image<J>& g_,
+ const Neighborhood<N>& nbh_)
+ {
+ trace::entering("morpho::geodesic::impl::dilation_permissive_1_set_fastest_alt");
+
+ const I& f = exact(f_);
+ const J& g = exact(g_);
+ const N& nbh = exact(nbh_);
+
+ internal::dilation_permissive_tests(f, g, nbh);
+
+ border::equalize(f, g, nbh.delta());
+ typedef mln_concrete(I) O;
+ O output = duplicate(f);
+ border::fill(f, false);
+
+ util::array<int> dp = offsets_wrt(f, nbh);
+ const unsigned n_nbhs = dp.nelements();
+
+ mln_box_runstart_piter(I) s(f.domain());
+ s.start();
+ const unsigned len = s.run_length();
+
+ // We browse the "(not f) and g" domain.
+
+ for (; s.is_valid(); s.next())
+ {
+ unsigned p = f.index_of_point(s);
+ for (unsigned i = 0; i < len; ++i, ++p)
+ {
+ if (f.element(p) // output.element(p) is already at true...
+ || ! g.element(p) // ...or conditioning by g not satisfied
+ )
+ continue;
+ for (unsigned j = 0; j < n_nbhs; ++j)
+ {
+ unsigned n = p + dp[j];
+ if (f.element(n)) // p is in the outer boundary of f
+ {
+ output.element(p) = true;
+ break; // we are done for p
+ }
+ }
+ }
+ }
+
+ trace::exiting("morpho::geodesic::impl::dilation_permissive_1_set_fastest_alt");
+ return output;
+ }
+
+
+ } // end of namespace morpho::geodesic::impl
+
+
+
+ // Dispatch.
+
+ namespace internal
+ {
+
+
+ // For size 1.
+
+ template <typename M,
+ typename I, typename J, typename N>
+ inline
+ mln_concrete(I)
+ dilation_permissive_1_dispatch(trait::image::kind::any,
+ M,
+ const Image<I>& f, const Image<J>& g,
+ const Neighborhood<N>& nbh)
+ {
+ // FIXME
+ std::cerr << "NYI: replace by strict version!" << std::endl;
+ return impl::dilation_strict_1_function_formula(f, g, nbh);
+ }
+
+ template <typename I, typename J, typename N>
+ inline
+ mln_concrete(I)
+ dilation_permissive_1_dispatch(trait::image::kind::binary,
+ metal::false_,
+ const Image<I>& f, const Image<J>& g,
+ const Neighborhood<N>& nbh)
+ {
+ return impl::dilation_permissive_1_set_generic(f, g, nbh);
+ }
+
+ template <typename I, typename J, typename N>
+ inline
+ mln_concrete(I)
+ dilation_permissive_1_dispatch(trait::image::kind::binary,
+ metal::true_,
+ const Image<I>& f, const Image<J>& g,
+ const Neighborhood<N>& nbh)
+ {
+ return impl::dilation_permissive_1_set_fastest(f, g, nbh);
+ }
+
+
+
+ // Entry point.
+
+ template <typename I, typename J, typename N>
+ inline
+ mln_concrete(I)
+ dilation_permissive_dispatch(const Image<I>& f, const Image<J>& g,
+ const Neighborhood<N>& nbh,
+ unsigned n)
+ {
+ enum {
+ is_fastest = (mlc_equal(mln_trait_image_speed(I),
+ trait::image::speed::fastest)::value &&
+ mlc_equal(mln_trait_image_speed(J),
+ trait::image::speed::fastest)::value &&
+ mln_is_simple_neighborhood(N)::value)
+ };
+ if (n == 1)
+ return dilation_permissive_1_dispatch(mln_trait_image_kind(I)(),
+ metal::bool_<is_fastest>(),
+ f, g, nbh);
+ else
+ return impl::dilation_permissive_n(f, g, nbh, n);
+ }
+
+
+ } // end of namespace morpho::geodesic::internal
+
+
+
+ // Facade.
+
+ template <typename I, typename J, typename N>
+ inline
+ mln_concrete(I)
+ dilation_permissive(const Image<I>& f, const Image<J>& g,
+ const Neighborhood<N>& nbh,
+ unsigned n)
+ {
+ trace::entering("morpho::geodesic::dilation_permissive");
+
+ mln_precondition(n != 0);
+ internal::dilation_permissive_tests(f, g, nbh);
+
+ mln_concrete(I) output;
+ output = internal::dilation_permissive_dispatch(f, g, nbh, n);
+
+ trace::exiting("morpho::geodesic::dilation_permissive");
+ return output;
+ }
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::geodesic
+
+ } // end of namespace mln::morpho
+
+} // end of namespace mln
+
+
+#endif // ! MLN_MORPHO_GEODESIC_DILATION_PERMISSIVE_HH
Index: theo/mln/morpho/geodesic/dilation.cc
--- theo/mln/morpho/geodesic/dilation.cc (revision 0)
+++ theo/mln/morpho/geodesic/dilation.cc (revision 0)
@@ -0,0 +1,31 @@
+#include <mln/core/image/image2d.hh>
+#include <mln/core/alias/neighb2d.hh>
+#include <mln/logical/and.hh>
+
+#include "dilation.hh"
+
+
+int main()
+{
+ using namespace mln;
+
+ image2d<bool> f, g, o;
+ neighb2d nbh = c4();
+
+ bool gvals[] = { 1, 1, 0, 0, 1,
+ 1, 1, 1, 1, 0,
+ 0, 1, 1, 1, 0,
+ 0, 1, 1, 1, 0,
+ 0, 1, 0, 0, 0 };
+ g = make::image2d(gvals);
+
+ bool fvals[] = { 0, 0, 0, 0, 0,
+ 0, 0, 1, 1, 1,
+ 1, 1, 1, 1, 0,
+ 1, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0 };
+ f = make::image2d(fvals);
+
+
+ o = morpho::geodesic::dilation(logical::and_(f, g), g, nbh);
+}
Index: theo/mln/morpho/geodesic/dilation_permissive_n.cc
--- theo/mln/morpho/geodesic/dilation_permissive_n.cc (revision 0)
+++ theo/mln/morpho/geodesic/dilation_permissive_n.cc (revision 0)
@@ -0,0 +1,35 @@
+#include <cstdlib>
+#include <mln/core/image/image2d.hh>
+#include <mln/core/alias/neighb2d.hh>
+#include <mln/io/pbm/load.hh>
+#include <mln/io/pbm/save.hh>
+#include <mln/logical/and.hh>
+#include <mln/util/timer.hh>
+
+#include "dilation_permissive.hh"
+
+
+int main(int argc, char* argv[])
+{
+ using namespace mln;
+
+
+ image2d<bool>
+ f = io::pbm::load("./+f.pbm"),
+ g = io::pbm::load("./+g.pbm"),
+ o;
+ neighb2d nbh = c8();
+
+ int n = std::atoi(argv[1]);
+
+// image2d<bool> f_g = logical::and_(f, g);
+// io::pbm::save(f_g, "f_g.pbm");
+// o = morpho::geodesic::dilation_permissive(f_g, g, nbh, n);
+
+ util::timer t;
+ t.start();
+ o = morpho::geodesic::dilation_permissive(f, g, nbh, n);
+ std::cout << t.stop() << std::endl;
+
+ io::pbm::save(o, "o.pbm");
+}
Index: theo/mln/morpho/geodesic/dilation_permissive_bench.cc
--- theo/mln/morpho/geodesic/dilation_permissive_bench.cc (revision 0)
+++ theo/mln/morpho/geodesic/dilation_permissive_bench.cc (revision 0)
@@ -0,0 +1,60 @@
+#include <mln/core/image/image2d.hh>
+#include <mln/core/alias/neighb2d.hh>
+#include <mln/debug/println.hh>
+#include <mln/io/pbm/load.hh>
+#include <mln/io/pbm/save.hh>
+#include <mln/util/timer.hh>
+
+#include "dilation_permissive.hh"
+
+
+int main()
+{
+ using namespace mln;
+
+ image2d<bool>
+ f = io::pbm::load("./+f.pbm"),
+ g = io::pbm::load("./+g.pbm"),
+ o;
+ neighb2d nbh = c4();
+
+ util::timer t;
+ const unsigned n = 20;
+
+ {
+ t.start();
+ for (unsigned i = 0; i < n; ++i)
+ o = morpho::geodesic::impl::dilation_strict_1_set_formula(f, g, nbh);
+ std::cout << "dilation_strict_1_set_formula " << t.stop() << std::endl;
+ io::pbm::save(o, "o.pbm");
+ }
+
+ {
+ t.start();
+ for (unsigned i = 0; i < n; ++i)
+ o = morpho::geodesic::impl::dilation_permissive_1_set_generic(f, g, nbh);
+ std::cout << "dilation_permissive_1_set_generic " << t.stop() << std::endl;
+ }
+
+ {
+ t.start();
+ for (unsigned i = 0; i < n; ++i)
+ o = morpho::geodesic::impl::dilation_permissive_1_set_fastest(f, g, nbh);
+ std::cout << "dilation_permissive_1_set_fastest " << t.stop() << std::endl;
+// io::pbm::save(o, "o.pbm");
+ }
+
+ {
+ t.start();
+ for (unsigned i = 0; i < n; ++i)
+ o = morpho::geodesic::impl::dilation_permissive_1_set_generic_alt(f, g, nbh);
+ std::cout << "dilation_permissive_1_set_generic_alt " << t.stop() << std::endl;
+ }
+
+ {
+ t.start();
+ for (unsigned i = 0; i < n; ++i)
+ o = morpho::geodesic::impl::dilation_permissive_1_set_fastest_alt(f, g, nbh);
+ std::cout << "dilation_permissive_1_set_fastest_alt " << t.stop() << std::endl;
+ }
+}
Index: theo/mln/morpho/geodesic/dilation_permissive.cc
--- theo/mln/morpho/geodesic/dilation_permissive.cc (revision 0)
+++ theo/mln/morpho/geodesic/dilation_permissive.cc (revision 0)
@@ -0,0 +1,47 @@
+#include <mln/core/image/image2d.hh>
+#include <mln/core/alias/neighb2d.hh>
+#include <mln/debug/println.hh>
+
+#include "dilation_permissive.hh"
+
+
+int main()
+{
+ using namespace mln;
+
+ image2d<bool> f, g, d_ref, d_gen, d_fast, d_gen_alt, d_fast_alt;
+ neighb2d nbh = c4();
+
+ bool gvals[] = { 1, 1, 0, 0, 1,
+ 1, 1, 1, 1, 0,
+ 0, 1, 1, 1, 0,
+ 0, 1, 1, 1, 0,
+ 0, 1, 0, 0, 0 };
+ g = make::image2d(gvals);
+ debug::println("g", g);
+
+ bool fvals[] = { 0, 0, 0, 0, 0,
+ 0, 0, 1, 1, 1,
+ 1, 1, 1, 1, 0,
+ 1, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0 };
+ f = make::image2d(fvals);
+ debug::println("f", f);
+
+
+ d_ref = morpho::geodesic::impl::dilation_strict_1_set_formula(f, g, nbh);
+ debug::println("d", d_ref);
+
+ d_gen = morpho::geodesic::impl::dilation_permissive_1_set_generic(f, g, nbh);
+ mln_assertion(logical::and_(d_gen, g) == d_ref);
+
+ d_fast = morpho::geodesic::impl::dilation_permissive_1_set_fastest(f, g, nbh);
+ mln_assertion(d_fast == d_gen);
+
+ d_gen_alt = morpho::geodesic::impl::dilation_permissive_1_set_generic_alt(f, g, nbh);
+ mln_assertion(logical::and_(d_gen_alt, g) == d_ref);
+ mln_assertion(d_gen_alt == d_gen);
+
+ d_fast_alt = morpho::geodesic::impl::dilation_permissive_1_set_fastest_alt(f, g, nbh);
+ mln_assertion(d_fast_alt == d_gen_alt);
+}
1
0