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
May 2007
- 3 participants
- 6 discussions
https://svn.lrde.epita.fr/svn/oln/trunk/olena
Users need yet to `typedef` their image type in order to use
Olena's Canvas.
Index: ChangeLog
from Ugo Jardonnet <ugo.jardonnet(a)lrde.epita.fr>
Fix wrong type in cc_tarjan versions.
* oln/core/gen/neighb.hh: .
* oln/morpho/cc_tarjan_v0.hh: .
* oln/morpho/cc_tarjan_v2.hh: .
* oln/morpho/cc_tarjan_v4.hh: .
* oln/morpho/cc_tarjan_v1.hh: .
* oln/morpho/cc_tarjan_v3.hh: .
* oln/canvas/queue_based.hh: .
* oln/canvas/sequential.hh: .
* oln/canvas/parallel.hh: .
* oln/canvas/two_pass_until_stability.hh: .
* oln/canvas/two_pass.hh: .
canvas/parallel.hh | 9 +++--
canvas/queue_based.hh | 9 +++--
canvas/sequential.hh | 9 +++--
canvas/two_pass.hh | 7 ++--
canvas/two_pass_until_stability.hh | 9 +++--
core/gen/neighb.hh | 1
morpho/cc_tarjan_v0.hh | 60 +++++++++++++++++++------------------
morpho/cc_tarjan_v1.hh | 30 +++++++++++-------
morpho/cc_tarjan_v2.hh | 18 ++++++-----
morpho/cc_tarjan_v3.hh | 24 ++++++++------
morpho/cc_tarjan_v4.hh | 22 +++++++------
11 files changed, 115 insertions(+), 83 deletions(-)
Index: oln/core/gen/neighb.hh
--- oln/core/gen/neighb.hh (revision 978)
+++ oln/core/gen/neighb.hh (working copy)
@@ -33,7 +33,6 @@
# include <oln/core/internal/neighborhood_base.hh>
# include <oln/core/gen/dpoints_piter.hh>
-
namespace oln
{
Index: oln/morpho/cc_tarjan_v0.hh
--- oln/morpho/cc_tarjan_v0.hh (revision 978)
+++ oln/morpho/cc_tarjan_v0.hh (working copy)
@@ -47,45 +47,46 @@
namespace impl
{
template <typename I>
- oln_point(I) find_root(I& ima,
+ oln_point(I) find_root(const I& f,
const oln_point(I)& x,
oln_plain_value(I, oln_point(I))& parent)
{
if (parent(x) != x)
{
- parent(x) = find_root(ima, parent(x), parent);
+ parent(x) = find_root(f, parent(x), parent);
return parent(x);
}
return x;
}
template <typename I>
- void do_union(I& ima,
+ void do_union(const I& f,
const oln_point(I)& n,
const oln_point(I)& p,
oln_plain_value(I, oln_point(I))& parent)
{
- oln_point(I) r = find_root(ima, n, parent);
+ oln_point(I) r = find_root(f, n, parent);
if (r != p)
parent(r) = p;
}
- template <typename I>
- void first_pass(const I& input,
+ template <typename I, typename N>
+ void first_pass(const I& f,
oln_plain_value(I, oln_point(I))& parent,
- oln_plain(I)& is_processed)
+ oln_plain(I)& is_processed,
+ const N& nhb)
{
- oln_bkd_piter(I) p(input.points());
+ oln_bkd_piter(I) p(f.points());
for_all(p)
{
parent(p) = p;
- if ( input(p) )
+ if ( f(p) )
{
- oln_niter(I) n(input, p);
- for_all(n)
+ oln_niter(N) n(nhb, p);
+ for_all(n) if ( f.has(n) )
{
- if ( input(n) == true and is_processed(n) )
- do_union(input, n, p, parent);
+ if ( f(n) == true and is_processed(n) )
+ do_union(f, n, p, parent);
}
is_processed(p) = true;
}
@@ -93,38 +94,40 @@
}
template <typename I>
- void second_pass(const I& input,
+ void second_pass(const I& f,
oln_plain_value(I, oln_point(I))& parent,
oln_plain_value(I, unsigned)& output)
{
unsigned current_label = 0;
- oln_fwd_piter(I) p(input.points());
+ oln_fwd_piter(I) p(f.points());
for_all(p)
{
- if ( input(p) == true and parent(p) == p )
+ if ( f(p) == true and parent(p) == p )
output(p) = ++current_label;
else
output(p) = output(parent(p));
}
}
- template <typename I>
+ template <typename I, typename N>
oln_plain_value(I, unsigned)
- cc_tarjan_(const Image_with_Nbh<I>& input)
+ cc_tarjan_(const I& f,
+ const N& nhb)
{
oln_plain_value(I, unsigned) output;
- prepare(output, with, input);
-
+ prepare(output, with, f);
oln_plain_value(I, oln_point(I)) parent;
- prepare(parent, with, input);
+ prepare(parent, with, f);
- // init.
+ // Init
oln_plain_value(I, bool) is_processed;
- prepare(is_processed, with, input);
+ prepare(is_processed, with, f);
level::fill(inplace(is_processed), false);
+ // First pass
+ first_pass(f, parent, is_processed, nhb);
+ // Second pass
+ second_pass(f, parent, output);
- first_pass(input, parent, is_processed);
- second_pass(input, parent, output);
return output;
}
@@ -132,11 +135,12 @@
// Facades.
- template <typename I>
+ template <typename I, typename N>
oln_plain_value(I, unsigned)
- cc_tarjan(const Binary_Image<I>& input)
+ cc_tarjan(const Binary_Image<I>& f,
+ const Neighborhood<N>& nhb)
{
- return impl::cc_tarjan_(exact(input));
+ return impl::cc_tarjan_(exact(f), exact(nhb));
}
# endif // ! OLN_INCLUDE_ONLY
Index: oln/morpho/cc_tarjan_v2.hh
--- oln/morpho/cc_tarjan_v2.hh (revision 978)
+++ oln/morpho/cc_tarjan_v2.hh (working copy)
@@ -49,16 +49,19 @@
namespace impl
{
- template <typename I>
+ template <typename I, typename N>
struct cc_tarjan_
{
typedef oln_point(I) point;
+ const N& nbh;
oln_plain_value(I, unsigned) output;
oln_plain_value(I, bool) is_processed;
oln_plain_value(I, point) parent;
- cc_tarjan_() {}
+ cc_tarjan_(const N& nbh)
+ : nbh(nbh)
+ { }
void init(I f)
{
@@ -73,8 +76,8 @@
parent(p) = p;
if ( f(p) )
{
- oln_niter(I) n(f, p);
- for_all(n)
+ oln_niter(N) n(nbh, p);
+ for_all(n) if ( f.has(n) )
{
if ( f(n) == true and is_processed(n) )
do_union(f, n, p);
@@ -124,11 +127,12 @@
// Facades.
- template <typename I>
+ template <typename I, typename N>
oln_plain_value(I, unsigned)
- cc_tarjan(const Image_with_Nbh<I>& f)
+ cc_tarjan(const Binary_Image<I>& f,
+ const Neighborhood<N>& nbh)
{
- impl::cc_tarjan_<I> run;
+ impl::cc_tarjan_<I,N> run(exact(nbh));
canvas::v2::two_pass(run, exact(f));
return run.output;
}
Index: oln/morpho/cc_tarjan_v4.hh
--- oln/morpho/cc_tarjan_v4.hh (revision 978)
+++ oln/morpho/cc_tarjan_v4.hh (working copy)
@@ -47,21 +47,22 @@
namespace impl
{
- template <typename I>
- struct cc_tarjan_ : public canvas::v4::two_pass<I, cc_tarjan_<I> >
+ template <typename I, typename N>
+ struct cc_tarjan_ : public canvas::v4::two_pass<I, cc_tarjan_<I, N> >
{
typedef oln_point(I) point;
const I& f;
+ const N& nbh;
oln_plain_value(I, unsigned) output;
oln_plain_value(I, bool) is_processed;
oln_plain_value(I, point) parent;
unsigned nlabels;
- cc_tarjan_(const I& f)
- : canvas::v4::two_pass<I, cc_tarjan_<I> >(f),
- f(f)
+ cc_tarjan_(const I& f, const N& nbh)
+ : canvas::v4::two_pass<I, cc_tarjan_<I, N> >(f),
+ f(f), nbh(nbh)
{
}
@@ -79,8 +80,8 @@
parent(p) = p;
if (f(p) == true)
{
- oln_niter(I) n(f, p);
- for_all(n)
+ oln_niter(N) n(nbh, p);
+ for_all(n) if ( f.has(n) )
{
if ( f(n) == true and is_processed(n) )
do_union(n, p);
@@ -127,11 +128,12 @@
} // end of namespace oln::morpho::impl
- template <typename I>
+ template <typename I, typename N>
oln_plain_value(I, unsigned)
- cc_tarjan(const Image_with_Nbh<I>& f)
+ cc_tarjan(const Image<I>& f,
+ const Neighborhood<N>& nbh)
{
- impl::cc_tarjan_<I> cc(exact(f));
+ impl::cc_tarjan_<I, N> cc(exact(f), exact(nbh));
cc.run();
Index: oln/morpho/cc_tarjan_v1.hh
--- oln/morpho/cc_tarjan_v1.hh (revision 978)
+++ oln/morpho/cc_tarjan_v1.hh (working copy)
@@ -53,20 +53,23 @@
namespace impl
{
- template <typename I>
+ template <typename I, typename N>
struct cc_tarjan_
{
typedef oln_point(I) point;
+ typedef I image;
const I& f;
+ const N& nbh;
oln_plain_value(I, unsigned) output;
oln_plain_value(I, bool) is_processed;
oln_plain_value(I, point) parent;
unsigned nlabels;
- cc_tarjan_(const I& f)
- : f(f)
+ cc_tarjan_(const I& f,
+ const N& nbh)
+ : f(f), nbh(nbh)
{
}
@@ -84,8 +87,8 @@
parent(p) = p;
if (f(p) == true)
{
- oln_niter(I) n(f, p);
- for_all(n)
+ oln_niter(N) n(nbh, p);
+ for_all(n) if ( f.has(n) )
{
if ( f(n) == true and is_processed(n) )
do_union(n, p);
@@ -137,23 +140,26 @@
// Facades.
- template <typename I>
+ template <typename I, typename N>
oln_plain_value(I, unsigned)
- cc_tarjan(const Image_with_Nbh<I>& f, unsigned& nlabels)
+ cc_tarjan(const Image<I>& f,
+ const Neighborhood<N>& nbh,
+ unsigned& nlabels)
{
- impl::cc_tarjan_<I> run(exact(f));
+ impl::cc_tarjan_<I, N> run(exact(f), exact(nbh));
canvas::v1::two_pass(run);
nlabels = run.nlabels;
oln_plain_value(I, unsigned) tmp = run.output;
return tmp;
}
- template <typename I>
+ template <typename I, typename N>
oln_plain_value(I, unsigned)
- cc_tarjan(const Image_with_Nbh<I>& f)
+ cc_tarjan(const Image<I>& f,
+ const Neighborhood<N>& nbh)
{
- unsigned nlabels;
- return cc_tarjan(f, nlabels);
+ unsigned nlabels = 0;
+ return cc_tarjan(f, nbh, nlabels);
}
# endif // ! OLN_INCLUDE_ONLY
Index: oln/morpho/cc_tarjan_v3.hh
--- oln/morpho/cc_tarjan_v3.hh (revision 978)
+++ oln/morpho/cc_tarjan_v3.hh (working copy)
@@ -48,18 +48,21 @@
namespace impl
{
- template <typename T>
+ template <typename T, typename U>
struct data_
{
typedef T I;
+ typedef U N;
const I& f;
+ const N& nbh;
+
oln_plain_value(I, unsigned) output;
oln_plain(I) is_processed;
oln_plain_value(I, oln_point(I)) parent;
- data_(const I& f)
- : f(f)
+ data_(const I& f, const N& nbh)
+ : f(f), nbh(nbh)
{
}
};
@@ -107,8 +110,8 @@
data.parent(p) = p;
if ( data.f(p) )
{
- oln_niter(Data::I) n(data.f, p);
- for_all(n)
+ oln_niter(Data::N) n(data.nbh, p);
+ for_all(n) if ( data.f.has(n) )
{
if ( data.f(n) == true and data.is_processed(n) )
do_union(data, n, p);
@@ -137,14 +140,15 @@
// Facades.
- template <typename I>
+ template <typename I, typename N>
oln_plain_value(I, unsigned)
- cc_tarjan(const Image_with_Nbh<I>& input)
+ cc_tarjan(const Binary_Image<I>& input,
+ const Neighborhood<N>& nbh)
{
- typedef impl::data_<I> data_t;
+ typedef impl::data_<I, N> data_t;
- data_t data(exact(input));
- impl::cc_tarjan_< impl::data_<I> > f;
+ data_t data(exact(input), exact(nbh));
+ impl::cc_tarjan_< data_t > f;
canvas::v3::two_pass(f, data);
return data.output;
}
Index: oln/canvas/queue_based.hh
--- oln/canvas/queue_based.hh (revision 978)
+++ oln/canvas/queue_based.hh (working copy)
@@ -34,10 +34,13 @@
namespace canvas
{
- template <template <class> class F,
- typename I, typename Queue>
- void queue_based(F<I>& fun)
+ template <typename F, typename Queue>
+ void queue_based(F& fun)
{
+
+ typedef typename F::image I;
+ mlc::assert_< mlc_is_a(I, Image) >::check();
+
Queue q;
fun.init();
Index: oln/canvas/sequential.hh
--- oln/canvas/sequential.hh (revision 978)
+++ oln/canvas/sequential.hh (working copy)
@@ -36,10 +36,13 @@
namespace canvas
{
- template <template <class> class F,
- typename I>
- void sequential(F<I>& fun)
+ template <typename F>
+ void sequential(F& fun)
{
+
+ typedef typename F::image I;
+ mlc::assert_< mlc_is_a(I, Image) >::check();
+
bool stability;
fun.init();
Index: oln/canvas/parallel.hh
--- oln/canvas/parallel.hh (revision 978)
+++ oln/canvas/parallel.hh (working copy)
@@ -36,10 +36,13 @@
namespace canvas
{
- template <template <class> class F,
- typename I>
- void parallel(F<I>& fun)
+ template <typename F>
+ void parallel(F& fun)
{
+
+ typedef typename F::image I;
+ mlc::assert_< mlc_is_a(I, Image) >::check();
+
fun.init();
oln_piter(I) p(fun.f.points());
Index: oln/canvas/two_pass_until_stability.hh
--- oln/canvas/two_pass_until_stability.hh (revision 978)
+++ oln/canvas/two_pass_until_stability.hh (working copy)
@@ -34,10 +34,13 @@
namespace canvas
{
- template <template <class> class F,
- typename I>
- void two_pass_until_stability(F<I>& fun)
+ template <typename F>
+ void two_pass_until_stability(F& fun)
{
+
+ typedef typename F::image I;
+ mlc::assert_< mlc_is_a(I, Image) >::check();
+
bool stability;
fun.init();
Index: oln/canvas/two_pass.hh
--- oln/canvas/two_pass.hh (revision 978)
+++ oln/canvas/two_pass.hh (working copy)
@@ -39,10 +39,11 @@
namespace v1
{
- template <template <class> class F,
- typename I> // Data owned by f.
- void two_pass(F<I>& fun)
+ template <typename F> // Data owned by f.
+ void two_pass(F& fun)
{
+
+ typedef typename F::image I;
mlc::assert_< mlc_is_a(I, Image) >::check();
fun.init();
1
0
https://svn.lrde.epita.fr/svn/oln/trunk/olena
Index: ChangeLog
from Thierry Geraud <thierry.geraud(a)lrde.epita.fr>
Add raw code for morphological reconstruction by d.
* oln/morpho/Rd: New directory.
* oln/morpho/Rd/hybrid.hh,
* oln/morpho/Rd/queue_based.hh,
* oln/morpho/Rd/parallel.cc,
* oln/morpho/Rd/hybrid.cc,
* oln/morpho/Rd/union_find.hh,
* oln/morpho/Rd/queue_based.cc,
* oln/morpho/Rd/sequential.hh,
* oln/morpho/Rd/debase.union_find.hh,
* oln/morpho/Rd/parallel.hh,
* oln/morpho/Rd/diff.cc,
* oln/morpho/Rd/union_find.cc,
* oln/morpho/Rd/sequential.cc,
* oln/morpho/Rd/utils.hh,
* oln/io/save_pgm.hh,
* oln/io/load_pgm.hh: New.
* oln/debug/format.hh: Update.
* oln/core/gen/neighb.hh (niter): New associated type.
* oln/level/fill.hh (iterator): Add include.
core/gen/neighb.hh | 4
debug/format.hh | 15 +-
io/load_pgm.hh | 169 +++++++++++++++++++++++++++
io/save_pgm.hh | 68 +++++++++++
level/fill.hh | 1
morpho/Rd/debase.union_find.hh | 165 +++++++++++++++++++++++++++
morpho/Rd/diff.cc | 28 ++++
morpho/Rd/hybrid.cc | 46 +++++++
morpho/Rd/hybrid.hh | 103 ++++++++++++++++
morpho/Rd/parallel.cc | 46 +++++++
morpho/Rd/parallel.hh | 80 +++++++++++++
morpho/Rd/queue_based.cc | 46 +++++++
morpho/Rd/queue_based.hh | 106 +++++++++++++++++
morpho/Rd/sequential.cc | 46 +++++++
morpho/Rd/sequential.hh | 85 +++++++++++++
morpho/Rd/union_find.cc | 46 +++++++
morpho/Rd/union_find.hh | 165 +++++++++++++++++++++++++++
morpho/Rd/utils.hh | 250 +++++++++++++++++++++++++++++++++++++++++
18 files changed, 1466 insertions(+), 3 deletions(-)
Index: oln/debug/format.hh
--- oln/debug/format.hh (revision 977)
+++ oln/debug/format.hh (working copy)
@@ -28,6 +28,9 @@
#ifndef OLN_DEBUG_FORMAT_HH
# define OLN_DEBUG_FORMAT_HH
+# include <string>
+# include <sstream>
+
namespace oln
{
@@ -41,7 +44,7 @@
const T&
format(const T& value);
- unsigned
+ std::string
format(const unsigned char& value);
char
@@ -56,9 +59,15 @@
return value;
}
- unsigned format(const unsigned char& value)
+ std::string format(const unsigned char& value)
{
- return value;
+ std::ostringstream ostr;
+ if (value < 10)
+ ostr << "00";
+ else if (value < 100)
+ ostr << '0';
+ ostr << unsigned(value);
+ return ostr.str();
}
char format(bool value)
Index: oln/core/gen/neighb.hh
--- oln/core/gen/neighb.hh (revision 977)
+++ oln/core/gen/neighb.hh (working copy)
@@ -31,6 +31,7 @@
# include <oln/core/internal/dpoints_impl.hh>
# include <oln/core/internal/neighborhood_base.hh>
+# include <oln/core/gen/dpoints_piter.hh>
namespace oln
@@ -65,6 +66,9 @@
{
public:
+ typedef stc_type(Dp, point) P;
+ typedef dpoints_fwd_piter_<P> niter;
+
neighb_();
neighb_<Dp>& take(const Dp& dp);
Index: oln/morpho/Rd/hybrid.hh
--- oln/morpho/Rd/hybrid.hh (revision 0)
+++ oln/morpho/Rd/hybrid.hh (revision 0)
@@ -0,0 +1,103 @@
+// Copyright (C) 2007 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#ifndef OLN_MORPHO_RD_HYBRID_HH
+# define OLN_MORPHO_RD_HYBRID_HH
+
+# include <queue>
+# include <oln/morpho/Rd/utils.hh>
+
+
+namespace oln
+{
+
+ namespace morpho
+ {
+
+ namespace Rd
+ {
+
+
+ template <typename I, typename N>
+ I hybrid(const I& f, const I& g, const N& nbh,
+ bool echo = false)
+ {
+ typedef oln_point(I) point;
+ std::queue<point> q;
+
+ // initialisation
+ I o = level::clone(f);
+
+ // sequence
+ {
+ oln_bkd_piter(I) p(f.points());
+ for_all(p)
+ o(p) = min( max_Nminus(o, p,nbh), g(p) );
+ }
+ {
+ oln_fwd_piter(I) p(f.points());
+ oln_niter(N) n(nbh, p);
+ for_all(p)
+ {
+ o(p) = min( max_Nplus(o, p,nbh), g(p) );
+ for_all(n) if (f.has(n) and n < p) // N+
+ if (o(n) < o(p) and o(n) < g(n))
+ q.push(p);
+ }
+ }
+
+ // propagation
+ {
+ point p;
+ oln_niter(N) n(nbh, p);
+ while (not q.empty())
+ {
+ p = q.front();
+ if (echo) std::cout << std::endl << "pop " << p << " :";
+ q.pop();
+ for_all(n) if (f.has(n))
+ if (o(n) < o(p) and o(n) != g(n))
+ {
+ o(n) = min(o(p), g(n));
+ if (echo) std::cout << " push " << n;
+ q.push(n);
+ }
+ }
+ if (echo) std::cout << std::endl;
+ }
+
+ return o;
+ }
+
+ } // end of namespace oln::morpho::Rd
+
+ } // end of namespace oln::morpho
+
+} // end of namespace oln
+
+
+#endif // ! OLN_MORPHO_RD_HYBRID_HH
Index: oln/morpho/Rd/queue_based.hh
--- oln/morpho/Rd/queue_based.hh (revision 0)
+++ oln/morpho/Rd/queue_based.hh (revision 0)
@@ -0,0 +1,106 @@
+// Copyright (C) 2007 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#ifndef OLN_MORPHO_RD_QUEUE_BASED_HH
+# define OLN_MORPHO_RD_QUEUE_BASED_HH
+
+# include <queue>
+# include <oln/morpho/Rd/utils.hh>
+
+
+namespace oln
+{
+
+ namespace morpho
+ {
+
+ namespace Rd
+ {
+
+ template <typename I, typename N>
+ I queue_based(const I& f, const I& g, const N& nbh,
+ bool echo = false)
+ {
+ if (echo) std::cout << std::endl;
+
+ typedef oln_point(I) point;
+ std::queue<point> q;
+ I o;
+
+ // initialisation
+ {
+ o = regional_maxima(f, nbh);
+ if (echo) debug::println(o);
+
+ oln_piter(I) p(f.points());
+ oln_niter(N) n(nbh, p);
+
+ for_all(p)
+ if (o(p) != 0)
+ {
+ bool ok = false;
+ for_all(n) if (f.has(n))
+ if (o(n) = 0)
+ ok = true;
+ if (ok)
+ q.push(p);
+ }
+ }
+
+ // propagation
+ {
+ point p;
+ oln_niter(N) n(nbh, p);
+ while (not q.empty())
+ {
+ p = q.front();
+ if (echo) std::cout << std::endl << "pop " << p << " :";
+ q.pop();
+ for_all(n) if (f.has(n))
+ {
+ if (o(n) < o(p) and o(n) != g(n))
+ {
+ o(n) = min(o(p), g(n));
+ if (echo) std::cout << " push " << n;
+ q.push(n);
+ }
+ }
+ }
+ if (echo) std::cout << std::endl;
+ }
+
+ return o;
+ }
+
+ } // end of namespace oln::morpho::Rd
+
+ } // end of namespace oln::morpho
+
+} // end of namespace oln
+
+
+#endif // ! OLN_MORPHO_RD_QUEUE_BASED_HH
Index: oln/morpho/Rd/parallel.cc
--- oln/morpho/Rd/parallel.cc (revision 0)
+++ oln/morpho/Rd/parallel.cc (revision 0)
@@ -0,0 +1,46 @@
+#include <oln/core/2d/image2d.hh>
+#include <oln/core/2d/neighb2d.hh>
+
+#include <oln/debug/println.hh>
+#include <oln/io/load_pgm.hh>
+#include <oln/io/save_pgm.hh>
+#include <oln/morpho/Rd/parallel.hh>
+
+
+void usage(char* argv[])
+{
+ std::cerr << "usage: " << argv[0] << " f.pgm g.pgm c output.pgm" << std::endl
+ << "reconstruction by dilation (parallel version; may 2007)" << std::endl
+ << "f = marker (to be dilated)" << std::endl
+ << "g = mask (constraint >= f)" << std::endl
+ << "c: 4 or 8" << std::endl;
+ exit(1);
+}
+
+
+int main(int argc, char* argv[])
+{
+ if (argc != 5)
+ usage(argv);
+
+ using namespace oln;
+ typedef image2d<unsigned char> I;
+
+ int c = atoi(argv[3]);
+ if (c != 4 and c != 8)
+ usage(argv);
+
+ I f = io::load_pgm(argv[1]);
+ I g = io::load_pgm(argv[2]);
+
+ if (not (f <= g))
+ {
+ std::cerr << "pb" << std::endl;
+ return 1;
+ }
+
+ io::save_pgm(morpho::Rd::parallel(f, g,
+ (c = 4 ? c4 : c8)),
+ argv[4]);
+ return 0;
+}
Index: oln/morpho/Rd/hybrid.cc
--- oln/morpho/Rd/hybrid.cc (revision 0)
+++ oln/morpho/Rd/hybrid.cc (revision 0)
@@ -0,0 +1,46 @@
+#include <oln/core/2d/image2d.hh>
+#include <oln/core/2d/neighb2d.hh>
+
+#include <oln/debug/println.hh>
+#include <oln/io/load_pgm.hh>
+#include <oln/io/save_pgm.hh>
+#include <oln/morpho/Rd/hybrid.hh>
+
+
+void usage(char* argv[])
+{
+ std::cerr << "usage: " << argv[0] << " f.pgm g.pgm c output.pgm" << std::endl
+ << "reconstruction by dilation (hybrid version; may 2007)" << std::endl
+ << "f = marker (to be dilated)" << std::endl
+ << "g = mask (constraint >= f)" << std::endl
+ << "c: 4 or 8" << std::endl;
+ exit(1);
+}
+
+
+int main(int argc, char* argv[])
+{
+ if (argc != 5)
+ usage(argv);
+
+ using namespace oln;
+ typedef image2d<unsigned char> I;
+
+ int c = atoi(argv[3]);
+ if (c != 4 and c != 8)
+ usage(argv);
+
+ I f = io::load_pgm(argv[1]);
+ I g = io::load_pgm(argv[2]);
+
+ if (not (f <= g))
+ {
+ std::cerr << "pb" << std::endl;
+ return 1;
+ }
+
+ io::save_pgm(morpho::Rd::hybrid(f, g,
+ (c = 4 ? c4 : c8)),
+ argv[4]);
+ return 0;
+}
Index: oln/morpho/Rd/union_find.hh
--- oln/morpho/Rd/union_find.hh (revision 0)
+++ oln/morpho/Rd/union_find.hh (revision 0)
@@ -0,0 +1,165 @@
+// Copyright (C) 2007 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#ifndef OLN_MORPHO_RD_UNION_FIND_HH
+# define OLN_MORPHO_RD_UNION_FIND_HH
+
+# include <oln/morpho/Rd/utils.hh>
+
+
+namespace oln
+{
+
+ namespace morpho
+ {
+
+ namespace Rd
+ {
+
+
+ template <typename I, typename N>
+ struct union_find_t
+ {
+ typedef oln_point(I) point;
+
+ // in:
+ I f, g;
+ N nbh;
+
+ // out:
+ I o;
+
+ // aux:
+ std::vector<point> S;
+ I data;
+ oln_plain_value(I, bool) is_proc;
+ oln_plain_value(I, point) parent;
+
+ union_find_t(const I& f, const I& g, const N& nbh)
+ : f(f), g(g), nbh(nbh)
+ {
+ prepare(o, with, f);
+ prepare(parent, with, f);
+ prepare(is_proc, with, f);
+ prepare(data, with, f);
+
+ // init
+
+ std::cout << "0 ";
+ level::fill(inplace(is_proc), false);
+ S = histo_reverse_sort(g);
+
+ // first pass
+
+ std::cout << "1 ";
+ for (unsigned i = 0; i < S.size(); ++i)
+ {
+ point p = S[i];
+
+ make_set(p);
+ oln_niter(N) n(nbh, p);
+ for_all(n)
+ if (f.has(n) and is_proc(n))
+ do_union(n, p);
+ is_proc(p) = true;
+ }
+
+ // second pass
+
+ std::cout << "2 ";
+ level::fill(inplace(is_proc), false);
+ for (int i = S.size() - 1; i >= 0; --i)
+ {
+ point p = S[i];
+ assert(is_proc(p) = false);
+ if (parent(p) = p)
+ o(p) = data(p) = 255 ? g(p) : data(p);
+ else
+ {
+ assert(is_proc(parent(p)) = true);
+ o(p) = o(parent(p));
+ }
+ is_proc(p) = true;
+ }
+
+ }
+
+ void make_set(const point& p)
+ {
+ parent(p) = p;
+ data(p) = f(p);
+ }
+
+ point find_root(const point& x)
+ {
+ if (parent(x) = x)
+ return x;
+ else
+ return parent(x) = find_root(parent(x));
+ }
+
+ bool equiv(const point& r, const point& p)
+ {
+ return g(r) = g(p) or g(p) >= data(r);
+ }
+
+ void do_union(const point& n, const point& p)
+ {
+ point r = find_root(n);
+ if (r != p)
+ {
+ if (equiv(r, p))
+ {
+ parent(r) = p;
+ if (data(r) > data(p))
+ data(p) = data(r); // increasing criterion
+ }
+ else
+ data(p) = 255;
+ }
+ }
+
+ };
+
+
+ template <typename I, typename N>
+ I union_find(const I& f, const I& g, const N& nbh)
+ {
+ precondition(f <= g);
+ union_find_t<I, N> run(f, g, nbh);
+ return run.o;
+ }
+
+
+ } // end of namespace oln::morpho::Rd
+
+ } // end of namespace oln::morpho
+
+} // end of namespace oln
+
+
+#endif // ! OLN_MORPHO_RD_UNION_FIND_HH
Index: oln/morpho/Rd/queue_based.cc
--- oln/morpho/Rd/queue_based.cc (revision 0)
+++ oln/morpho/Rd/queue_based.cc (revision 0)
@@ -0,0 +1,46 @@
+#include <oln/core/2d/image2d.hh>
+#include <oln/core/2d/neighb2d.hh>
+
+#include <oln/debug/println.hh>
+#include <oln/io/load_pgm.hh>
+#include <oln/io/save_pgm.hh>
+#include <oln/morpho/Rd/queue_based.hh>
+
+
+void usage(char* argv[])
+{
+ std::cerr << "usage: " << argv[0] << " f.pgm g.pgm c output.pgm" << std::endl
+ << "reconstruction by dilation (queue_based version; may 2007)" << std::endl
+ << "f = marker (to be dilated)" << std::endl
+ << "g = mask (constraint >= f)" << std::endl
+ << "c: 4 or 8" << std::endl;
+ exit(1);
+}
+
+
+int main(int argc, char* argv[])
+{
+ if (argc != 5)
+ usage(argv);
+
+ using namespace oln;
+ typedef image2d<unsigned char> I;
+
+ int c = atoi(argv[3]);
+ if (c != 4 and c != 8)
+ usage(argv);
+
+ I f = io::load_pgm(argv[1]);
+ I g = io::load_pgm(argv[2]);
+
+ if (not (f <= g))
+ {
+ std::cerr << "pb" << std::endl;
+ return 1;
+ }
+
+ io::save_pgm(morpho::Rd::queue_based(f, g,
+ (c = 4 ? c4 : c8)),
+ argv[4]);
+ return 0;
+}
Index: oln/morpho/Rd/sequential.hh
--- oln/morpho/Rd/sequential.hh (revision 0)
+++ oln/morpho/Rd/sequential.hh (revision 0)
@@ -0,0 +1,85 @@
+// Copyright (C) 2007 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#ifndef OLN_MORPHO_RD_SEQUENTIAL_HH
+# define OLN_MORPHO_RD_SEQUENTIAL_HH
+
+# include <oln/morpho/Rd/utils.hh>
+
+
+namespace oln
+{
+
+ namespace morpho
+ {
+
+ namespace Rd
+ {
+
+ template <typename I, typename N>
+ I sequential(const I& f, const I& g, const N& nbh)
+ {
+ precondition(f <= g);
+ I o_(f.points());
+
+ // initialisation
+ I o = level::clone(f);
+
+ bool stability;
+ do
+ {
+ level::paste(o, inplace(o_)); // memorisation
+
+ // passe 1
+ {
+ oln_bkd_piter(I) p(f.points());
+ for_all(p)
+ o(p) = min( max_Nminus(o, p,nbh), g(p) );
+ }
+
+ // passe 2
+ {
+ oln_fwd_piter(I) p(f.points());
+ for_all(p)
+ o(p) = min( max_Nplus(o, p,nbh), g(p) );
+ }
+
+ stability = (o = o_);
+ }
+ while (not stability);
+ postcondition(o <= g);
+ return o;
+ }
+
+ } // end of namespace oln::morpho::Rd
+
+ } // end of namespace oln::morpho
+
+} // end of namespace oln
+
+
+#endif // ! OLN_MORPHO_RD_SEQUENTIAL_HH
Index: oln/morpho/Rd/debase.union_find.hh
--- oln/morpho/Rd/debase.union_find.hh (revision 0)
+++ oln/morpho/Rd/debase.union_find.hh (revision 0)
@@ -0,0 +1,165 @@
+// Copyright (C) 2007 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#ifndef OLN_MORPHO_RD_UNION_FIND_HH
+# define OLN_MORPHO_RD_UNION_FIND_HH
+
+# include <oln/morpho/Rd/utils.hh>
+
+
+namespace oln
+{
+
+ namespace morpho
+ {
+
+ namespace Rd
+ {
+
+
+ template <typename I, typename N>
+ struct union_find_t
+ {
+ typedef oln_point(I) point;
+
+ // in:
+ I f, g;
+ N nbh;
+
+ // out:
+ I o;
+
+ // aux:
+ std::vector<point> S;
+ I data;
+ oln_plain_value(I, bool) is_proc;
+ oln_plain_value(I, point) parent;
+
+ union_find_t(const I& f, const I& g, const N& nbh)
+ : f(f), g(g), nbh(nbh)
+ {
+ prepare(o, with, f);
+ prepare(parent, with, f);
+ prepare(is_proc, with, f);
+ prepare(data, with, f);
+
+ // init
+
+ std::cout << "0 ";
+ level::fill(inplace(is_proc), false);
+ S = histo_reverse_sort(g);
+
+ // first pass
+
+ std::cout << "1 ";
+ for (unsigned i = 0; i < S.size(); ++i)
+ {
+ point p = S[i];
+
+ make_set(p);
+ oln_niter(N) n(nbh, p);
+ for_all(n)
+ if (f.has(n) and is_proc(n))
+ do_union(n, p);
+ is_proc(p) = true;
+ }
+
+ // second pass
+
+ std::cout << "2 ";
+ level::fill(inplace(is_proc), false);
+ for (int i = S.size() - 1; i >= 0; --i)
+ {
+ point p = S[i];
+ assert(is_proc(p) = false);
+ if (parent(p) = p)
+ o(p) = data(p) = 255 ? g(p) : data(p);
+ else
+ {
+ assert(is_proc(parent(p)) = true);
+ o(p) = o(parent(p));
+ }
+ is_proc(p) = true;
+ }
+
+ }
+
+ void make_set(const point& p)
+ {
+ parent(p) = p;
+ data(p) = f(p);
+ }
+
+ point find_root(const point& x)
+ {
+ if (parent(x) = x)
+ return x;
+ else
+ return parent(x) = find_root(parent(x));
+ }
+
+ bool equiv(const point& r, const point& p)
+ {
+ return g(r) = g(p) or g(p) >= data(r);
+ }
+
+ void do_union(const point& n, const point& p)
+ {
+ point r = find_root(n);
+ if (r != p)
+ {
+ if (equiv(r, p))
+ {
+ parent(r) = p;
+ if (data(r) > data(p))
+ data(p) = data(r); // increasing criterion
+ }
+ else
+ data(p) = 255;
+ }
+ }
+
+ };
+
+
+ template <typename I, typename N>
+ I union_find(const I& f, const I& g, const N& nbh)
+ {
+ precondition(f <= g);
+ union_find_t<I, N> run(f, g, nbh);
+ return run.o;
+ }
+
+
+ } // end of namespace oln::morpho::Rd
+
+ } // end of namespace oln::morpho
+
+} // end of namespace oln
+
+
+#endif // ! OLN_MORPHO_RD_UNION_FIND_HH
Index: oln/morpho/Rd/parallel.hh
--- oln/morpho/Rd/parallel.hh (revision 0)
+++ oln/morpho/Rd/parallel.hh (revision 0)
@@ -0,0 +1,80 @@
+// Copyright (C) 2007 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#ifndef OLN_MORPHO_RD_PARALLEL_HH
+# define OLN_MORPHO_RD_PARALLEL_HH
+
+# include <oln/morpho/Rd/utils.hh>
+
+
+namespace oln
+{
+
+ namespace morpho
+ {
+
+ namespace Rd
+ {
+
+ template <typename I, typename N>
+ I parallel(const I& f, const I& g, const N& nbh)
+ {
+ precondition(f <= g);
+ I o_(f.points());
+ oln_piter(I) p(f.points());
+
+ // initialisation
+ I o = level::clone(f);
+
+ bool stability;
+ do
+ {
+ level::paste(o, inplace(o_)); // memorisation
+
+ // opere
+ for_all(p)
+ o(p) = max_N(o_, p,nbh);
+ // conditionne
+ for_all(p)
+ o(p) = min(o(p), g(p));
+
+ stability = (o = o_);
+ }
+ while (not stability);
+
+ postcondition(o <= g);
+ return o;
+ }
+
+ } // end of namespace oln::morpho::Rd
+
+ } // end of namespace oln::morpho
+
+} // end of namespace oln
+
+
+#endif // ! OLN_MORPHO_RD_PARALLEL_HH
Index: oln/morpho/Rd/diff.cc
--- oln/morpho/Rd/diff.cc (revision 0)
+++ oln/morpho/Rd/diff.cc (revision 0)
@@ -0,0 +1,28 @@
+#include <oln/core/2d/image2d.hh>
+#include <oln/io/load_pgm.hh>
+#include <oln/level/compare.hh>
+
+
+void usage(char* argv[])
+{
+ std::cerr << "usage: " << argv[0] << " 1.pgm 2.pgm" << std::endl
+ << "(may 2007)" << std::endl;
+ exit(1);
+}
+
+
+int main(int argc, char* argv[])
+{
+ if (argc != 3)
+ usage(argv);
+
+ using namespace oln;
+ typedef image2d<unsigned char> I;
+
+ I ima1 = io::load_pgm(argv[1]);
+ I ima2 = io::load_pgm(argv[2]);
+
+ if (ima1 != ima2)
+ std::cout << "images differ" << std::endl;
+ return 0;
+}
Index: oln/morpho/Rd/union_find.cc
--- oln/morpho/Rd/union_find.cc (revision 0)
+++ oln/morpho/Rd/union_find.cc (revision 0)
@@ -0,0 +1,46 @@
+#include <oln/core/2d/image2d.hh>
+#include <oln/core/2d/neighb2d.hh>
+
+#include <oln/debug/println.hh>
+#include <oln/io/load_pgm.hh>
+#include <oln/io/save_pgm.hh>
+#include <oln/morpho/Rd/union_find.hh>
+
+
+void usage(char* argv[])
+{
+ std::cerr << "usage: " << argv[0] << " f.pgm g.pgm c output.pgm" << std::endl
+ << "reconstruction by dilation (union_find version; may 2007)" << std::endl
+ << "f = marker (to be dilated)" << std::endl
+ << "g = mask (constraint >= f)" << std::endl
+ << "c: 4 or 8" << std::endl;
+ exit(1);
+}
+
+
+int main(int argc, char* argv[])
+{
+ if (argc != 5)
+ usage(argv);
+
+ using namespace oln;
+ typedef image2d<unsigned char> I;
+
+ int c = atoi(argv[3]);
+ if (c != 4 and c != 8)
+ usage(argv);
+
+ I f = io::load_pgm(argv[1]);
+ I g = io::load_pgm(argv[2]);
+
+ if (not (f <= g))
+ {
+ std::cerr << "pb" << std::endl;
+ return 1;
+ }
+
+ io::save_pgm(morpho::Rd::union_find(f, g,
+ (c = 4 ? c4 : c8)),
+ argv[4]);
+ return 0;
+}
Index: oln/morpho/Rd/sequential.cc
--- oln/morpho/Rd/sequential.cc (revision 0)
+++ oln/morpho/Rd/sequential.cc (revision 0)
@@ -0,0 +1,46 @@
+#include <oln/core/2d/image2d.hh>
+#include <oln/core/2d/neighb2d.hh>
+
+#include <oln/debug/println.hh>
+#include <oln/io/load_pgm.hh>
+#include <oln/io/save_pgm.hh>
+#include <oln/morpho/Rd/sequential.hh>
+
+
+void usage(char* argv[])
+{
+ std::cerr << "usage: " << argv[0] << " f.pgm g.pgm c output.pgm" << std::endl
+ << "reconstruction by dilation (sequential version; may 2007)" << std::endl
+ << "f = marker (to be dilated)" << std::endl
+ << "g = mask (constraint >= f)" << std::endl
+ << "c: 4 or 8" << std::endl;
+ exit(1);
+}
+
+
+int main(int argc, char* argv[])
+{
+ if (argc != 5)
+ usage(argv);
+
+ using namespace oln;
+ typedef image2d<unsigned char> I;
+
+ int c = atoi(argv[3]);
+ if (c != 4 and c != 8)
+ usage(argv);
+
+ I f = io::load_pgm(argv[1]);
+ I g = io::load_pgm(argv[2]);
+
+ if (not (f <= g))
+ {
+ std::cerr << "pb" << std::endl;
+ return 1;
+ }
+
+ io::save_pgm(morpho::Rd::sequential(f, g,
+ (c = 4 ? c4 : c8)),
+ argv[4]);
+ return 0;
+}
Index: oln/morpho/Rd/utils.hh
--- oln/morpho/Rd/utils.hh (revision 0)
+++ oln/morpho/Rd/utils.hh (revision 0)
@@ -0,0 +1,250 @@
+// Copyright (C) 2007 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#ifndef OLN_MORPHO_RD_UTILS_HH
+# define OLN_MORPHO_RD_UTILS_HH
+
+# include <vector>
+
+# include <oln/core/concept/image.hh>
+# include <oln/core/internal/f_ch_value.hh>
+
+# include <oln/level/fill.hh>
+# include <oln/level/paste.hh>
+# include <oln/level/clone.hh>
+# include <oln/level/compare.hh>
+
+
+
+namespace oln
+{
+
+ namespace morpho
+ {
+
+ namespace Rd
+ {
+
+
+ template <typename T>
+ T min(T v1, T v2)
+ {
+ return v1 < v2 ? v1 : v2;
+ }
+
+
+ template <typename I>
+ std::vector<unsigned> compute_histo(const I& ima)
+ {
+ std::vector<unsigned> h(256, 0);
+ oln_piter(I) p(ima.points());
+ for_all(p)
+ ++h[ima(p)];
+ return h;
+ }
+
+
+ template <typename I>
+ std::vector<oln_point(I)> histo_sort(const I& ima)
+ {
+ std::vector<unsigned> h = compute_histo(ima);
+ // preparing output data
+ std::vector<int> loc(256);
+ loc[0] = 0;
+ for (int l = 1; l < 256; ++l)
+ loc[l] = loc[l-1] + h[l-1];
+ std::vector<oln_point(I)> vec(ima.points().npoints());
+ // storing output data
+ oln_piter(I) p(ima.points());
+ for_all(p)
+ vec[loc[ima(p)]++] = p;
+ return vec;
+ }
+
+
+ template <typename I>
+ std::vector<oln_point(I)> histo_reverse_sort(const I& ima)
+ {
+ std::vector<unsigned> h = compute_histo(ima);
+ // preparing output data
+ std::vector<int> loc(256);
+ loc[255] = 0;
+ for (int l = 254; l >= 0; --l)
+ loc[l] = loc[l+1] + h[l+1];
+ std::vector<oln_point(I)> vec(ima.points().npoints());
+ // storing output data
+ oln_piter(I) p(ima.points());
+ for_all(p)
+ vec[loc[ima(p)]++] = p;
+ return vec;
+ }
+
+
+ template <typename I, typename P, typename N>
+ oln_value(I) max_Nplus(const I& ima, const P& p, const N& nbh)
+ {
+ oln_value(I) v = ima(p);
+ oln_niter(N) n(nbh, p);
+ for_all(n)
+ if (ima.has(n) and n < p and ima(n) > v)
+ v = ima(n);
+ return v;
+ }
+
+
+ template <typename I, typename P, typename N>
+ oln_value(I) max_Nminus(const I& ima, const P& p, const N& nbh)
+ {
+ oln_value(I) v = ima(p);
+ oln_niter(N) n(nbh, p);
+ for_all(n)
+ if (ima.has(n) and n > p and ima(n) > v)
+ v = ima(n);
+ return v;
+ }
+
+
+ template <typename I, typename P, typename N>
+ oln_value(I) max_N(const I& ima, const P& p, const N& nbh)
+ {
+ oln_value(I) v = ima(p);
+ oln_niter(N) n(nbh, p);
+ for_all(n)
+ if (ima.has(n) and ima(n) > v)
+ v = ima(n);
+ return v;
+ }
+
+
+ template <typename I, typename N>
+ struct regional_maxima_t
+ {
+ typedef oln_point(I) point;
+ typedef oln_plain_value(I, bool) image_bool;
+ typedef oln_plain_value(I, point) image_point;
+
+ // in:
+ I f;
+ N nbh;
+
+ // out:
+ I o;
+
+ // aux:
+ std::vector<point> S;
+ image_bool is_proc;
+ image_bool attr;
+ image_point parent;
+
+ regional_maxima_t(const I& f, const N& nbh)
+ : f(f), nbh(nbh)
+ {
+ prepare(o, with, f);
+ prepare(parent, with, f);
+ prepare(attr, with, f);
+ prepare(is_proc, with, f);
+
+ // init
+
+ level::fill(inplace(is_proc), false);
+ S = histo_reverse_sort(f);
+
+ // first pass
+
+ for (unsigned i = 0; i < S.size(); ++i)
+ {
+ point p = S[i];
+
+ make_set(p);
+ oln_niter(N) n(nbh, p);
+ for_all(n)
+ if (f.has(n) and is_proc(n))
+ {
+ if (f(n) = f(p))
+ do_union(n, p);
+ else // f(n) > f(p)
+ attr(p) = false;
+ }
+ is_proc(p) = true;
+ }
+
+ // second pass
+
+ for (int i = S.size() - 1; i >= 0; --i)
+ {
+ point p = S[i];
+ if (parent(p) = p)
+ o(p) = attr(p) ? f(p) : 0;
+ else
+ o(p) = o(parent(p));
+ }
+ }
+
+ void make_set(const point& p)
+ {
+ parent(p) = p;
+ attr(p) = true;
+ }
+
+ point find_root(const point& x)
+ {
+ if (parent(x) = x)
+ return x;
+ else
+ return parent(x) = find_root(parent(x));
+ }
+
+ void do_union(const point& n, const point& p)
+ {
+ point r = find_root(n);
+ if (r != p)
+ {
+ parent(r) = p;
+ attr(p) = attr(p) and attr(r);
+ }
+ }
+
+ };
+
+
+ template <typename I, typename N>
+ I
+ regional_maxima(const I& f, const N& nbh)
+ {
+ regional_maxima_t<I, N> run(f, nbh);
+ return run.o;
+ }
+
+
+ } // end of namespace oln::morpho::Rd
+
+ } // end of namespace oln::morpho
+
+} // end of namespace oln
+
+
+#endif // ! OLN_MORPHO_RD_UTILS_HH
Index: oln/level/fill.hh
--- oln/level/fill.hh (revision 977)
+++ oln/level/fill.hh (working copy)
@@ -33,6 +33,7 @@
# include <oln/core/concept/image.hh>
# include <oln/core/concept/point.hh>
+# include <oln/core/concept/iterator.hh>
# include <oln/core/gen/fun.hh>
# include <oln/core/gen/inplace.hh>
Index: oln/io/save_pgm.hh
--- oln/io/save_pgm.hh (revision 0)
+++ oln/io/save_pgm.hh (revision 0)
@@ -0,0 +1,68 @@
+// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 EPITA
+// Research and Development Laboratory
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#ifndef OLN_IO_SAVE_PGM_HH
+# define OLN_IO_SAVE_PGM_HH
+
+# include <iostream>
+# include <fstream>
+
+# include <oln/core/2d/image2d.hh>
+
+
+namespace oln
+{
+
+ namespace io
+ {
+
+ void save_pgm(const image2d<unsigned char>& ima, const std::string& filename)
+ {
+ std::ofstream file(filename.c_str());
+ if (not file)
+ {
+ std::cerr << "error: cannot open file '" << filename
+ << "'!";
+ abort();
+ }
+ file << "P5" << std::endl;
+ file << "# olena" << std::endl;
+ file << ima.ncols() << ' ' << ima.nrows() << std::endl;
+ file << "255" << std::endl;
+ int col = ima.min_col();
+ size_t len = ima.ncols() * sizeof(unsigned char);
+ for (int row = ima.min_row(); row <= ima.max_row(); ++row)
+ file.write((char*)(&(ima.at(row, col))), len);
+ }
+
+ } // end of namespace oln::io
+
+} // end of namespace oln
+
+
+#endif // ! OLN_IO_SAVE_PGM_HH
Index: oln/io/load_pgm.hh
--- oln/io/load_pgm.hh (revision 0)
+++ oln/io/load_pgm.hh (revision 0)
@@ -0,0 +1,169 @@
+// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 EPITA
+// Research and Development Laboratory
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#ifndef OLN_IO_LOAD_PGM_HH
+# define OLN_IO_LOAD_PGM_HH
+
+# include <iostream>
+# include <fstream>
+# include <string>
+
+# include <oln/core/2d/image2d.hh>
+
+
+namespace oln {
+
+ namespace io {
+
+ namespace internal {
+
+ void abort()
+ {
+ std::cerr << " aborting." << std::endl;
+ exit(0);
+ }
+
+ bool read_pnm_header(std::istream& istr,
+ char& type,
+ int& nrows, int& ncols,
+ bool test = false)
+ {
+ // check magic
+ if (istr.get() != 'P' )
+ goto err;
+ type = istr.get();
+ if (type < '1' or type > '6')
+ goto err;
+ if (istr.get() != '\n')
+ goto err;
+
+ // skip comments
+ while (istr.peek() = '#')
+ {
+ std::string line;
+ std::getline(istr, line);
+ }
+
+ // get size
+ istr >> ncols >> nrows;
+ if (nrows <= 0 or ncols <= 0)
+ goto err;
+
+ // skip maxvalue
+ if (istr.get() != '\n')
+ goto err;
+ if (type != '1' and type != '4')
+ {
+ std::string line;
+ std::getline(istr, line);
+ }
+ return true;
+
+ err:
+ if (not test)
+ {
+ std::cerr << "error: badly formed header!";
+ abort();
+ }
+ return false;
+ }
+
+ void read_pnm_header(char ascii, char raw,
+ std::istream& istr,
+ char& type,
+ int& nrows, int& ncols)
+ {
+ read_pnm_header(istr, type, nrows, ncols);
+ if (not (type = ascii or type = raw))
+ {
+ std::cerr << "error: bad pnm type; "
+ << "expected P" << ascii
+ << " or P" << raw
+ << ", get P" << type << "!";
+ abort();
+ }
+ }
+
+
+ /// load_ascii.
+ template <typename I>
+ void load_pgm_ascii(std::ifstream& file, I& ima)
+ {
+ oln_fwd_piter(I) p(ima.points());
+ for_all(p)
+ {
+ unsigned value;
+ file >> value;
+ ima(p) = value;
+ // FIXME: Test alt code below.
+ // file >> ima(p);
+ }
+ }
+
+
+ /// load_raw_2d.
+ template <typename I>
+ void load_pgm_raw_2d(std::ifstream& file, I& ima)
+ {
+ int col = ima.min_col();
+ size_t len = ima.ncols() * sizeof(oln_value(I));
+ for (int row = ima.min_row(); row <= ima.max_row(); ++row)
+ file.read((char*)(&(ima.at(row, col))), len);
+ }
+
+
+ } // end of namespace oln::io::internal
+
+
+ image2d<unsigned char> load_pgm(const std::string& filename)
+ {
+ std::ifstream file(filename.c_str());
+ if (not file)
+ {
+ std::cerr << "error: file '" << filename
+ << "' not found!";
+ abort();
+ }
+ char type;
+ int nrows, ncols;
+ internal::read_pnm_header('2', '5', file, type, nrows, ncols);
+ image2d<unsigned char> ima(nrows, ncols);
+ if (type = '5')
+ internal::load_pgm_raw_2d(file, ima);
+ else
+ if (type = '2')
+ internal::load_pgm_ascii(file, ima);
+ return ima;
+ }
+
+ } // end of namespace oln::io
+
+} // end of namespace oln
+
+
+#endif // ! OLN_IO_LOAD_PGM_HH
1
0
https://svn.lrde.epita.fr/svn/oln/trunk/olena
Suitability to d'ornellas pattern in morphological algorithms
-----------------
P = Parrallel | S = Sequential | Q = Queued
-----------------
erosion/dilatation P S Q
conditionnal erosion/dilation P S Q
distance transform S Q
geodesic distance transform S Q
opening/closing P S Q
center filter S
alternate sequential filtering (ASF) S
area opening/closing Q
opening/closing/ASF by reconstruction S Q
inf/sup -reconstruction S Q
regional minima-maxima S Q
valley/peak removal S Q
minima imposition S Q
hole filling S Q
edge off S Q
opening/closing top-hat S
open/close by reconstruction top-hat S Q
ultimate erosion S Q
morphological skeleton P S Q
sup/inf -generating (hit-miss) P
thinning/thickening P
conditionnal thinning/thickening P
SKIZ (SKeleton by Influence Zone) P
Watersheds Q
Index: ChangeLog
from Ugo Jardonnet <ugo.jardonnet(a)lrde.epita.fr>
Add dOrnellas morphological canvas + Reconstruction.
* oln/morpho/binary_reconstruction_v0.hh: Remove useless code.
* oln/morpho/binary_reconstruction_v2.hh: Impl with canvas reconstruction.
* oln/morpho/cc_tarjan_v1.hh: Minor modification.
* oln/morpho/binary_reconstruction_v1.hh: Draft sequential canvas.
* oln/morpho/cc_tarjan_v3.hh: cc with auxiliary data canvas.
* oln/level/apply_local.hh: whitespaces.
* oln/canvas/reconstruction.hh: Canvas reconstruction.
* oln/canvas/queue_based.hh: dOrnellas canvas.
* oln/canvas/sequential.hh: dOrnellas canvas.
* oln/canvas/parallel.hh: dOrnellas canvas.
* oln/canvas/two_pass_until_stability.hh: Fix.
* oln/canvas/two_pass.hh: Remove useless code.
canvas/parallel.hh | 25 ++++++-
canvas/queue_based.hh | 41 +++++++++---
canvas/reconstruction.hh | 89 ++++++++++++++++++++++++++
canvas/sequential.hh | 96 ++++++++++++++++++++++++++++
canvas/two_pass.hh | 67 ++-----------------
canvas/two_pass_until_stability.hh | 29 +++++---
morpho/binary_reconstruction_v0.hh | 27 --------
morpho/binary_reconstruction_v1.hh | 86 +++++++++++++++----------
morpho/binary_reconstruction_v2.hh | 124 +++++++++++++++++++++++++++++++++++++
morpho/cc_tarjan_v1.hh | 3
morpho/cc_tarjan_v3.hh | 94 +++++++++++++++-------------
11 files changed, 495 insertions(+), 186 deletions(-)
Index: oln/morpho/binary_reconstruction_v0.hh
--- oln/morpho/binary_reconstruction_v0.hh (revision 976)
+++ oln/morpho/binary_reconstruction_v0.hh (working copy)
@@ -55,29 +55,6 @@
template <typename I, typename J>
oln_plain(I)
- binary_reconstruction_loop(const Image_with_Nbh<I>& marker,
- const Binary_Image<J>& mask)
- {
- oln_plain(I) output;
- prepare(output, with, marker);
-
- accumulator::max_<oln_value(I)> max;
-
- // first pass
- oln_fwd_piter(I) p(marker.points());
- for_all(p)
- output(p) = level::local_sup(max, marker, p) and mask(p);
-
- // second pass
- oln_bkd_piter(I) p2(marker.points());
- for_all(p2)
- output(p2) = level::local_inf(max, marker, p2) and mask(p2);
-
- return output;
- }
-
- template <typename I , typename J>
- oln_plain(I)
binary_reconstruction_(const Image_with_Nbh<I>& marker,
const Binary_Image<J>& mask)
{
@@ -108,11 +85,11 @@
} // end of namespace oln::morpho::impl
template <typename I , typename J>
- void
+ oln_plain(I)
binary_reconstruction(Binary_Image<I>& marker,
const Binary_Image<J>& mask)
{
- impl::binary_reconstruction_(marker + c4, mask);
+ return impl::binary_reconstruction_(marker + c4, mask);
}
# endif // ! OLN_INCLUDE_ONLY
Index: oln/morpho/binary_reconstruction_v2.hh
--- oln/morpho/binary_reconstruction_v2.hh (revision 0)
+++ oln/morpho/binary_reconstruction_v2.hh (revision 0)
@@ -0,0 +1,124 @@
+// Copyright (C) 2007 EPITA Research and Development Laboratory
+// Copyright (C) 2007 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#ifndef OLN_MORPHO_BINARY_RECONSTRUCTION_HH
+# define OLN_MORPHO_BINARY_RECONSTRUCTION_HH
+
+# include <oln/core/concept/image.hh>
+# include <oln/accumulator/max.hh>
+# include <oln/level/clone.hh>
+# include <oln/level/fill.hh>
+# include <oln/level/compare.hh>
+# include <oln/level/local_inf.hh>
+# include <oln/level/local_sup.hh>
+# include <oln/core/internal/f_ch_value.hh> // FIXME : could be auto
+ // included ?
+
+# include <oln/canvas/reconstruction.hh>
+
+namespace oln
+{
+
+ namespace morpho
+ {
+
+ template <typename I , typename J>
+ oln_plain(I)
+ binary_reconstruction(const Image_with_Nbh<I>& marker,
+ const Binary_Image<J>& mask);
+
+# ifndef OLN_INCLUDE_ONLY
+
+ namespace impl
+ {
+
+ template <typename I, typename J>
+ struct binary_reconstruction_
+ {
+ typedef I Ima;
+ const I& marker;
+ const J& mask;
+ I output, memo;
+
+ accumulator::max_<oln_value(I)> accu;
+
+ binary_reconstruction_(const Binary_Image<I>& marker,
+ const J& mask)
+ : marker(exact(marker)), mask(mask)
+ {
+ }
+
+ void init()
+ {
+ }
+
+ bool condition_fwd(const oln_point(I) p)
+ {
+ return mask(p);
+ }
+
+ bool condition_bkd(const oln_point(I)& p)
+ {
+ return mask(p);
+ }
+
+ bool is_stable()
+ {
+ return output == memo;
+ }
+
+ void re_loop()
+ {
+ }
+
+ void final()
+ {
+ }
+
+ };
+
+ } // end of namespace oln::morpho::impl
+
+ template <typename I , typename J>
+ oln_plain(I)
+ binary_reconstruction(const Image_with_Nbh<I>& marker,
+ const Binary_Image<J>& mask)
+ {
+ impl::binary_reconstruction_<I,J> run(exact(marker), exact(mask));
+ canvas::reconstruction(run);
+ return run.output;
+ }
+
+# endif // ! OLN_INCLUDE_ONLY
+
+ } // end of namespace oln::morpho
+
+} // end of namespace oln
+
+
+#endif // ! OLN_MORPHO_BINARY_RECONSTRUCTION_HH
Index: oln/morpho/cc_tarjan_v1.hh
--- oln/morpho/cc_tarjan_v1.hh (revision 976)
+++ oln/morpho/cc_tarjan_v1.hh (working copy)
@@ -29,7 +29,6 @@
# define OLN_MORPHO_CC_TARJAN_HH
# include <oln/core/concept/image.hh>
-
# include <oln/canvas/two_pass.hh>
# include <oln/level/fill.hh>
# include <oln/core/internal/f_ch_value.hh>
@@ -143,9 +142,7 @@
cc_tarjan(const Image_with_Nbh<I>& f, unsigned& nlabels)
{
impl::cc_tarjan_<I> run(exact(f));
- std::cout << run.output.is_empty() << std::endl;
canvas::v1::two_pass(run);
- std::cout << run.output.is_empty() << std::endl;
nlabels = run.nlabels;
oln_plain_value(I, unsigned) tmp = run.output;
return tmp;
Index: oln/morpho/binary_reconstruction_v1.hh
--- oln/morpho/binary_reconstruction_v1.hh (revision 976)
+++ oln/morpho/binary_reconstruction_v1.hh (working copy)
@@ -1,4 +1,5 @@
// Copyright (C) 2007 EPITA Research and Development Laboratory
+// Copyright (C) 2007 EPITA Research and Development Laboratory
//
// This file is part of the Olena Library. This library is free
// software; you can redistribute it and/or modify it under the terms
@@ -32,8 +33,12 @@
# include <oln/accumulator/max.hh>
# include <oln/level/clone.hh>
# include <oln/level/fill.hh>
+# include <oln/level/compare.hh>
# include <oln/level/local_inf.hh>
# include <oln/level/local_sup.hh>
+# include <oln/core/internal/f_ch_value.hh> // FIXME : could be auto
+ // included ?
+
namespace oln
{
@@ -52,61 +57,72 @@
{
template <typename I>
- bool
- stability(const Image_with_Nbh<I>& marker,
- oln_plain(I)& tmp)
- {
- oln_piter(I) p(marker.points());
- for_all(p)
- if (marker(p) != tmp(p))
- return false;
- return true;
- }
+ struct binary_reconstruction_
+ {
+ accumulator::max_<oln_value(I)> accu;
- template <typename I, typename J>
- oln_plain(I)
- binary_reconstruction_loop(const Image_with_Nbh<I>& marker,
- const Binary_Image<J>& mask)
+ oln_plain(I) output, memo;
+ const I& f;
+
+ binary_reconstruction_(const I& f)
+ : f(f)
{
- oln_plain(I) output;
- prepare(output, with, marker);
+ }
- accumulator::max_<oln_value(I)> max;
+ void init()
+ {
+ prepare(output, with, f);
+ output = level::clone(marker);
+ }
- // first pass
- oln_fwd_piter(I) p(marker.points());
- for_all(p)
- output(p) = level::local_sup(max, marker, p) and mask(p);
+ void forward_scan(const oln_point(I)& p,
+ const oln_point(I)& n)
+ {
+ accu(fun.f(n));
+ }
- // second pass
- oln_bkd_piter(I) p2(marker.points());
- for_all(p2)
- output(p2) = level::local_inf(max, marker, p2) and mask(p2);
+ void backward_scan(const oln_point(I)& p,
+ const oln_point(I)& n)
+ {
+ accu(fun.f(n));
+ }
- return output;
}
template <typename I , typename J>
- void // FIXME : Slow impl.
+ oln_plain(I)
binary_reconstruction_(const Image_with_Nbh<I>& marker,
const Binary_Image<J>& mask)
{
- oln_plain(I) tmp = level::clone(marker);
+ accumulator::max_<oln_value(I)> max;
+ oln_plain(I)
+ output = level::clone(marker),
+ memo;
- while ( not stability(marker, tmp) )
+ do
{
- level::fill(inplace(exact(marker).image()), tmp);
- tmp = binary_reconstruction_loop(marker, mask);
- }
+ memo = level::clone(output);
+
+ // first pass
+ oln_fwd_piter(I) p1(marker.points());
+ for_all(p1)
+ output(p1) = level::local_sup(max, output, p1) and mask(p1);
- level::fill(inplace(exact(marker).image()), tmp);
+ // second pass
+ oln_bkd_piter(I) p2(marker.points());
+ for_all(p2)
+ output(p2) = level::local_inf(max, output, p2) and mask(p2);
+
+ } while (output != memo);
+
+ return output;
}
} // end of namespace oln::morpho::impl
template <typename I , typename J>
- void
- binary_reconstruction(Binary_Image<I>& marker,
+ oln_plain(I)
+ binary_reconstruction(const Binary_Image<I>& marker,
const Binary_Image<J>& mask)
{
impl::binary_reconstruction_(marker + c4, mask);
Index: oln/morpho/cc_tarjan_v3.hh
--- oln/morpho/cc_tarjan_v3.hh (revision 976)
+++ oln/morpho/cc_tarjan_v3.hh (working copy)
@@ -29,9 +29,9 @@
# define OLN_MORPHO_CC_TARJAN_HH
# include <oln/core/concept/image.hh>
-
# include <oln/canvas/two_pass.hh>
# include <oln/level/fill.hh>
+# include <oln/core/internal/f_ch_value.hh>
namespace oln
{
@@ -47,78 +47,87 @@
namespace impl
{
- template <typename I>
- struct cc_tarjan_
+
+ template <typename T>
+ struct data_
{
- const I& input;
- oln_plain_value(I, unsigned) output;
+ typedef T I;
+ const I& f;
+ oln_plain_value(I, unsigned) output;
oln_plain(I) is_processed;
oln_plain_value(I, oln_point(I)) parent;
- cc_tarjan_(const I& in)
- : input(in)
+ data_(const I& f)
+ : f(f)
+ {
+ }
+ };
+
+ template <typename Data>
+ struct cc_tarjan_
+ {
+ cc_tarjan_()
{
- prepare(is_processed, with, in);
- prepare(output, with, in);
- prepare(parent, with, in);
}
- oln_point(I)
- find_root(const I& ima,
- const oln_point(I)& x,
- oln_plain_value(I, oln_point(I))& parent)
+ oln_point(Data::I)
+ find_root(Data& data,
+ const oln_point(Data::I)& x)
{
- if (parent(x) != x)
+ if (data.parent(x) != x)
{
- parent(x) = find_root(ima, parent(x), parent);
- return parent(x);
+ data.parent(x) = find_root(data, data.parent(x));
+ return data.parent(x);
}
return x;
}
void
- do_union(const I& ima,
- const oln_point(I)& n,
- const oln_point(I)& p,
- oln_plain_value(I, oln_point(I))& parent)
+ do_union(Data& data,
+ const oln_point(Data::I)& n,
+ const oln_point(Data::I)& p)
{
- oln_point(I) r = find_root(ima, n, parent);
+ oln_point(Data::I) r = find_root(data, n);
if (r != p)
- parent(r) = p;
+ data.parent(r) = p;
}
- void init()
+ void init(Data& data)
{
- level::fill(inplace(is_processed), false);
+ prepare(data.is_processed, with, data.f);
+ prepare(data.output, with, data.f);
+ prepare(data.parent, with, data.f);
+ level::fill(inplace(data.is_processed), false);
}
- void first_pass_body(const oln_point(I)& p)
+ void first_pass_body(const oln_point(Data::I)& p,
+ Data& data)
{
- parent(p) = p;
- if ( input(p) )
+ data.parent(p) = p;
+ if ( data.f(p) )
{
- oln_niter(I) n(input, p);
+ oln_niter(Data::I) n(data.f, p);
for_all(n)
{
- if ( input(n) == true and is_processed(n) )
- do_union(input, n, p, parent);
+ if ( data.f(n) == true and data.is_processed(n) )
+ do_union(data, n, p);
}
- is_processed(p) = true;
+ data.is_processed(p) = true;
}
-
}
- void second_pass_body(const oln_point(I)& p)
+ void second_pass_body(const oln_point(Data::I)& p,
+ Data& data)
{
unsigned current_label = 0;
- if ( input(p) == true and parent(p) == p )
- output(p) = ++current_label;
+ if ( data.f(p) == true and data.parent(p) == p )
+ data.output(p) = ++current_label;
else
- output(p) = output(parent(p));
+ data.output(p) = data.output(data.parent(p));
}
- void final()
+ void final(Data&)
{
}
@@ -132,9 +141,12 @@
oln_plain_value(I, unsigned)
cc_tarjan(const Image_with_Nbh<I>& input)
{
- impl::cc_tarjan_<I> f(exact(input));
- canvas::v1::two_pass(f);
- return f.output;
+ typedef impl::data_<I> data_t;
+
+ data_t data(exact(input));
+ impl::cc_tarjan_< impl::data_<I> > f;
+ canvas::v3::two_pass(f, data);
+ return data.output;
}
# endif // ! OLN_INCLUDE_ONLY
Index: oln/level/apply_local.hh
Index: oln/canvas/reconstruction.hh
--- oln/canvas/reconstruction.hh (revision 0)
+++ oln/canvas/reconstruction.hh (revision 0)
@@ -0,0 +1,89 @@
+// Copyright (C) 2007 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have receiv 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 OLN_CANVAS_RECONSTRUCTION_HH
+# define OLN_CANVAS_RECONSTRUCTION_HH
+
+# include <oln/level/clone.hh>
+# include <oln/level/local_sup.hh>
+# include <oln/level/local_inf.hh>
+
+// FIXME : similar to two_pass_until_stability
+
+namespace oln
+{
+
+ namespace canvas
+ {
+
+ template <typename F>
+ void reconstruction(F& fun)
+ {
+ typedef typename F::Ima I;
+
+ bool stability;
+ fun.output = level::clone(fun.marker);
+
+ fun.init();
+
+ do
+ {
+ fun.memo = level::clone(fun.output);
+
+ // Forward Scan
+ oln_fwd_piter(I) p1(fun.marker.points());
+ for_all(p1)
+ {
+ if ( fun.condition_fwd(p1) )
+ fun.output(p1) = level::local_sup(fun.accu, fun.output, p1);
+ }
+
+ // Backward Scan
+ oln_bkd_piter(I) p2(fun.marker.points());
+ for_all(p2)
+ {
+ if ( fun.condition_bkd(p2) )
+ fun.output(p2) = level::local_sup(fun.accu, fun.output, p2);
+ }
+
+ // stability check
+ stability = fun.is_stable();
+ if (stability)
+ break;
+
+ // prepare a new loop iteration
+ fun.re_loop();
+ } while (true);
+
+ fun.final();
+ }
+
+ } // end of namespace canva
+
+} // end of namespace oln
+
+#endif // ! OLN_CANVAS_RECONSTRUCTION_HH
Index: oln/canvas/queue_based.hh
--- oln/canvas/queue_based.hh (revision 976)
+++ oln/canvas/queue_based.hh (working copy)
@@ -28,27 +28,48 @@
#ifndef OLN_CANVAS_QUEUE_BASED_HH
# define OLN_CANVAS_QUEUE_BASED_HH
+namespace oln
+{
+
namespace canvas
{
- template <typename F, typename I>
- void queue_based(F f, I input)
+ template <template <class> class F,
+ typename I, typename Queue>
+ void queue_based(F<I>& fun)
{
- queue q;
+ Queue q;
- f.init(input);
+ fun.init();
- oln_piter(I) p1(input.points());
+ // initialization
+ oln_piter(I) p1(fun.f.points());
for_all(p1)
- f.enqueue(p1, q, input);
+ if ( fun.condition1() ) // FIXME : part of the canvas or not ?
+ q.enqueue(p1);
- while ( !q.empty() ) do
+ // Data-driven Propagation
+ oln_piter(I) p;
+ while ( !q.empty() )
+ {
+ p = q.deq();
+ oln_niter(I) n(fun.f, p);
+ for_all(n)
+ {
+ if ( fun.condition2(p, n) )
{
- oln_piter(I) p = q.deq();
- f.loop(p, input);
+ fun.process(p, n);
+ // region settings
+ q.enqueue(n);
+ }
+ }
}
- f.final(input);
+ fun.final();
}
+ } // end of namespace canvas
+
+} // end of namespace oln
+
#endif // ! OLN_CANVAS_QUEUE_BASED_HH
Index: oln/canvas/sequential.hh
--- oln/canvas/sequential.hh (revision 0)
+++ oln/canvas/sequential.hh (revision 0)
@@ -0,0 +1,96 @@
+// Copyright (C) 2007 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have receiv 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 OLN_CANVAS_SEQUENTIAL_HH
+# define OLN_CANVAS_SEQUENTIAL_HH
+
+// FIXME : similar to two_pass_until_stability
+
+namespace oln
+{
+
+ namespace canvas
+ {
+
+ template <template <class> class F,
+ typename I>
+ void sequential(F<I>& fun)
+ {
+ bool stability;
+
+ fun.init();
+
+ for (;;)
+ {
+
+ // Forward Scan
+ oln_fwd_piter(I) p1(fun.f.points());
+ oln_niter(I) n1(fun.f, p1);
+ for_all(p1)
+ {
+ fun.accu.init_with( fun.f(p1) );
+ for_all(n1)
+ {
+ if (n1 < p1)
+ fun.forward_scan(p1, n1);
+ }
+ fun.output(p1) = fun.accu.value();
+ //fun.accu.reload(); // FIXME : need reload
+ }
+
+ // Backward Scan
+ oln_bkd_piter(I) p2(fun.f.points());
+ oln_niter(I) n2(fun.f, p2);
+ for_all(p2)
+ {
+ fun.accu.init_with(fun.f(p2));
+ for_all(n2)
+ {
+ if (n2 >= p2)
+ fun.backward_scan(p2, n2);
+ }
+ fun.output(p2) = fun.accu.value();
+ //fun.accu.reload();
+ }
+
+ // stability check
+ stability = fun.is_stable();
+ if (stability)
+ break;
+
+ // prepare a new loop iteration
+ fun.re_loop();
+ }
+
+ fun.final();
+ }
+
+ } // end of namespace canva
+
+} // end of namespace oln
+
+#endif // ! OLN_CANVAS_SEQUENTIAL_HH
Index: oln/canvas/parallel.hh
--- oln/canvas/parallel.hh (revision 976)
+++ oln/canvas/parallel.hh (working copy)
@@ -28,15 +28,36 @@
#ifndef OLN_CANVAS_PARALLEL_HH
# define OLN_CANVAS_PARALLEL_HH
+// FIXME : ~~same code as apply_local
+
+namespace oln
+{
+
namespace canvas
{
- template <typename F, typename I>
- void parallel(F f, I input)
+ template <template <class> class F,
+ typename I>
+ void parallel(F<I>& fun)
{
+ fun.init();
+ oln_piter(I) p(fun.f.points());
+ oln_niter(I) n(fun.f, p);
+ for_all(p)
+ {
+ for_all(n)
+ {
+ fun.process(p, n);
}
+ }
+
+ fun.final();
}
+ } // end of namespace canvas
+
+} // end of namespace oln
+
#endif // ! OLN_CANVAS_PARALLEL_HH
Index: oln/canvas/two_pass_until_stability.hh
--- oln/canvas/two_pass_until_stability.hh (revision 976)
+++ oln/canvas/two_pass_until_stability.hh (working copy)
@@ -28,42 +28,47 @@
#ifndef OLN_CANVAS_TWO_PASS_UNTIL_STABILITY_HH
# define OLN_CANVAS_TWO_PASS_UNTIL_STABILITY_HH
+namespace oln
+{
+
namespace canvas
{
- template <typename F, typename I>
- void two_pass_until_stability(F f, I input)
+ template <template <class> class F,
+ typename I>
+ void two_pass_until_stability(F<I>& fun)
{
bool stability;
- f.init(input);
+ fun.init();
for (;;)
{
// first pass
- oln_fwd_piter(I) p1(input.points());
+ oln_fwd_piter(I) p1(fun.f.points());
for_all(p1)
- f.first_pass_body(p1, input);
+ fun.first_pass_body(p1);
// second pass
- oln_bkd_piter(I) p2(input.points());
+ oln_bkd_piter(I) p2(fun.f.points());
for_all(p2)
- f.second_pass_body(p2, input);
+ fun.second_pass_body(p2);
// stability check
- stability = f.is_stable(input); // Oblige de posseder output.
+ stability = fun.is_stable(); // Oblige de posseder output.
if (stability)
- return;
+ break;
// prepare a new loop iteration
- f.re_loop(input);
+ fun.re_loop(input);
}
- f.final(input);
+ fun.final(input);
}
+ } // end of namespace canvas
-}
+} // end of namespace oln
#endif // ! OLN_CANVAS_TWO_PASS_UNTIL_STABILITY_HH
Index: oln/canvas/two_pass.hh
--- oln/canvas/two_pass.hh (revision 976)
+++ oln/canvas/two_pass.hh (working copy)
@@ -86,24 +86,24 @@
namespace v3 // Auxiliar data given as argument.
{
- template <typename F, typename I, typename A>
- void two_pass(F& fun, I& f, A& aux)
+ template <typename F, typename D>
+ void two_pass(F& fun, D& data)
{
- mlc::assert_< mlc_is_a(I, Image) >::check();
+ mlc::assert_< mlc_is_a(typename D::I, Image) >::check();
- f.init(f, aux);
+ fun.init(data);
// first pass
- oln_bkd_piter(I) p1(f.points());
+ oln_bkd_piter(D::I) p1(data.f.points());
for_all(p1)
- f.first_pass_body(p1, f, aux);
+ fun.first_pass_body(p1, data);
// second pass
- oln_fwd_piter(I) p2(f.points());
+ oln_fwd_piter(D::I) p2(data.f.points());
for_all(p2)
- f.second_pass_body(p2, f, aux);
+ fun.second_pass_body(p2, data);
- f.final(f, aux);
+ fun.final(data);
}
}
@@ -166,55 +166,6 @@
};
}
-
- namespace v5
- {
- template<typename I, typename Exact>
- struct two_pass
- {
- const I& f;
-
- void init()
- {
- assert(0 && "'void init()' not implemented.");
- }
-
- void final()
- {
- assert(0 && "'void final()' not implemented.");
- }
-
- void first_pass_body(const oln_point(I)&)
- {
- assert(0 && "'void first_pass_body(const oln_point(I)& p)' not implemented.");
- }
-
- void second_pass_body(const oln_point(I)&)
- {
- assert(0 && "'void second_pass_body(const oln_point(I)& p)' not implemented.");
- }
-
- void run()
- {
- init();
-
- // first pass
- oln_bkd_piter(I) p1(f.points());
- for_all(p1)
- first_pass_body(p1);
-
- // second pass
- oln_fwd_piter(I) p2(f.points());
- for_all(p2)
- second_pass_body(p2);
-
- typename Exact::final();
- }
-
- };
-
- } // end of namespace v5
-
} // end of namespace morpho
} // end of namespace oln
1
0
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
URL: https://svn.lrde.epita.fr/svn/oln/trunk/static
ChangeLog:
2007-05-11 Thomas Moulard <thomas.moulard(a)lrde.epita.fr>
Add auto implementation and fix morphers.
* samples/mini-std/cpp2/mini-std.cc: Here.
mini-std.cc | 298 +++++++++++++++++++++++++++++++++++++++++++-----------------
1 file changed, 215 insertions(+), 83 deletions(-)
Index: trunk/static/samples/mini-std/cpp2/mini-std.cc
===================================================================
- --- trunk/static/samples/mini-std/cpp2/mini-std.cc (revision 975)
+++ trunk/static/samples/mini-std/cpp2/mini-std.cc (revision 976)
@@ -55,17 +55,14 @@
# include <stc/scoop.hxx>
} // End of namespace mstd
- -
- -#define mstd_internal_select_class(T, CLASS) \
- -mlc::bexpr_ < sizeof(internal::CLASS##_select(internal::makePtr< T >())) == sizeof(internal::yes_) >
- -
- -#define mstd_internal_select_mechanism(CLASS) \
- -template <class E> \
- -yes_ CLASS##_select(const CLASS<E>* arg); \
- -template <class T> \
- -no_ CLASS##_select(const T* arg); \
- -no_ CLASS##_select(...)
- -
+// FIXME
+struct transform : public std::unary_function<int&, int>
+{
+ result_type operator() (argument_type i)
+ {
+ return i + 1;
+ }
+};
namespace mstd
@@ -102,8 +99,76 @@
mlc_decl_typedef(container_t);
mlc_decl_typedef(stdcontainer_t);
+
+ mlc_decl_typedef(primitiveIterator_t);
} // End of namespace mstd.
+/*----------------------------.
+| Automatic implementations. |
+`----------------------------*/
+
+namespace mstd
+{
+ namespace behavior { struct identity; }
+
+ // Forward declarations.
+ template <typename Exact>
+ struct Container;
+
+ template <typename Exact>
+ struct ForwardContainer;
+
+ template <typename Exact>
+ struct BiDirContainer;
+
+ template <typename Exact>
+ struct Iterator;
+
+ namespace automatic
+ {
+ template <typename Exact>
+ struct set_impl< Container, behavior::identity, Exact > : public virtual Any<Exact>
+ {
+ stc_typename(value_t);
+
+ value_t impl_size() const
+ {
+ return exact(this)->get_deleg().impl_size();
+ }
+
+ bool impl_empty() const
+ {
+ return exact(this)->get_deleg().impl_empty();
+ }
+
+ void impl_clear()
+ {
+ exact(this)->get_deleg().impl_clear();
+ }
+ };
+
+ template <typename Exact>
+ struct set_impl< ForwardContainer, behavior::identity, Exact > : public virtual Any<Exact>
+ {
+ stc_typename(iter_t);
+ };
+
+ template <typename Exact>
+ struct set_impl< BiDirContainer, behavior::identity, Exact > : public virtual Any<Exact>
+ {
+ stc_typename(iter_t);
+ };
+
+ template <typename Exact>
+ struct set_impl< Iterator, behavior::identity, Exact > : public virtual Any<Exact>
+ {
+ bool impl_op_nequal(const Exact& it)
+ {
+ return exact(this)->get_deleg().impl_op_nequal(it.get_deleg());
+ }
+ };
+ }
+};
/*---------------.
| Abstractions. |
@@ -116,17 +181,19 @@
// ---------- //
template <typename Exact>
- - struct Iterator : virtual public Any<Exact>
+ struct Iterator : virtual public Any<Exact>,
+ virtual public automatic::set_impl< Iterator, behavior::identity, Exact >
{
typedef Iterator<Exact> current;
stc_typename(container_t);
stc_typename(iter_t);
stc_typename(value_t);
+ stc_typename(primitiveIterator_t);
- - value_t& operator*()
+ value_t operator*()
{
- - exact(this)->impl_op_star();
+ return exact(this)->impl_op_star();
}
bool operator ==(const Exact& it)
@@ -146,7 +213,8 @@
template <typename Exact>
struct Container : virtual public Any<Exact>,
- - virtual public automatic::get_impl<Container, Exact>
+ virtual public automatic::set_impl< Container, behavior::identity, Exact >
+ //automatic::get_impl<Container, Exact>
{
stc_typename(value_t);
stc_typename(size_t);
@@ -208,7 +276,8 @@
// ------------------ //
template <typename Exact>
- - struct ForwardContainer : public virtual Container<Exact>
+ struct ForwardContainer : public virtual Container<Exact>,
+ public virtual automatic::set_impl<ForwardContainer, behavior::identity, Exact>
{
typedef Container<Exact> super;
stc_typename(iter_t);
@@ -224,7 +293,8 @@
// ---------------- //
template <typename Exact>
- - struct BiDirContainer : public virtual ForwardContainer<Exact>
+ struct BiDirContainer : public virtual ForwardContainer<Exact>,
+ public virtual automatic::set_impl<BiDirContainer, behavior::identity, Exact>
{
typedef ForwardContainer<Exact> super;
stc_using(iter_t);
@@ -349,16 +419,6 @@
template <typename T>
struct associativeIterator;
- - // Bridge equipment
- - namespace internal
- - {
- - mstd_internal_select_mechanism(forwardIterator);
- - mstd_internal_select_mechanism(backwardIterator);
- - mstd_internal_select_mechanism(biDirIterator);
- - mstd_internal_select_mechanism(randomAccessibleIterator);
- - mstd_internal_select_mechanism(associativeIterator);
- - } // End of namespace interal
- -
// Tag.
struct switch_is_sorted;
@@ -408,28 +468,28 @@
template <typename Exact>
struct case_<switch_is_frontinsertion, Exact, 1> :
- - public mlc::where_ < mstd_internal_select_class(stc_find_type(Exact, iter_t), forwardIterator) >
+ public mlc::where_ < mlc_is_a(stc_find_type(Exact, iter_t), forwardIterator) >
{
typedef FrontInsertionContainer<Exact> ret;
};
template <typename Exact>
struct case_<switch_is_frontinsertion, Exact, 2> :
- - public mlc::where_ < mstd_internal_select_class(stc_find_type(Exact, iter_t), backwardIterator) >
+ public mlc::where_ < mlc_is_a(stc_find_type(Exact, iter_t), backwardIterator) >
{
typedef FrontInsertionContainer<Exact> ret;
};
template <typename Exact>
struct case_<switch_is_frontinsertion, Exact, 3> :
- - public mlc::where_ < mstd_internal_select_class(stc_find_type(Exact, iter_t), biDirIterator) >
+ public mlc::where_ < mlc_is_a(stc_find_type(Exact, iter_t), biDirIterator) >
{
typedef FrontInsertionContainer<Exact> ret;
};
template <typename Exact>
struct case_<switch_is_frontinsertion, Exact, 4> :
- - public mlc::where_ < mstd_internal_select_class(stc_find_type(Exact, iter_t), randomAccessibleIterator) >
+ public mlc::where_ < mlc_is_a(stc_find_type(Exact, iter_t), randomAccessibleIterator) >
{
typedef FrontInsertionContainer<Exact> ret;
};
@@ -445,21 +505,21 @@
template <typename Exact>
struct case_<switch_is_backinsertion, Exact, 1> :
- - public mlc::where_ < mstd_internal_select_class(stc_find_type(Exact, iter_t), backwardIterator) >
+ public mlc::where_ < mlc_is_a(stc_find_type(Exact, iter_t), backwardIterator) >
{
typedef BackInsertionContainer<Exact> ret;
};
template <typename Exact>
struct case_<switch_is_backinsertion, Exact, 2> :
- - public mlc::where_ < mstd_internal_select_class(stc_find_type(Exact, iter_t), biDirIterator) >
+ public mlc::where_ < mlc_is_a(stc_find_type(Exact, iter_t), biDirIterator) >
{
typedef BackInsertionContainer<Exact> ret;
};
template <typename Exact>
struct case_<switch_is_backinsertion, Exact, 3> :
- - public mlc::where_ < mstd_internal_select_class(stc_find_type(Exact, iter_t), randomAccessibleIterator) >
+ public mlc::where_ < mlc_is_a(stc_find_type(Exact, iter_t), randomAccessibleIterator) >
{
typedef BackInsertionContainer<Exact> ret;
};
@@ -475,35 +535,35 @@
template <typename Exact>
struct case_<switch_iterator_kind, Exact, 1> :
- - public mlc::where_ < mstd_internal_select_class(stc_find_type(Exact, iter_t), forwardIterator) >
+ public mlc::where_ < mlc_is_a(stc_find_type(Exact, iter_t), forwardIterator) >
{
typedef ForwardContainer<Exact> ret;
};
template <typename Exact>
struct case_<switch_iterator_kind, Exact, 2> :
- - public mlc::where_ < mstd_internal_select_class(stc_find_type(Exact, iter_t), backwardIterator) >
+ public mlc::where_ < mlc_is_a(stc_find_type(Exact, iter_t), backwardIterator) >
{
typedef BiDirContainer<Exact> ret;
};
template <typename Exact>
struct case_<switch_iterator_kind, Exact, 3> :
- - public mlc::where_ < mstd_internal_select_class(stc_find_type(Exact, iter_t), biDirIterator) >
+ public mlc::where_ < mlc_is_a(stc_find_type(Exact, iter_t)::primitiveIterator_t, biDirIterator) > // ::primitiveIterator_t
{
typedef BiDirContainer<Exact> ret;
};
template <typename Exact>
struct case_<switch_iterator_kind, Exact, 4> :
- - public mlc::where_ < mstd_internal_select_class(stc_find_type(Exact, iter_t), randomAccessibleIterator) >
+ public mlc::where_ < mlc_is_a(stc_find_type(Exact, iter_t), randomAccessibleIterator) >
{
typedef RandomAccessibleContainer<Exact> ret;
};
template <typename Exact>
struct case_<switch_iterator_kind, Exact, 5> :
- - public mlc::where_ < mstd_internal_select_class(stc_find_type(Exact, iter_t), associativeIterator) >
+ public mlc::where_ < mlc_is_a(stc_find_type(Exact, iter_t), associativeIterator) >
{
typedef AssociativeContainer<Exact> ret;
};
@@ -622,6 +682,7 @@
typedef stc_type(container_t, value_t) value_t;
typedef stc_type(container_t, stdcontainer_t)::iterator iter_t;
+ typedef forwardIterator<T> primitiveIterator_t;
};
template <typename T>
@@ -704,6 +765,7 @@
typedef stc_type(container_t, value_t) value_t;
typedef stc_type(container_t, stdcontainer_t)::iterator iter_t;
+ typedef biDirIterator<T> primitiveIterator_t;
};
template <typename T>
@@ -799,6 +861,7 @@
typedef stc_type(container_t, value_t) value_t;
typedef stc_type(container_t, stdcontainer_t)::iterator iter_t;
+ typedef randomAccessibleIterator<T> primitiveIterator_t;
};
template <typename T>
@@ -933,7 +996,7 @@
return list_.back();
}
- - private:
+ protected:
stdcontainer_t list_;
};
@@ -964,48 +1027,78 @@
stc_typename(delegatee);
protected:
- - iterator_morpher_();
+ iterator_morpher_()
+ {
+ }
};
- - template <typename Iterator>
+ template <typename Iterator, typename Functor>
struct transform_morpher_iterator;
- - template <typename Iterator>
- - struct super_trait_<transform_morpher_iterator<Iterator> >
+ template <typename Iterator, typename Functor>
+ struct super_trait_<transform_morpher_iterator<Iterator, Functor> >
{
- - typedef iterator_morpher_<transform_morpher_iterator<Iterator> > ret;
+ typedef iterator_morpher_<transform_morpher_iterator<Iterator, Functor> > ret;
};
- - template <typename Iterator>
- - struct vtypes<transform_morpher_iterator<Iterator> >
+ template <typename Iterator, typename Functor>
+ struct vtypes<transform_morpher_iterator<Iterator, Functor> >
{
typedef Iterator delegatee;
};
- - template <typename Iterator>
- - struct transform_morpher_iterator : public iterator_morpher_<transform_morpher_iterator<Iterator> >
+ template <typename Iterator, typename Functor>
+ struct transform_morpher_iterator : public iterator_morpher_<transform_morpher_iterator<Iterator, Functor> >
{
- - typedef iterator_morpher_<transform_morpher_iterator<Iterator> > super;
+ typedef transform_morpher_iterator<Iterator, Functor> current;
+ typedef iterator_morpher_<current> super;
stc_using(delegatee);
stc_using(value_t);
+ stc_using(primitiveIterator_t);
- - typedef std::unary_function<value_t&,value_t> transform_t;
- -
- - transform_morpher_iterator(delegatee& deleg, transform_t& trans) :
+ transform_morpher_iterator(delegatee deleg, Functor trans) :
deleg_ (deleg),
trans_ (trans)
{
}
- - value_t& impl_op_star()
+ value_t impl_op_star()
{
- - return (*trans_)(*(deleg_.iter_));
+ typedef std::unary_function<value_t&,value_t> transform_t;
+ mlc::assert_< mlc_is_a(Functor, transform_t) >::check();
+ value_t val = *deleg_;
+ return trans_(val);
}
- - private:
+ delegatee& get_deleg()
+ {
+ return deleg_;
+ }
+
+ delegatee& get_deleg() const
+ {
+ return deleg_;
+ }
+
+
+ //FIXME
+ current& operator++()
+ {
+ deleg_++;
+ return *exact(this);
+ }
+
+ //FIXME
+ current operator++(int)
+ {
+ current ret = *exact(this);
+ ++deleg_;
+ return ret;
+ }
+ protected:
delegatee& deleg_;
- - transform_t& trans_;
+ Functor trans_;
};
@@ -1024,6 +1117,7 @@
template <typename Exact>
struct vtypes<container_morpher_<Exact> >
{
+ typedef behavior::identity behavior;
};
template <typename Exact>
@@ -1032,48 +1126,73 @@
stc_typename(delegatee);
protected:
- - container_morpher_();
+ container_morpher_()
+ {
+ }
};
// transform_morpher
- - template <typename Container>
+ template <typename Container, typename Functor>
struct transform_morpher;
- - template <typename Container>
- - struct super_trait_<transform_morpher<Container> >
+ template <typename Container, typename Functor>
+ struct super_trait_<transform_morpher<Container, Functor> >
{
typedef container_morpher_<Container> ret;
};
- - template <typename Container>
- - struct vtypes<transform_morpher<Container> >
+ template <typename Container, typename Functor>
+ struct vtypes<transform_morpher<Container, Functor> >
{
typedef Container delegatee;
- - typedef transform_morpher_iterator<typename Container::iter_t> iter_t;
+ typedef transform_morpher_iterator<typename Container::iter_t, Functor> iter_t;
};
- - template <typename Container>
- - struct transform_morpher : public container_morpher_<transform_morpher<Container> >
+ template <typename Container, typename Functor>
+ struct transform_morpher : public container_morpher_<transform_morpher<Container, Functor> >
{
- - typedef transform_morpher<Container> current;
- - typedef container_morpher_<Container> super;
+ typedef transform_morpher<Container, Functor> current;
+ typedef container_morpher_<current> super;
stc_using(delegatee);
stc_using(value_t);
+ stc_using(iter_t);
- - typedef std::unary_function<value_t&,value_t> transform_t;
+ //typedef std::unary_function<value_t&,value_t> transform_t;
- - transform_morpher(delegatee& d, transform_t& trans) :
+ transform_morpher(delegatee& d, Functor trans) :
container_morpher_<current>(),
deleg_ (d),
trans_ (trans)
{
}
+ delegatee& get_deleg()
+ {
+ return deleg_;
+ }
+
+ delegatee& get_deleg() const
+ {
+ return deleg_;
+ }
+
+ iter_t impl_begin()
+ {
+ return iter_t(deleg_.begin(), trans_);
+ }
+
+ iter_t impl_end()
+ {
+ // iter_t it(deleg_.end(), trans_);
+ // it.get_deleg().to_end();
+ return iter_t(deleg_.end(), trans_);
+ }
+
protected:
delegatee& deleg_;
- - transform_t& trans_;
+ Functor trans_;
};
} // End of namespace mstd.
@@ -1105,14 +1224,6 @@
{
}
- -class transform : public std::unary_function<int&, int>
- -{
- - int operator() (int& i)
- - {
- - return i + 1;
- - }
- -};
- -
int main()
{
// List
@@ -1178,15 +1289,36 @@
for (mstd::list<int>::iter_t it = l.begin(); it != l.end(); ++it)
TEST(*it);
- - // Functions
+ // Fonctions
test(l);
// Dummy<int> a;
// test(a);
// Morphers
- - transform t;
- - mstd::transform_morpher<mstd::list<int> > tm(l, t);
+ typedef mstd::transform_morpher<mstd::list<int>, transform > morpher_t;
+ morpher_t tm(l, transform());
- - // mstd::transform_morpher_iterator< mstd::list<int>::iter_t > im(l, t);
+ typedef mstd::transform_morpher_iterator<mstd::list<int>::iter_t, transform> itmorpher_t;
+ mlc::assert_< mlc_is_a_(itmorpher_t, mstd::Iterator) >::check();
+
+ typedef mstd::transform_morpher_iterator<mstd::list<int>::iter_t, transform> realiter_t;
+ mlc::assert_< mlc_eq(morpher_t::iter_t, realiter_t) >::check();
+
+ std::cout << "= Morpher" << std::endl;
+ for (morpher_t::iter_t im = tm.begin(); im != tm.end(); ++im)
+ TEST(*im);
+ std::cout << "= Morpher fin" << std::endl;
+
+ morpher_t::iter_t im = tm.begin();
+ TEST(*im);
+
+ {
+ mstd::list<int>::iter_t it = l.begin();
+ mstd::transform_morpher_iterator<mstd::list<int>::iter_t, transform> im(it, transform());
+ TEST(*it);
+ TEST(*im);
+ }
+ tm.clear();
+ TEST(tm.size());
}
- --
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (GNU/Linux)
iD8DBQFGRHWg8QvmnUS5oeMRAiX4AJ9ZpBJ82Tq8yWUf6XWK5IAvqztbXgCfRRpy
hLl7NPAbQRnMmMEiuB7gSQI=
=yFpN
-----END PGP SIGNATURE-----
1
0
https://svn.lrde.epita.fr/svn/oln/trunk/olena
criteres ?
- contrat sur les attributs.
- implementation par defaut.
- fragmentation du code / lisibilite.
- temps d'execution.
- temps de compilation.
- simplicite.
- coherance.
- clarte des messages d'erreurs.
v0: procedure
-ecriture difficile et longue
-pas forcement plus rapide qu'avec un canevas
v1: donnees tenues
+performant
+tres lisible
-function obligatoirement parametree
v2: donnees tenues sauf image
-moins coherent que v1
+la function peut ne pas etre parametree
v3: donnee passe en argument dans une classe.
-peu elegant
-lent ?
...
v4: heritage
+performant
+principe naturelle en poo
+function peut etre tres specifique (pas de parametre)
-fragmentation du code si classe de factorisation
-lisibilite bof (code perdu parmis les appelles d'implementation)
+permet d'imposer des attributs
CODE:
-------------------------------------------
#include <oln/core/2d/image2d.hh>
#include <oln/core/2d/neighb2d.hh>
#include <oln/canvas/two_pass.hh>
#include <oln/morpho/cc_tarjan_v ? .hh>
int main()
{
using namespace oln;
unsigned N = 1024;
image2d<bool> img(N, N);
float tmp;
for (unsigned i = 0; i < N; i++)
for (unsigned j = 0; j < N; j++)
{
tmp = 5 * cos(i) * cos(j);
img.at(i, j) = (tmp > 0) ? tmp : 0;
}
morpho::cc_tarjan(img + c4);
}
-------------------------------------------
Without Options :
-----------------
test_v0:
compile: 16.357s
execution: 1m27.001s
test_v1
compile: 16.229s
execution: 1m14.485s
test_v2
compile: 16.485s
execution: 1m20.421s
test_v4
compile: 16.377s
execution: 1m13.705s
-O3 -DNDEBUG :
--------------
test_v0
compile: 1m5.236s
execution: 1.732s
test_v1
compile: 1m7.844s
execution: 1.560s
test_v2
compile: 1m7.528s
execution: 1.724s
test_v4
compile: 1m7.624s
execution: 1.560s
-O2 -DNDEBUG :
--------------
test_v0
compile: 1m3.108s
execution: 4.196s
test_v1
compile: 1m7.872s
execution: 3.856s
test_v2
compile: 1m9.240s
execution: 4.328s
test_v4
compile: 1m8.360s
execution: 3.720s
-O1 -DNDEBUG :
--------------
test_v0
compile: 21.301s
execution: 4.692s
test_v1
compile: 22.145s
execution: 4.336s
test_v2
compile: 22.185s
execution: 4.604s
test_v4
compile: 22.069s
execution: 4.620s
---------------
version procedurale plus lente !??
Index: ChangeLog
from Ugo Jardonnet <ugo.jardonnet(a)lrde.epita.fr>
Fix Reconstruction. Draft canvas unionfind. .
* oln/morpho/binary_reconstruction_v0.hh: .
* oln/morpho/cc_tarjan_v4.hh: .
* oln/morpho/cc_tarjan_v1.hh: .
* oln/level/local_sup.hh: .
* oln/level/local_inf.hh: .
* oln/canvas/union_find.hh: .
* oln/canvas/two_pass.hh: .
canvas/two_pass.hh | 104 ++++++++++++++++++++++++++++++-------
canvas/union_find.hh | 27 ++++++---
level/local_inf.hh | 18 +++---
level/local_sup.hh | 18 +++---
morpho/binary_reconstruction_v0.hh | 40 +++++++-------
morpho/cc_tarjan_v1.hh | 5 -
morpho/cc_tarjan_v4.hh | 76 ++++++++++++---------------
7 files changed, 181 insertions(+), 107 deletions(-)
Index: oln/morpho/binary_reconstruction_v0.hh
--- oln/morpho/binary_reconstruction_v0.hh (revision 974)
+++ oln/morpho/binary_reconstruction_v0.hh (working copy)
@@ -33,6 +33,7 @@
# include <oln/accumulator/max.hh>
# include <oln/level/clone.hh>
# include <oln/level/fill.hh>
+# include <oln/level/compare.hh>
# include <oln/level/local_inf.hh>
# include <oln/level/local_sup.hh>
@@ -52,18 +53,6 @@
namespace impl
{
- template <typename I>
- bool
- stability(const Image_with_Nbh<I>& marker,
- oln_plain(I)& tmp)
- {
- oln_piter(I) p(marker.points());
- for_all(p)
- if (marker(p) != tmp(p))
- return false;
- return true;
- }
-
template <typename I, typename J>
oln_plain(I)
binary_reconstruction_loop(const Image_with_Nbh<I>& marker,
@@ -88,19 +77,32 @@
}
template <typename I , typename J>
- void // FIXME : Slow impl.
+ oln_plain(I)
binary_reconstruction_(const Image_with_Nbh<I>& marker,
const Binary_Image<J>& mask)
{
- oln_plain(I) tmp = level::clone(marker);
+ accumulator::max_<oln_value(I)> max;
+ oln_plain(I)
+ output = level::clone(marker),
+ memo;
- while ( not stability(marker, tmp) )
+ do
{
- level::fill(inplace(exact(marker).image()), tmp);
- tmp = binary_reconstruction_loop(marker, mask);
- }
+ memo = level::clone(output);
- level::fill(inplace(exact(marker).image()), tmp);
+ // first pass
+ oln_fwd_piter(I) p1(marker.points());
+ for_all(p1)
+ output(p1) = level::local_sup(max, output, p1) and mask(p1);
+
+ // second pass
+ oln_bkd_piter(I) p2(marker.points());
+ for_all(p2)
+ output(p2) = level::local_inf(max, output, p2) and mask(p2);
+
+ } while (output != memo);
+
+ return output;
}
} // end of namespace oln::morpho::impl
Index: oln/morpho/cc_tarjan_v4.hh
--- oln/morpho/cc_tarjan_v4.hh (revision 974)
+++ oln/morpho/cc_tarjan_v4.hh (working copy)
@@ -29,10 +29,9 @@
# define OLN_MORPHO_CC_TARJAN_HH
# include <oln/core/concept/image.hh>
-# include <oln/core/internal/f_ch_value.hh>
-
# include <oln/canvas/two_pass.hh>
# include <oln/level/fill.hh>
+# include <oln/core/internal/f_ch_value.hh>
namespace oln
{
@@ -40,8 +39,6 @@
namespace morpho
{
- // Fwd declaration.
-
template <typename I>
oln_plain_value(I, unsigned)
cc_tarjan(const Image_with_Nbh<I>& f);
@@ -50,95 +47,95 @@
namespace impl
{
-
template <typename I>
- struct cc_tarjan_ : public canvas::v4::two_pass<I>
+ struct cc_tarjan_ : public canvas::v4::two_pass<I, cc_tarjan_<I> >
{
typedef oln_point(I) point;
+ const I& f;
+
oln_plain_value(I, unsigned) output;
oln_plain_value(I, bool) is_processed;
oln_plain_value(I, point) parent;
+ unsigned nlabels;
- cc_tarjan_(const I& img)
+ cc_tarjan_(const I& f)
+ : canvas::v4::two_pass<I, cc_tarjan_<I> >(f),
+ f(f)
{
}
- void init()
+ void impl_init()
{
- prepare(is_processed, with, this.f);
- prepare(output, with, this.f);
- prepare(parent, with, this.f);
+ prepare(is_processed, with, f);
+ prepare(output, with, f);
+ prepare(parent, with, f);
level::fill(inplace(is_processed), false);
+ nlabels = 0;
}
- void first_pass_body(const point& p)
+ void impl_first_pass_body(const point& p)
{
parent(p) = p;
- if ( f(p) )
+ if (f(p) == true)
{
- oln_niter(I) n(this.f, p);
+ oln_niter(I) n(f, p);
for_all(n)
{
- if ( this.f(n) == true and is_processed(n) )
- do_union(this.f, n, p);
+ if ( f(n) == true and is_processed(n) )
+ do_union(n, p);
}
is_processed(p) = true;
}
-
}
- void second_pass_body(const point& p)
+ void impl_second_pass_body(const point& p)
{
- unsigned current_label = 0;
- if ( this.f(p) == true and parent(p) == p )
- output(p) = ++current_label;
+ if (f(p) == true)
+ {
+ if (parent(p) == p)
+ output(p) = ++nlabels;
else
output(p) = output(parent(p));
}
+ else
+ output(p) = 0; // bg label
+ }
- void final()
+ void impl_final()
{
}
-
// auxiliary methods
- point find_root(const I& ima,
- const point& x)
+ point find_root(const point& x) // FIXME: or w/o const&?
{
- if (parent(x) != x)
- {
- parent(x) = find_root(ima, parent(x));
- return parent(x);
- }
+ if (parent(x) == x)
return x;
+ else
+ return parent(x) = find_root(parent(x));
}
- void do_union(const I& ima,
- const point& n,
+ void do_union(const point& n,
const point& p)
{
- point r = find_root(ima, n);
+ point r = find_root(n);
if (r != p)
parent(r) = p;
}
-
};
} // end of namespace oln::morpho::impl
-// Facades.
-
template <typename I>
oln_plain_value(I, unsigned)
cc_tarjan(const Image_with_Nbh<I>& f)
{
- impl::cc_tarjan_<I> f_cc_tarjan(exact(f));
+ impl::cc_tarjan_<I> cc(exact(f));
- f_cc_tarjan.run();
+ cc.run();
- return f_cc_tarjan.output;
+ return cc.output;
}
# endif // ! OLN_INCLUDE_ONLY
@@ -147,5 +144,4 @@
} // end of namespace oln
-
#endif // ! OLN_MORPHO_CC_TARJAN_HH
Index: oln/morpho/cc_tarjan_v1.hh
--- oln/morpho/cc_tarjan_v1.hh (revision 974)
+++ oln/morpho/cc_tarjan_v1.hh (working copy)
@@ -54,8 +54,7 @@
namespace impl
{
- template <typename I> // FIXME : template< op_<I, extended_by, N>,
- // typename I, Typename N> ?
+ template <typename I>
struct cc_tarjan_
{
typedef oln_point(I) point;
@@ -129,7 +128,7 @@
{
point r = find_root(n);
if (r != p)
- parent(r) = p5A5A;
+ parent(r) = p;
}
};
Index: oln/level/local_sup.hh
--- oln/level/local_sup.hh (revision 974)
+++ oln/level/local_sup.hh (working copy)
@@ -68,9 +68,9 @@
const oln_point(I)& p)
{
f.init_with(input(p));
- oln_niter(I) n(p, input);
+ oln_niter(I) n(input, p);
for_all(n)
- if (n > p)
+ if (n < p)
f(input(n));
return f.value();
}
@@ -86,9 +86,9 @@
f.init_with(input(p));
if (f.value() == true)
return true;
- oln_niter(I) n(p, input);
+ oln_niter(I) n(input, p);
for_all(n)
- if (n > p)
+ if (n < p)
{
f(input(n)); // FIXME: Change to f.take(input(n))?
if (f.value() == true)
@@ -106,9 +106,9 @@
const oln_point(I)& p)
{
f.init_with(input(p));
- oln_niter(I) n(p, input);
+ oln_niter(I) n(input, p);
for_all(n)
- if (n > p)
+ if (n < p)
{
f(input(n)); // FIXME: Change to f.take(input(n))?
if (f.value() == false)
@@ -135,7 +135,7 @@
f.init_with(input(p));
oln_qiter(W) q(win, p);
for_all(q)
- if (q > p)
+ if (q < p)
if (input.owns_(q))
f(input(q));
return f.value();
@@ -155,7 +155,7 @@
return true;
oln_qiter(W) q(win, p);
for_all(q)
- if (q > p)
+ if (q < p)
{
if (input.owns_(q))
f(input(q));
@@ -177,7 +177,7 @@
f.init_with(input(p));
oln_qiter(W) q(win, p);
for_all(q)
- if (q > p)
+ if (q < p)
{
if (input.owns_(q))
f(input(q));
Index: oln/level/local_inf.hh
--- oln/level/local_inf.hh (revision 974)
+++ oln/level/local_inf.hh (working copy)
@@ -68,9 +68,9 @@
const oln_point(I)& p)
{
f.init_with(input(p));
- oln_niter(I) n(p, input);
+ oln_niter(I) n(input, p);
for_all(n)
- if (n < p)
+ if (n > p)
f(input(n));
return f.value();
}
@@ -86,9 +86,9 @@
f.init_with(input(p));
if (f.value() == true)
return true;
- oln_niter(I) n(p, input);
+ oln_niter(I) n(input, p);
for_all(n)
- if (n < p)
+ if (n > p)
{
f(input(n)); // FIXME: Change to f.take(input(n))?
if (f.value() == true)
@@ -106,9 +106,9 @@
const oln_point(I)& p)
{
f.init_with(input(p));
- oln_niter(I) n(p, input);
+ oln_niter(I) n(input, p);
for_all(n)
- if (n < p)
+ if (n > p)
{
f(input(n)); // FIXME: Change to f.take(input(n))?
if (f.value() == false)
@@ -135,7 +135,7 @@
f.init_with(input(p));
oln_qiter(W) q(win, p);
for_all(q)
- if (q < p)
+ if (q > p)
if (input.owns_(q))
f(input(q));
return f.value();
@@ -155,7 +155,7 @@
return true;
oln_qiter(W) q(win, p);
for_all(q)
- if (q < p)
+ if (q > p)
{
if (input.owns_(q))
f(input(q));
@@ -177,7 +177,7 @@
f.init_with(input(p));
oln_qiter(W) q(win, p);
for_all(q)
- if (q < p)
+ if (q > p)
{
if (input.owns_(q))
f(input(q));
Index: oln/canvas/union_find.hh
--- oln/canvas/union_find.hh (revision 974)
+++ oln/canvas/union_find.hh (working copy)
@@ -43,15 +43,24 @@
oln_bkd_piter(I) p1(fun.f.points());
for_all(p1)
{
- fun.parent(p1) = p1;
- if (fun.f(p) == true)
+ if (fun.is_in_I(p1))
{
- oln_niter(I) n(f, p);
+ fun.make_set(p);
+ oln_niter(I) n(fun.f.points(), p);
for_all(n)
{
+ if ( fun.p_in_D_upper_or_equal(p1) )
+ {
if (is_processed(n))
- if (f.condition_bck(p1, n))
- fun.first_pass_body(p1);
+ fun.first_pass_body1(p1);
+ }
+ else
+ if ( fun.p_in_Do(p1) )
+ fun.is_processed(p1) = false;
+ else ( fun.p_in_D_lower_or_equal(p1) )
+ {
+ fun.first_pass_body2(p1);
+ }
}
}
}
@@ -60,10 +69,12 @@
oln_fwd_piter(I) p2(fun.f.points());
for_all(p2)
{
- if (fun.f(p2) == true)
- if (fun.condition_fwd(p2))
+ if (fun.is_in_I(p2))
{
- fun.second_pass_body(p2);
+ if (fun.is_root(p2))
+ fun.set_output_value(p2);
+ else
+ fun.output(p) = fun.output(fun.parent(p)) ; //bg label
}
}
Index: oln/canvas/two_pass.hh
--- oln/canvas/two_pass.hh (revision 974)
+++ oln/canvas/two_pass.hh (working copy)
@@ -25,11 +25,15 @@
// reasons why the executable file might be covered by the GNU General
// Public License.
-#include <oln/core/concept/image.hh>
-
#ifndef OLN_CANVAS_TWO_PASS_HH
# define OLN_CANVAS_TWO_PASS_HH
+# include <oln/core/concept/image.hh>
+
+
+namespace oln
+{
+
namespace canvas
{
@@ -39,7 +43,7 @@
typename I> // Data owned by f.
void two_pass(F<I>& fun)
{
-// mlc::assert_< mlc_is_a(I, Image) >::check();
+ mlc::assert_< mlc_is_a(I, Image) >::check();
fun.init();
@@ -62,7 +66,7 @@
template <typename F, typename I>
void two_pass(F& fun, I f)
{
-// mlc::assert_< mlc_is_a(I, Image) >::check();
+ mlc::assert_< mlc_is_a(I, Image) >::check();
fun.init(f);
@@ -83,9 +87,9 @@
namespace v3 // Auxiliar data given as argument.
{
template <typename F, typename I, typename A>
- void two_pass(F fun, I f, A& aux)
+ void two_pass(F& fun, I& f, A& aux)
{
-// mlc::assert_< mlc_is_a(I, Image) >::check();
+ mlc::assert_< mlc_is_a(I, Image) >::check();
f.init(f, aux);
@@ -106,51 +110,113 @@
namespace v4 // Via Inheritance.
{
+ template <typename I, typename Exact>
+ struct two_pass : public virtual Any<Exact>
+ {
+ void init()
+ {
+ exact(this)->impl_init();
+ }
+
+ void first_pass_body(const oln_point(I)& p)
+ {
+ exact(this)->impl_first_pass_body(p);
+ }
+
+ void second_pass_body(const oln_point(I)& p)
+ {
+ exact(this)->impl_second_pass_body(p);
+ }
+
+ void final()
+ {
+ exact(this)->impl_final();
+ }
+
+ // Concrete method.
+ void run()
+ {
+ init();
+
+ // first pass
+ for_all(p1)
+ first_pass_body(p1);
+
+ // second pass
+
+ for_all(p2)
+ second_pass_body(p2);
+
+ final();
+ }
+
+
+ protected:
+
+ // Ctor.
+ two_pass(const Image<I>& f) :
+ p1(f.points()),
+ p2(f.points())
+ {
+ }
- template <typename Exact>
+ oln_bkd_piter(I) p1;
+ oln_fwd_piter(I) p2;
+
+ };
+ }
+
+
+ namespace v5
+ {
+ template<typename I, typename Exact>
struct two_pass
{
+ const I& f;
+
void init()
{
- this->exact().impl_init();
+ assert(0 && "'void init()' not implemented.");
}
void final()
{
- this->exact().impl_final();
+ assert(0 && "'void final()' not implemented.");
}
- void first_pass_body(const oln_point(I)& p)
+ void first_pass_body(const oln_point(I)&)
{
- this->exact().impl_first_pass_body(p);
+ assert(0 && "'void first_pass_body(const oln_point(I)& p)' not implemented.");
}
- void second_pass_body(const oln_point(I)& p)
+ void second_pass_body(const oln_point(I)&)
{
- this->exact().impl_second_pass_body(p);
+ assert(0 && "'void second_pass_body(const oln_point(I)& p)' not implemented.");
}
void run()
{
- init(f);
+ init();
// first pass
- oln_bkd_piter(typename Exact::I) p1(f.points());
+ oln_bkd_piter(I) p1(f.points());
for_all(p1)
first_pass_body(p1);
// second pass
- oln_fwd_piter(typename Exact::I) p2(f.points());
+ oln_fwd_piter(I) p2(f.points());
for_all(p2)
second_pass_body(p2);
- final(f);
+ typename Exact::final();
}
};
- }
+ } // end of namespace v5
-}
+ } // end of namespace morpho
+
+} // end of namespace oln
#endif // ! OLN_CANVAS_TWO_PASS_HH
1
0
https://svn.lrde.epita.fr/svn/oln/trunk/olena
Index: ChangeLog
from Thierry Geraud <thierry.geraud(a)lrde.epita.fr>
Add materials for value types and builtins.
* oln/core/internal/f_grid_coord_to_point.hh: New.
* oln/core/internal/macros_ops.hh: New.
* oln/core/internal/value_base.hh: New.
* oln/morpho/thinning.hh: New.
* oln/value/gray_level.hh: New.
* oln/value/bool.hh: New.
* oln/value/gray.hh: New.
* oln/value/black.hh: New.
* oln/value/mlc_extra.hh: New.
* oln/core/2d/image2d_b.hh (fiter): Update.
* oln/core/3d/image3d_b.hh: Likewise.
* oln/core/equipment.hh (encoding, fiter, nbits): New.
* oln/core/gen/extended_by.hh: Add mutable nbh version.
* oln/core/gen/inplace.hh: New error type.
* oln/core/gen/value.hh (unwrap): New.
(make_value): New overload.
* oln/core/gen/zero.hh: Replace operators by...
(assignment_): New.
* oln/core/concept/literal.hh (operator T): New.
* oln/core/concept/dpoint.hh (operator%=): Fix and factor.
* oln/core/internal/dpoint_base.hh (impl_op_mod_equal_): Remove.
* oln/core/concept/value.hh (Boolean): Remove.
* oln/core/concept/operators.hh: Handle builtins.
* oln/morpho/elementary_gradient.hh (postcondition): Update.
* oln/morpho/top_hat_black.hh,
* oln/morpho/top_hat_white.hh,
* oln/morpho/elementary_gradient_internal.hh,
* oln/morpho/elementary_gradient_external.hh,
* oln/morpho/gradient_internal.hh,
* oln/morpho/gradient.hh,
* oln/morpho/gradient_external.hh: Likewise.
* oln/arith/plus.hh,
* oln/arith/minus.hh,
* oln/level/local_sup.hh,
* oln/level/fill.hh,
* oln/level/local_inf.hh,
* oln/value/builtin_traits.hh,
* oln/value/builtin.hh: Update.
* oln/level/compare.hh: Update.
arith/minus.hh | 2
arith/plus.hh | 2
core/2d/image2d_b.hh | 3
core/3d/image3d_b.hh | 3
core/concept/dpoint.hh | 9
core/concept/literal.hh | 13 +
core/concept/operators.hh | 59 ++++
core/concept/value.hh | 22 -
core/equipment.hh | 6
core/gen/extended_by.hh | 2
core/gen/inplace.hh | 7
core/gen/value.hh | 17 +
core/gen/zero.hh | 33 --
core/internal/dpoint_base.hh | 14 -
core/internal/f_grid_coord_to_point.hh | 111 ++++++++
core/internal/macros_ops.hh | 77 ++++++
core/internal/value_base.hh | 300 +++++++++++++++++++++++
level/compare.hh | 161 ++++++++----
level/fill.hh | 3
level/local_inf.hh | 6
level/local_sup.hh | 6
morpho/elementary_gradient.hh | 2
morpho/elementary_gradient_external.hh | 2
morpho/elementary_gradient_internal.hh | 2
morpho/gradient.hh | 2
morpho/gradient_external.hh | 2
morpho/gradient_internal.hh | 2
morpho/thinning.hh | 141 +++++++++++
morpho/top_hat_black.hh | 2
morpho/top_hat_white.hh | 2
value/black.hh | 91 +++++++
value/bool.hh | 55 ++++
value/builtin.hh | 61 +---
value/builtin_traits.hh | 64 ++---
value/gray.hh | 420 +++++++++++++++++++++++++++++++++
value/gray_level.hh | 360 ++++++++++++++++++++++++++++
value/mlc_extra.hh | 76 +++++
37 files changed, 1913 insertions(+), 227 deletions(-)
Index: oln/core/2d/image2d_b.hh
--- oln/core/2d/image2d_b.hh (revision 973)
+++ oln/core/2d/image2d_b.hh (working copy)
@@ -89,8 +89,7 @@
typedef internal::plain_primitive_image_<current> super;
typedef array2d_<T, int> array_t;
public:
- //FIXME (fast image concept??)
- typedef typename vtypes< image2d_b<T> >::fiter fiter;
+ typedef stc_type(current, fiter) fiter;
stc_using(data);
image2d_b();
Index: oln/core/equipment.hh
--- oln/core/equipment.hh (revision 973)
+++ oln/core/equipment.hh (working copy)
@@ -83,7 +83,12 @@
# define oln_dim(T) oln_typename_shortcut__(T, dim)
# define oln_dpoint(T) oln_typename_shortcut__(T, dpoint)
+ // e
+ stc_decl_associated_type( encoding );
+# define oln_encoding(T) oln_typename_shortcut__(T, encoding)
+
// f
+ stc_decl_associated_type( fiter );
stc_decl_associated_type( fwd_niter );
stc_decl_associated_type( fwd_piter );
stc_decl_associated_type( fwd_qiter );
@@ -108,6 +113,7 @@
// n
stc_decl_associated_type( n );
stc_decl_associated_type( nbh );
+ stc_decl_associated_type( nbits );
stc_decl_associated_type( niter );
# define oln_niter(T) oln_typename_shortcut__(T, niter)
Index: oln/core/3d/image3d_b.hh
--- oln/core/3d/image3d_b.hh (revision 973)
+++ oln/core/3d/image3d_b.hh (working copy)
@@ -88,8 +88,7 @@
typedef internal::plain_primitive_image_<current> super;
typedef array3d_<T, int> array_t;
public:
- //FIXME (fast image concept??)
- typedef typename vtypes< image3d_b<T> >::fiter fiter;
+ typedef stc_type(current, fiter) fiter;
stc_using(data);
image3d_b();
Index: oln/core/gen/extended_by.hh
--- oln/core/gen/extended_by.hh (revision 973)
+++ oln/core/gen/extended_by.hh (working copy)
@@ -46,11 +46,13 @@
{
oln_decl_op_image_extended_by_const(Neighborhood);
+ oln_decl_op_image_extended_by_mutable(Neighborhood);
# ifndef OLN_INCLUDE_ONLY
oln_def_op_image_extended_by_const(Neighborhood);
+ oln_def_op_image_extended_by_mutable(Neighborhood);
# endif // ! OLN_INCLUDE_ONLY
Index: oln/core/gen/inplace.hh
--- oln/core/gen/inplace.hh (revision 973)
+++ oln/core/gen/inplace.hh (working copy)
@@ -62,6 +62,13 @@
inplace(inplace_<I> ima);
+ namespace ERROR
+ {
+
+ struct keyword_inplace_is_missing;
+
+ } // end of namespace oln::ERROR
+
# ifndef OLN_INCLUDE_ONLY
Index: oln/core/gen/value.hh
--- oln/core/gen/value.hh (revision 973)
+++ oln/core/gen/value.hh (working copy)
@@ -79,6 +79,8 @@
template <typename U>
operator value_<U>() const;
+ const T& unwrap() const;
+
private:
T val_;
};
@@ -146,14 +148,25 @@
}
template <typename T>
- value_<T> make_value(const T& val)
+ const T&
+ value_<T>::unwrap() const
+ {
+ return this->val_;
+ }
+
+ // make_value
+
+ template <typename T>
+ value_<T>
+ make_value(const T& val)
{
value_<T> tmp = val;
return tmp;
}
template <typename T>
- value_<T> make_value(const value_<T>& val)
+ value_<T>
+ make_value(const value_<T>& val)
{
return val;
}
Index: oln/core/gen/zero.hh
--- oln/core/gen/zero.hh (revision 973)
+++ oln/core/gen/zero.hh (working copy)
@@ -34,17 +34,17 @@
namespace oln
{
- struct zero_t : public Literal< zero_t >
- {
+ struct zero_t;
- template <typename T>
- operator T() const;
- // builtins:
- operator unsigned() const;
- operator int() const;
- operator float() const;
- operator double() const;
+ void assignment_(int& i, const zero_t&) { i = 0; }
+ void assignment_(unsigned& u, const zero_t&) { u = 0u; }
+ void assignment_(float& f, const zero_t&) { f = 0.f; }
+ void assignment_(double& d, const zero_t&) { d = 0.; }
+
+
+ struct zero_t : public Literal< zero_t >
+ {
}
zero;
@@ -62,21 +62,6 @@
# ifndef OLN_INCLUDE_ONLY
template <typename T>
- zero_t::operator T() const
- {
- mlc::assert_< mlc_is_a(T, Any) >::check(); // FIXME: Add err msg.
- T tmp;
- tmp.assign_(*this);
- return tmp;
- }
-
- zero_t::operator unsigned() const { return 0u; }
- zero_t::operator int() const { return 0; }
- zero_t::operator float() const { return 0.f; }
- zero_t::operator double() const { return 0.; }
-
-
- template <typename T>
T
operator - (const Any<T>& rhs)
{
Index: oln/core/concept/literal.hh
--- oln/core/concept/literal.hh (revision 973)
+++ oln/core/concept/literal.hh (working copy)
@@ -40,6 +40,10 @@
struct Literal : public Any<Exact>
{
typedef Literal<void> category;
+
+ template <typename T>
+ operator T() const; // NEW
+
protected:
Literal();
};
@@ -64,6 +68,15 @@
{
}
+ template <typename Exact>
+ template <typename T>
+ Literal<Exact>::operator T() const
+ {
+ T tmp;
+ assignment_(tmp, exact(*this));
+ return tmp;
+ }
+
template <typename L, typename R>
oln_minus_trait(R, R)
operator - (const Literal<L>& lhs, const Any<R>& rhs)
Index: oln/core/concept/dpoint.hh
--- oln/core/concept/dpoint.hh (revision 973)
+++ oln/core/concept/dpoint.hh (working copy)
@@ -30,6 +30,7 @@
# define OLN_CORE_CONCEPT_DPOINT_HH
# include <oln/core/concept/point.hh>
+# include <xtd/vec.hh>
@@ -192,7 +193,13 @@
template <typename D, typename D2>
D& operator %= (Dpoint<D>& lhs, const Dpoint<D2>& rhs)
{
- exact(lhs).vec() %= exact(rhs).vec();
+ // FIXME: Check that D::n = D2::n
+ for (unsigned i = 0; i < D::n; ++i)
+ {
+ exact(lhs)[i] %= exact(rhs)[i];
+ if (exact(lhs)[i] < 0)
+ exact(lhs)[i] += exact(rhs)[i];
+ }
return exact(lhs);
}
Index: oln/core/concept/value.hh
--- oln/core/concept/value.hh (revision 973)
+++ oln/core/concept/value.hh (working copy)
@@ -44,21 +44,6 @@
Value();
};
- /// Concept-class "Boolean".
-
- template <typename Exact>
- struct Boolean : public Value<Exact>
- {
- protected:
- Boolean();
- };
-
- template <>
- struct vtypes< bool > // FIXME: single_vtype? or move elsewhere?
- {
- typedef stc::is<Boolean> category;
- };
-
# ifndef OLN_INCLUDE_ONLY
@@ -69,13 +54,6 @@
{
}
- // Boolean.
-
- template <typename Exact>
- Boolean<Exact>::Boolean()
- {
- }
-
# endif // ! OLN_INCLUDE_ONLY
} // end of namespace oln
Index: oln/core/concept/operators.hh
--- oln/core/concept/operators.hh (revision 973)
+++ oln/core/concept/operators.hh (working copy)
@@ -31,6 +31,7 @@
# include <oln/core/equipment.hh>
# include <oln/core/gen/traits.hh>
# include <oln/core/gen/value.hh>
+# include <oln/core/internal/macros_ops.hh>
namespace oln
@@ -61,7 +62,7 @@
template <typename T>
T
- operator - (const Any<T>& lhs, const Any<T>& rhs); // Using "+=".
+ operator - (const Any<T>& lhs, const Any<T>& rhs); // Using "-=".
template <typename T>
T
@@ -69,6 +70,13 @@
+ // With builtin:
+
+ oln_def_cmp_ops_with_builtin(int);
+ oln_def_cmp_ops_with_builtin(float);
+ oln_def_cmp_ops_with_builtin(double);
+
+
namespace ERROR
{
@@ -120,6 +128,43 @@
+ // FIXME: Just a try.
+
+ // The result of "a builtin Op any type" is just like
+ // the commuted operation, that is, "any type Op a builtin".
+ // As a consequence, we never have to handle the case of a builtin
+ // being the lhs operand.
+
+ template <typename T>
+ oln_plus_trait(T, int)
+ operator+ (int lhs, const Any<T>& rhs)
+ {
+ return exact(rhs) + lhs;
+ }
+
+ template <typename T>
+ oln_times_trait(T, int)
+ operator* (int lhs, const Any<T>& rhs)
+ {
+ return exact(rhs) * lhs;
+ }
+
+ template <typename T>
+ oln_times_trait(T, float)
+ operator* (float lhs, const Any<T>& rhs)
+ {
+ return exact(rhs) * lhs;
+ }
+
+ template <typename T>
+ oln_times_trait(T, double)
+ operator* (double lhs, const Any<T>& rhs)
+ {
+ return exact(rhs) * lhs;
+ }
+
+ // FIXME: end of "Just a try".
+
# ifndef OLN_INCLUDE_ONLY
@@ -175,7 +220,7 @@
// Operator =.
template <typename L, typename R>
- void operator = (const Any<L>& lhs, const Any<R>& rhs)
+ void operator = (const Any<L>&, const Any<R>&)
{
mlc::abort_<L,
typename ERROR::operator_< eq_id >::_is_missing_for_types_<L, R>
@@ -184,7 +229,7 @@
// Operator <.
template <typename L, typename R>
- void operator < (const Any<L>& lhs, const Any<R>& rhs)
+ void operator < (const Any<L>&, const Any<R>&)
{
mlc::abort_<L,
typename ERROR::operator_< less_id >::template _is_missing_for_types_<L, R>
@@ -193,7 +238,7 @@
// Operator +=.
template <typename L, typename R>
- void operator += (const Any<L>& lhs, const Any<R>& rhs)
+ void operator += (const Any<L>&, const Any<R>&)
{
mlc::abort_<L,
typename ERROR::operator_< plus_equal_id >::template _is_missing_for_types_<L, R>
@@ -202,7 +247,7 @@
// Operator -=.
template <typename L, typename R>
- void operator -= (const Any<L>& lhs, const Any<R>& rhs)
+ void operator -= (const Any<L>&, const Any<R>&)
{
mlc::abort_<L,
typename ERROR::operator_< minus_equal_id >::template _is_missing_for_types_<L, R>
@@ -211,7 +256,7 @@
// Operator %=.
template <typename L, typename R>
- void operator %= (const Any<L>& lhs, const Any<R>& rhs)
+ void operator %= (const Any<L>&, const Any<R>&)
{
mlc::abort_<L,
typename ERROR::operator_< modulus_equal_id >::template _is_missing_for_types_<L, R>
@@ -220,7 +265,7 @@
// Operator -.
template <typename T>
- void operator - (const Any<T>& rhs)
+ void operator - (const Any<T>&)
{
mlc::abort_<T,
typename ERROR::operator_< uminus_id >::template _is_missing_for_<T>
Index: oln/core/internal/dpoint_base.hh
--- oln/core/internal/dpoint_base.hh (revision 973)
+++ oln/core/internal/dpoint_base.hh (working copy)
@@ -85,8 +85,6 @@
coord operator[](unsigned i) const;
coord& operator[](unsigned i);
- Exact& impl_op_mod_equal_(const Exact& rhs); // FIXME: Remove HERE
-
typedef xtd::vec<n, coord> vec_t;
const vec_t& vec() const;
vec_t& vec();
@@ -118,18 +116,6 @@
}
template <typename Exact>
- Exact& dpoint_base_<Exact>::impl_op_mod_equal_(const Exact& rhs)
- {
- for (unsigned i = 0; i < n; ++i)
- {
- v_[i] %= rhs.v_[i];
- if (v_[i] < 0)
- v_[i] += rhs.v_[i];
- }
- return exact(*this);
- }
-
- template <typename Exact>
const typename dpoint_base_<Exact>::vec_t&
dpoint_base_<Exact>::vec() const
{
Index: oln/core/internal/f_grid_coord_to_point.hh
--- oln/core/internal/f_grid_coord_to_point.hh (revision 0)
+++ oln/core/internal/f_grid_coord_to_point.hh (revision 0)
@@ -0,0 +1,111 @@
+// Copyright (C) 2007 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#ifndef OLN_CORE_INTERNAL_F_GRID_COORD_TO_POINT_HH
+# define OLN_CORE_INTERNAL_F_GRID_COORD_TO_POINT_HH
+
+# include <oln/core/concept/grid.hh>
+
+
+# define oln_f_grid_coord_to_point(G, C) \
+typename oln::internal::f_grid_coord_to_point_< G, C >::ret
+
+
+namespace oln
+{
+
+ /// \{
+ /// Forward declarations.
+
+ // Grid types.
+
+ struct grid1d;
+ struct grid2d; // FIXME: hex, tri...
+ struct grid3d;
+
+ // Point types.
+
+ struct point1d;
+ struct point2d;
+ struct point3d;
+ template <typename G, typename C> class point;
+
+ /// \}
+
+
+
+ namespace internal
+ {
+
+ template <typename G, typename C>
+ struct grid_coord_to_point__;
+
+
+ /// \{
+ /// Definitions.
+
+ template <typename G, typename C>
+ struct grid_coord_to_point__
+ {
+ typedef oln::point<G, C> ret;
+ };
+
+ template <>
+ struct grid_coord_to_point__< grid1d, int >
+ {
+ typedef point1d ret;
+ };
+
+ template <>
+ struct grid_coord_to_point__< grid2d, int >
+ {
+ typedef point2d ret;
+ };
+
+ // FIXME: 2D hex/tri...
+
+ template <>
+ struct grid_coord_to_point__< grid3d, int >
+ {
+ typedef point3d ret;
+ };
+
+ /// \}
+
+
+ template <typename G, typename C>
+ struct f_grid_coord_to_point_ : private mlc::assert_< mlc_is_a(G, Grid) >,
+ public grid_coord_to_point__< G, C >
+ {
+ };
+
+ } // end of namespace oln::internal
+
+} // end of namespace oln
+
+
+#endif // ! OLN_CORE_INTERNAL_F_GRID_COORD_TO_POINT_HH
Index: oln/core/internal/point_impl.hh
Index: oln/core/internal/macros_ops.hh
--- oln/core/internal/macros_ops.hh (revision 0)
+++ oln/core/internal/macros_ops.hh (revision 0)
@@ -0,0 +1,77 @@
+// Copyright (C) 2007 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#ifndef OLN_CORE_INTERNAL_MACROS_OPS_HH
+# define OLN_CORE_INTERNAL_MACROS_OPS_HH
+
+
+# define oln_def_cmp_ops_with_builtin(Builtin) \
+ \
+ template <typename L> \
+ bool operator = (const Any<L>& lhs, Builtin rhs) { return exact(lhs) = make_value(rhs); } \
+ \
+ template <typename L> \
+ bool operator != (const Any<L>& lhs, Builtin rhs) { return not (exact(lhs) = make_value(rhs)); } \
+ \
+ \
+ template <typename L> \
+ bool operator = (Builtin lhs, const Any<L>& rhs) { return exact(rhs) = make_value(lhs); } \
+ \
+ template <typename L> \
+ bool operator != (Builtin lhs, const Any<L>& rhs) { return not (exact(rhs) = make_value(lhs)); } \
+ \
+ \
+ template <typename L> \
+ bool operator < (const Any<L>& lhs, Builtin rhs) { return exact(lhs) < make_value(rhs); } \
+ \
+ template <typename L> \
+ bool operator > (const Any<L>& lhs, Builtin rhs) { return exact(lhs) > make_value(rhs); } \
+ \
+ template <typename L> \
+ bool operator <= (const Any<L>& lhs, Builtin rhs) { return exact(lhs) <= make_value(rhs); } \
+ \
+ template <typename L> \
+ bool operator >= (const Any<L>& lhs, Builtin rhs) { return exact(lhs) >= make_value(rhs); } \
+ \
+ \
+ template <typename L> \
+ bool operator < (Builtin lhs, const Any<L>& rhs) { return exact(rhs) > make_value(lhs); } \
+ \
+ template <typename L> \
+ bool operator > (Builtin lhs, const Any<L>& rhs) { return exact(rhs) < make_value(lhs); } \
+ \
+ template <typename L> \
+ bool operator <= (Builtin lhs, const Any<L>& rhs) { return exact(rhs) >= make_value(lhs); } \
+ \
+ template <typename L> \
+ bool operator >= (Builtin lhs, const Any<L>& rhs) { return exact(rhs) <= make_value(lhs); } \
+ \
+ \
+ struct e_n_d___w_i_t_h___s_e_m_i_c_o_l_u_m_n
+
+
+#endif // ! OLN_CORE_INTERNAL_MACROS_OPS_HH
Index: oln/core/internal/value_base.hh
--- oln/core/internal/value_base.hh (revision 0)
+++ oln/core/internal/value_base.hh (revision 0)
@@ -0,0 +1,300 @@
+// Copyright (C) 2007 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#ifndef OLN_CORE_INTERNAL_VALUE_BASE_HH
+# define OLN_CORE_INTERNAL_VALUE_BASE_HH
+
+# include <oln/core/concept/value.hh>
+
+
+// FIXME: Rename this file as oln/value/internal/value_base.hh?
+
+
+/*
+ * The base value classes mimics this image hierarchy:
+ *
+ * Image
+ * |
+ * |
+ * o -- + -- Gray_Level_Image
+ * |
+ * + -- Color_Image
+ * |
+ * + -- Label_Image
+ * | |
+ * | + -- Binary_Image
+ * | |
+ * | + -- String_Image
+ * |
+ * + -- Deformation_Field_Image
+ * |
+ * + -- Data_Image
+ */
+
+
+namespace oln
+{
+
+ /// \{
+ /// Fwd decls.
+
+ namespace internal
+ {
+ template <typename Exact> class value_base_;
+
+ template <typename Exact> class graylevel_value_;
+ template <typename Exact> class color_value_;
+
+ template <typename Exact> class label_value_;
+ template <typename Exact> class boolean_value_;
+ template <typename Exact> class string_value_;
+
+ template <typename Exact> class data_value_;
+ }
+
+ /// \}
+
+
+ /// \{
+ /// Super types.
+
+ template <typename Exact>
+ struct super_trait_< internal::value_base_<Exact> >
+ {
+ typedef Value<Exact> ret;
+ };
+
+ template <typename Exact>
+ struct super_trait_< internal::graylevel_value_<Exact> >
+ {
+ typedef internal::value_base_<Exact> ret;
+ };
+
+ template <typename Exact>
+ struct super_trait_< internal::color_value_<Exact> >
+ {
+ typedef internal::value_base_<Exact> ret;
+ };
+
+ template <typename Exact>
+ struct super_trait_< internal::label_value_<Exact> >
+ {
+ typedef internal::value_base_<Exact> ret;
+ };
+
+ template <typename Exact>
+ struct super_trait_< internal::boolean_value_<Exact> >
+ {
+ typedef internal::label_value_<Exact> ret;
+ };
+
+ template <typename Exact>
+ struct super_trait_< internal::string_value_<Exact> >
+ {
+ typedef internal::label_value_<Exact> ret;
+ };
+
+ template <typename Exact>
+ struct super_trait_< internal::data_value_<Exact> >
+ {
+ typedef internal::value_base_<Exact> ret;
+ };
+
+ /// \}
+
+
+ /// \{
+ /// Virtual types.
+
+ template <typename Exact>
+ struct vtypes< internal::value_base_<Exact> >
+ {
+ typedef stc::abstract encoding;
+
+ // Final:
+ typedef stc::final< stc::is<Value> > category;
+ };
+
+ template <typename Exact>
+ struct vtypes< internal::graylevel_value_<Exact> >
+ {
+ typedef stc::abstract nbits;
+ };
+
+ template <typename Exact>
+ struct vtypes< internal::color_value_<Exact> >
+ {
+ };
+
+ template <typename Exact>
+ struct vtypes< internal::label_value_<Exact> >
+ {
+ typedef stc::abstract nbits;
+ };
+
+ template <typename Exact>
+ struct vtypes< internal::boolean_value_<Exact> >
+ {
+ };
+
+ template <typename Exact>
+ struct vtypes< internal::string_value_<Exact> >
+ {
+ };
+
+ template <typename Exact>
+ struct vtypes< internal::data_value_<Exact> >
+ {
+ };
+
+ /// \}
+
+
+
+ namespace internal
+ {
+
+ /// Base implementation class for value classes.
+
+ template <typename Exact>
+ class value_base_ : public Value<Exact>
+ {
+ public:
+ stc_typename(encoding);
+
+ // FIXME: Contents?
+ protected:
+ value_base_();
+ };
+
+
+ template <typename Exact>
+ class graylevel_value_ : public value_base_<Exact>
+ {
+ public:
+ // FIXME: Contents?
+ protected:
+ graylevel_value_();
+ };
+
+
+ template <typename Exact>
+ class color_value_ : public value_base_<Exact>
+ {
+ public:
+ // FIXME: Contents?
+ protected:
+ color_value_();
+ };
+
+
+ template <typename Exact>
+ class label_value_ : public value_base_<Exact>
+ {
+ public:
+ // FIXME: Contents?
+ protected:
+ label_value_();
+ };
+
+
+ template <typename Exact>
+ class boolean_value_ : public label_value_<Exact>
+ {
+ public:
+ // FIXME: Contents?
+ protected:
+ boolean_value_();
+ };
+
+
+ template <typename Exact>
+ class string_value_ : public label_value_<Exact>
+ {
+ public:
+ // FIXME: Contents?
+ protected:
+ string_value_();
+ };
+
+
+ template <typename Exact>
+ class data_value_ : public value_base_<Exact>
+ {
+ public:
+ // FIXME: Contents?
+ protected:
+ data_value_();
+ };
+
+
+
+# ifndef OLN_INCLUDE_ONLY
+
+ template <typename Exact>
+ value_base_<Exact>::value_base_()
+ {
+ }
+
+ template <typename Exact>
+ graylevel_value_<Exact>::graylevel_value_()
+ {
+ }
+
+ template <typename Exact>
+ color_value_<Exact>::color_value_()
+ {
+ }
+
+ template <typename Exact>
+ label_value_<Exact>::label_value_()
+ {
+ }
+
+ template <typename Exact>
+ boolean_value_<Exact>::boolean_value_()
+ {
+ }
+
+ template <typename Exact>
+ string_value_<Exact>::string_value_()
+ {
+ }
+
+ template <typename Exact>
+ data_value_<Exact>::data_value_()
+ {
+ }
+
+# endif // ! OLN_INCLUDE_ONLY
+
+ } // end of namespace oln::internal
+
+} // end of namespace oln
+
+
+#endif // ! OLN_CORE_INTERNAL_VALUE_BASE_HH
Index: oln/morpho/elementary_gradient.hh
--- oln/morpho/elementary_gradient.hh (revision 973)
+++ oln/morpho/elementary_gradient.hh (working copy)
@@ -76,7 +76,7 @@
elementary_gradient(const Image_with_Nbh<I>& input)
{
oln_plain(I) output = impl::elementary_gradient_(exact(input));
- postcondition(output >= zero);
+ postcondition(output >= oln_value(I)(zero));
return output;
}
Index: oln/morpho/top_hat_black.hh
--- oln/morpho/top_hat_black.hh (revision 973)
+++ oln/morpho/top_hat_black.hh (working copy)
@@ -75,7 +75,7 @@
top_hat_black(const Image<I>& input, const Window<W>& win)
{
oln_plain(I) output = impl::top_hat_black_(exact(input), exact(win));
- postcondition(output >= zero);
+ postcondition(output >= oln_value(I)(zero));
return output;
}
Index: oln/morpho/top_hat_white.hh
--- oln/morpho/top_hat_white.hh (revision 973)
+++ oln/morpho/top_hat_white.hh (working copy)
@@ -74,7 +74,7 @@
top_hat_white(const Image<I>& input, const Window<W>& win)
{
oln_plain(I) output = impl::top_hat_white_(exact(input), exact(win));
- postcondition(output >= zero);
+ postcondition(output >= oln_value(I)(zero));
return output;
}
Index: oln/morpho/thinning.hh
--- oln/morpho/thinning.hh (revision 0)
+++ oln/morpho/thinning.hh (revision 0)
@@ -0,0 +1,141 @@
+// Copyright (C) 2007 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#ifndef OLN_MORPHO_THINNING_HH
+# define OLN_MORPHO_THINNING_HH
+
+# include <oln/morpho/erosion.hh>
+# include <oln/morpho/dilation.hh>
+/*
+# include <oln/core/gen/ternary_fun.hh>
+# include <oln/core/level/ternary.hh>
+# include <oln/arith/ternary.hh>
+*/
+
+
+namespace oln
+{
+
+ namespace morpho
+ {
+
+ // Fwd decl.
+
+ template <typename I, typename W1, typename W2>
+ oln_plain(I)
+ thinning(const Image<I>& input,
+ const Window<W1>& B1, const Window<W2>& B2);
+
+
+# ifndef OLN_INCLUDE_ONLY
+
+ namespace impl
+ {
+
+ // Generic version.
+
+ template <typename I, typename W1, typename W2>
+ oln_plain(I)
+ thinning_on_function_(const Image<I>& f,
+ const Window<W1>& B1, const Window<W2>& B2)
+ {
+ oln_plain(I)
+ e = morpho::erosion(f, B1),
+ d = morpho::dilation(f, B2);
+
+ /*
+ oln_plain_value(I, bool) t;
+ t = d < f and f = e;
+ return level::ternary(t, d, f);
+ */
+
+ /*
+ oln_plain(I) o;
+ prepare(o, with, f);
+ level::fill( inplace(o),
+ ternary_fun( pw_value(d) < pw_value(f) and pw_value(f) = pw_value(e),
+ pw_value(d),
+ pw_value(f) ) );
+ return o;
+ */
+
+ oln_plain(I) o;
+ prepare(o, with, f);
+ oln_piter(I) p(f.points());
+ for_all(p)
+ o(p) = ( d(p) < f(p) and f(p) = e(p)
+ ? d(p)
+ : f(p) );
+ return o;
+ }
+
+ // FIXME: Add a fast version.
+
+
+ // Impl facade.
+
+ template <typename I, typename W1, typename W2>
+ oln_plain(I)
+ thinning_(const Image<I>& input,
+ const W1& B1, const W2& B2)
+ {
+ return thinning_on_function_(exact(input), B1, B2);
+ }
+
+// template <typename I, typename W1, typename W2>
+// oln_plain(I)
+// thinning_(const Binary_Image<I>& input,
+// const W1& B1, const W2& B2)
+// {
+// return thinning_on_set_(exact(input), B1, B2);
+// }
+
+
+ } // end of namespace oln::morpho::impl
+
+
+ // Facade.
+
+ template <typename I, typename W1, typename W2>
+ oln_plain(I)
+ thinning(const Image<I>& input,
+ const Window<W1>& B1, const Window<W2>& B2)
+ {
+ precondition(B1.is_centered());
+ oln_plain(I) output = impl::thinning_(exact(input), exact(B1), exact(B2));
+ postcondition(output <= input);
+ return output;
+ }
+
+# endif // ! OLN_INCLUDE_ONLY
+
+ } // end of namespace oln::morpho
+
+} // end of namespace oln
+
+
+#endif // ! OLN_MORPHO_THINNING_HH
Index: oln/morpho/elementary_gradient_internal.hh
--- oln/morpho/elementary_gradient_internal.hh (revision 973)
+++ oln/morpho/elementary_gradient_internal.hh (working copy)
@@ -74,7 +74,7 @@
elementary_gradient_internal(const Image_with_Nbh<I>& input)
{
oln_plain(I) output = impl::elementary_gradient_internal_(exact(input));
- postcondition(output >= zero);
+ postcondition(output >= oln_value(I)(zero));
return output;
}
Index: oln/morpho/elementary_gradient_external.hh
--- oln/morpho/elementary_gradient_external.hh (revision 973)
+++ oln/morpho/elementary_gradient_external.hh (working copy)
@@ -74,7 +74,7 @@
elementary_gradient_external(const Image_with_Nbh<I>& input)
{
oln_plain(I) output = impl::elementary_gradient_external_(exact(input));
- postcondition(output >= zero);
+ postcondition(output >= oln_value(I)(zero));
return output;
}
Index: oln/morpho/gradient_internal.hh
--- oln/morpho/gradient_internal.hh (revision 973)
+++ oln/morpho/gradient_internal.hh (working copy)
@@ -73,7 +73,7 @@
gradient_internal(const Image<I>& input, const Window<W>& win)
{
oln_plain(I) output = impl::gradient_internal_(exact(input), exact(win));
- postcondition(output >= zero);
+ postcondition(output >= oln_value(I)(zero));
return output;
}
Index: oln/morpho/gradient.hh
--- oln/morpho/gradient.hh (revision 973)
+++ oln/morpho/gradient.hh (working copy)
@@ -74,7 +74,7 @@
gradient(const Image<I>& input, const Window<W>& win)
{
oln_plain(I) output = impl::gradient_(exact(input), exact(win));
- postcondition(output >= zero);
+ postcondition(output >= oln_value(I)(zero));
return output;
}
Index: oln/morpho/gradient_external.hh
--- oln/morpho/gradient_external.hh (revision 973)
+++ oln/morpho/gradient_external.hh (working copy)
@@ -72,7 +72,7 @@
gradient_external(const Image<I>& input, const Window<W>& win)
{
oln_plain(I) output = impl::gradient_external_(exact(input), exact(win));
- postcondition(output >= zero);
+ postcondition(output >= oln_value(I)(zero));
return output;
}
Index: oln/arith/plus.hh
--- oln/arith/plus.hh (revision 973)
+++ oln/arith/plus.hh (working copy)
@@ -94,7 +94,7 @@
precondition(lhs.points() = rhs.points());
oln_plain_value(I, V) output;
prepare(output, with, lhs);
- level::fill(output,
+ level::fill(inplace(output),
value_cast<V>(pw_value(lhs) + pw_value(rhs)));
return output;
}
Index: oln/arith/minus.hh
--- oln/arith/minus.hh (revision 973)
+++ oln/arith/minus.hh (working copy)
@@ -90,7 +90,7 @@
precondition(lhs.points() = rhs.points());
oln_plain_value(I, V) output;
prepare(output, with, lhs);
- level::fill(output,
+ level::fill(inplace(output),
value_cast<V>(pw_value(lhs) - pw_value(rhs)));
return output;
}
Index: oln/level/local_sup.hh
--- oln/level/local_sup.hh (revision 973)
+++ oln/level/local_sup.hh (working copy)
@@ -68,7 +68,7 @@
const oln_point(I)& p)
{
f.init_with(input(p));
- oln_niter(I) n(input, p);
+ oln_niter(I) n(p, input);
for_all(n)
if (n > p)
f(input(n));
@@ -86,7 +86,7 @@
f.init_with(input(p));
if (f.value() = true)
return true;
- oln_niter(I) n(input, p);
+ oln_niter(I) n(p, input);
for_all(n)
if (n > p)
{
@@ -106,7 +106,7 @@
const oln_point(I)& p)
{
f.init_with(input(p));
- oln_niter(I) n(input, p);
+ oln_niter(I) n(p, input);
for_all(n)
if (n > p)
{
Index: oln/level/fill.hh
--- oln/level/fill.hh (revision 973)
+++ oln/level/fill.hh (working copy)
@@ -153,7 +153,8 @@
template <typename I, typename T>
void fill(const Image<I>&, const T&)
{
- mlc::abort_<I>::check(); // FIXME: Add err msg.
+ mlc::abort_< I,
+ ERROR::keyword_inplace_is_missing >::check();
}
# endif // ! OLN_INCLUDE_ONLY
Index: oln/level/compare.hh
--- oln/level/compare.hh (revision 973)
+++ oln/level/compare.hh (working copy)
@@ -30,11 +30,11 @@
# include <oln/core/concept/image.hh>
# include <oln/core/gen/pset_compare.hh>
+# include <oln/core/gen/value.hh>
// FIXME: Rename this file as "comparison.hh".
-
namespace oln
{
@@ -43,20 +43,29 @@
template <typename L, typename R>
bool operator = (const Image<L>& lhs, const Image<R>& rhs);
- template <typename I>
- bool operator = (const Image<I>& lhs, const oln_value(I)& val);
-
template <typename L, typename R>
bool operator < (const Image<L>& lhs, const Image<R>& rhs);
- template <typename I>
- bool operator < (const Image<I>& lhs, const oln_value(I)& val);
-
- template <typename L, typename R>
+ template <typename L, typename R> // required!
bool operator <= (const Image<L>& lhs, const Image<R>& rhs);
- template <typename I>
- bool operator <= (const Image<I>& lhs, const oln_value(I)& val);
+
+ // with a value:
+
+ template <typename I, typename V>
+ bool operator = (const Image<I>& lhs, const value_<V>& val);
+
+ template <typename I, typename V>
+ bool operator < (const Image<I>& lhs, const value_<V>& val);
+
+ template <typename I, typename V>
+ bool operator <= (const Image<I>& lhs, const value_<V>& val);
+
+ template <typename I, typename V>
+ bool operator > (const Image<I>& lhs, const value_<V>& val);
+
+ template <typename I, typename V>
+ bool operator >= (const Image<I>& lhs, const value_<V>& val);
// FIXME: is-it a good idea to have "ima = lit"?
@@ -74,98 +83,109 @@
// Generic version.
template <typename L, typename R>
- bool op_eq_(const Image<L>& lhs, const Image<R>& rhs)
+ bool operator_equal_(const Image<L>& lhs, const Image<R>& rhs)
{
- precondition(lhs.points() = rhs.points());
oln_piter(L) p(lhs.points());
for_all(p)
- if (lhs(p) != rhs(p))
+ if (not (lhs(p) = rhs(p)))
return false;
return true;
}
- // Image I = Value V
- // ----------------------
+ // Image L < Image R
+ // ---------------------
// Generic version.
- template <typename I>
- bool op_eq_(const Image<I>& lhs, const oln_value(I)& val)
+ template <typename L, typename R>
+ bool operator_less_(const Image<L>& lhs, const Image<R>& rhs)
{
- oln_piter(I) p(lhs.points());
+ oln_piter(L) p(lhs.points());
for_all(p)
- if (lhs(p) != val)
+ if (not (lhs(p) < rhs(p)))
return false;
return true;
}
- // Image L < Image R
- // ---------------------
+ // Image L <= Image R
+ // ----------------------
// Generic version.
template <typename L, typename R>
- bool op_less_(const Image<L>& lhs, const Image<R>& rhs)
+ bool operator_less_or_equal_(const Image<L>& lhs, const Image<R>& rhs)
{
- precondition(lhs.points() = rhs.points());
oln_piter(L) p(lhs.points());
for_all(p)
- if (lhs(p) >= rhs(p))
+ if (not (lhs(p) <= rhs(p)))
return false;
return true;
}
- // Image I < Value V
- // ---------------------
+ // Image I = Value V
+ // ----------------------
// Generic version.
template <typename I>
- bool op_less_(const Image<I>& lhs, const oln_value(I)& val)
+ bool operator_image_equal_to_value_(const Image<I>& lhs,
+ const oln_value(I)& val)
{
oln_piter(I) p(lhs.points());
for_all(p)
- if (lhs(p) >= val)
+ if (not (lhs(p) = val))
return false;
return true;
}
- // Image L <= Image R
- // ----------------------
+ // Image I cmp Value V
+ // -----------------------
- // Generic version.
+ // Generic versions.
- template <typename L, typename R>
- bool op_leq_(const Image<L>& lhs, const Image<R>& rhs)
+ template <typename I>
+ bool operator_image_less_than_value_(const Image<I>& lhs, const oln_value(I)& val)
{
- precondition(lhs.points() = rhs.points());
- oln_piter(L) p(lhs.points());
+ oln_piter(I) p(lhs.points());
for_all(p)
- if (lhs(p) > rhs(p))
+ if (not (lhs(p) < val))
return false;
return true;
}
-
- // Image I <= Value V
- // ----------------------
-
- // Generic version.
+ template <typename I>
+ bool operator_image_less_or_equal_than_value_(const Image<I>& lhs, const oln_value(I)& val)
+ {
+ oln_piter(I) p(lhs.points());
+ for_all(p)
+ if (not (lhs(p) <= val))
+ return false;
+ return true;
+ }
template <typename I>
- bool op_leq_(const Image<I>& lhs, const oln_value(I)& val)
+ bool operator_image_greater_than_value_(const Image<I>& lhs, const oln_value(I)& val)
{
oln_piter(I) p(lhs.points());
for_all(p)
- if (lhs(p) > val)
+ if (not (lhs(p) > val))
return false;
return true;
}
+ template <typename I>
+ bool operator_image_greater_or_equal_than_value_(const Image<I>& lhs, const oln_value(I)& val)
+ {
+ oln_piter(I) p(lhs.points());
+ for_all(p)
+ if (not (lhs(p) >= val))
+ return false;
+ return true;
+ }
} // end of namespace oln::level::impl
@@ -176,39 +196,62 @@
bool operator = (const Image<L>& lhs, const Image<R>& rhs)
{
assert_same_grid_<L, R>::check();
- return impl::op_eq_(exact(lhs), exact(rhs));
+ precondition(lhs.points() = rhs.points());
+ return impl::operator_equal_(exact(lhs), exact(rhs));
}
- template <typename I>
- bool operator = (const Image<I>& lhs, const oln_value(I)& val)
+ template <typename L, typename R>
+ bool operator < (const Image<L>& lhs, const Image<R>& rhs)
{
- return impl::op_eq_(exact(lhs), val);
+ assert_same_grid_<L, R>::check();
+ precondition(lhs.points() = rhs.points());
+ return impl::operator_less_(exact(lhs), exact(rhs));
}
template <typename L, typename R>
- bool operator < (const Image<L>& lhs, const Image<R>& rhs)
+ bool operator <= (const Image<L>& lhs, const Image<R>& rhs)
{
assert_same_grid_<L, R>::check();
- return impl::op_less_(exact(lhs), exact(rhs));
+ precondition(lhs.points() = rhs.points());
+ return impl::operator_less_or_equal_(exact(lhs), exact(rhs));
}
- template <typename I>
- bool operator < (const Image<I>& lhs, const oln_value(I)& val)
+
+ // with a value:
+
+ template <typename I, typename V>
+ bool operator = (const Image<I>& lhs, const value_<V>& val)
{
- return impl::op_less_(exact(lhs), val);
+ // FIXME: insert static assertion?
+ return impl::operator_image_equal_to_value_(exact(lhs), val.unwrap());
}
- template <typename L, typename R>
- bool operator <= (const Image<L>& lhs, const Image<R>& rhs)
+ template <typename I, typename V>
+ bool operator < (const Image<I>& lhs, const value_<V>& val)
{
- assert_same_grid_<L, R>::check();
- return impl::op_leq_(exact(lhs), exact(rhs));
+ // FIXME: insert static assertion?
+ return impl::operator_image_less_than_value_(exact(lhs), val.unwrap());
}
- template <typename I>
- bool operator <= (const Image<I>& lhs, const oln_value(I)& val)
+ template <typename I, typename V>
+ bool operator <= (const Image<I>& lhs, const value_<V>& val)
+ {
+ // FIXME: insert static assertion?
+ return impl::operator_image_less_or_equal_than_value_(exact(lhs), val.unwrap());
+ }
+
+ template <typename I, typename V>
+ bool operator > (const Image<I>& lhs, const value_<V>& val)
+ {
+ // FIXME: insert static assertion?
+ return impl::operator_image_greater_than_value_(exact(lhs), val.unwrap());
+ }
+
+ template <typename I, typename V>
+ bool operator >= (const Image<I>& lhs, const value_<V>& val)
{
- return impl::op_leq_(exact(lhs), val);
+ // FIXME: insert static assertion?
+ return impl::operator_image_greater_or_equal_than_value_(exact(lhs), val.unwrap());
}
# endif // ! OLN_INCLUDE_ONLY
Index: oln/level/local_inf.hh
--- oln/level/local_inf.hh (revision 973)
+++ oln/level/local_inf.hh (working copy)
@@ -68,7 +68,7 @@
const oln_point(I)& p)
{
f.init_with(input(p));
- oln_niter(I) n(input, p);
+ oln_niter(I) n(p, input);
for_all(n)
if (n < p)
f(input(n));
@@ -86,7 +86,7 @@
f.init_with(input(p));
if (f.value() = true)
return true;
- oln_niter(I) n(input, p);
+ oln_niter(I) n(p, input);
for_all(n)
if (n < p)
{
@@ -106,7 +106,7 @@
const oln_point(I)& p)
{
f.init_with(input(p));
- oln_niter(I) n(input, p);
+ oln_niter(I) n(p, input);
for_all(n)
if (n < p)
{
Index: oln/value/gray_level.hh
--- oln/value/gray_level.hh (revision 0)
+++ oln/value/gray_level.hh (revision 0)
@@ -0,0 +1,360 @@
+// Copyright (C) 2006, 2007 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#ifndef OLN_VALUE_GRAY_LEVEL_HH
+# define OLN_VALUE_GRAY_LEVEL_HH
+
+# include <iostream>
+# include <oln/core/concept/operators.hh>
+# include <oln/core/internal/value_base.hh>
+# include <mlc/int.hh>
+
+
+// FIXME: Move!
+# include <oln/value/mlc_extra.hh>
+
+
+namespace oln
+{
+
+ namespace value
+ {
+
+ namespace internal
+ {
+
+ template <typename T> T format(T t) { return t; }
+ unsigned format(unsigned char t) { return t; }
+
+
+ template <unsigned nbits> struct encoding_;
+
+ template <> struct encoding_ <1> { typedef bool ret; };
+
+ template <> struct encoding_ <2> { typedef unsigned char ret; };
+ template <> struct encoding_ <3> { typedef unsigned char ret; };
+ template <> struct encoding_ <4> { typedef unsigned char ret; };
+ template <> struct encoding_ <5> { typedef unsigned char ret; };
+ template <> struct encoding_ <6> { typedef unsigned char ret; };
+ template <> struct encoding_ <7> { typedef unsigned char ret; };
+ template <> struct encoding_ <8> { typedef unsigned char ret; };
+
+ template <> struct encoding_ < 9> { typedef unsigned short ret; };
+ template <> struct encoding_ <10> { typedef unsigned short ret; };
+ template <> struct encoding_ <11> { typedef unsigned short ret; };
+ template <> struct encoding_ <12> { typedef unsigned short ret; };
+ template <> struct encoding_ <13> { typedef unsigned short ret; };
+ template <> struct encoding_ <14> { typedef unsigned short ret; };
+ template <> struct encoding_ <15> { typedef unsigned short ret; };
+ template <> struct encoding_ <16> { typedef unsigned short ret; };
+
+ template <> struct encoding_ <32> { typedef unsigned long ret; };
+
+ } // end of oln::value::internal
+
+
+ // Fwd decls.
+ template <unsigned N> class gray_level;
+ class gray;
+
+
+ } // end of namespace oln::value
+
+
+ /// \{
+ /// Aliases.
+
+ typedef value::gray_level<8> gl8;
+ typedef value::gray_level<16> gl16;
+ typedef value::gray_level<32> gl32;
+
+ /// \}
+
+
+# define current gray_level<N>
+# define super oln::internal::graylevel_value_< oln::value::current >
+
+ // Super type.
+
+ template <unsigned N>
+ struct super_trait_< value::current >
+ {
+ typedef super ret;
+ };
+
+ // Virtual types.
+
+ template <unsigned N>
+ struct vtypes< value::current >
+ {
+ typedef typename value::internal::encoding_<N>::ret encoding;
+ typedef mlc::uint_<N> nbits;
+ };
+
+
+ namespace value
+ {
+
+ /// General gray-level class on n bits.
+ template <unsigned N>
+ class gray_level : public super
+ {
+ public:
+ stc_using(encoding);
+
+ // Ctors.
+ gray_level();
+
+ // In oln/value/gray.hh:
+ gray_level(const gray& g);
+ gray_level<N>& operator=(const gray& val);
+ operator gray() const;
+
+ // Access to encoding value.
+ const encoding& enc() const;
+ encoding& enc();
+
+ // Conversions.
+ operator float() const;
+ operator double() const;
+
+ protected:
+ encoding val_;
+ };
+
+
+ // Op<<.
+ template <unsigned N>
+ std::ostream& operator<<(std::ostream& ostr, const gray_level<N>& g);
+
+
+ template <unsigned N>
+ bool operator=(const gray_level<N>& lhs, const gray_level<N>& rhs);
+
+ template <unsigned N, unsigned M>
+ bool operator=(const gray_level<N>& lhs, const gray_level<M>& rhs);
+
+
+ template <unsigned N>
+ bool operator<(const gray_level<N>& lhs, const gray_level<N>& rhs);
+
+ template <unsigned N, unsigned M>
+ bool operator<(const gray_level<N>& lhs, const gray_level<M>& rhs);
+
+
+ // -> gray
+
+ template <unsigned N, unsigned M>
+ gray operator+(const gray_level<N>& lhs, const gray_level<M>& rhs);
+
+ template <unsigned N, unsigned M>
+ gray operator-(const gray_level<N>& lhs, const gray_level<M>& rhs);
+
+ template <unsigned N>
+ gray operator*(int s, const gray_level<N>& rhs);
+
+ template <unsigned N>
+ gray operator*(const gray_level<N>& lhs, int s);
+
+ template <unsigned N>
+ gray operator/(const gray_level<N>& lhs, int s);
+
+
+
+
+# ifndef OLN_INCLUDE_ONLY
+
+ template <unsigned N>
+ current::gray_level()
+ {
+ }
+
+ template <unsigned N>
+ const typename current::encoding&
+ current::enc() const
+ {
+ return this->val_;
+ }
+
+ template <unsigned N>
+ typename current::encoding&
+ current::enc()
+ {
+ return this->val_;
+ }
+
+ template <unsigned N>
+ current:: operator float() const
+ {
+ static const float coef_
+ = 1.f / float(mlc::math::two_pow_<N>::value - 1.f);
+ return coef_ * this->val_;
+ }
+
+ template <unsigned N>
+ current::operator double() const
+ {
+ static const double coef_
+ = 1. / double(mlc::math::two_pow_<N>::value - 1.);
+ return coef_ * this->val_;
+ }
+
+ template <unsigned N>
+ std::ostream& operator<<(std::ostream& ostr, const gray_level<N>& g)
+ {
+ return ostr << internal::format( g.enc() )
+ << "[/" << N << ']';
+ }
+
+
+ template <unsigned N>
+ bool operator=(const gray_level<N>& lhs, const gray_level<N>& rhs)
+ {
+ return lhs.enc() = rhs.enc();
+ }
+
+ template <unsigned N, unsigned M>
+ bool operator=(const gray_level<N>& lhs, const gray_level<M>& rhs)
+ {
+ return
+ mlc::math::two_pow_<M>::value * lhs.enc()
+ = mlc::math::two_pow_<N>::value * rhs.enc();
+ // FIXME: return gray(lhs) = gray(rhs);
+ }
+
+
+ template <unsigned N>
+ bool operator<(const gray_level<N>& lhs, const gray_level<N>& rhs)
+ {
+ return lhs.enc() < rhs.enc();
+ }
+
+ template <unsigned N, unsigned M>
+ bool operator<(const gray_level<N>& lhs, const gray_level<M>& rhs)
+ {
+ return
+ mlc::math::two_pow_<M>::value * lhs.enc()
+ < mlc::math::two_pow_<N>::value * rhs.enc();
+ // FIXME: return gray(lhs) < gray(rhs);
+ }
+
+ /*
+
+ template <unsigned N>
+ gray_level<N>::operator gray() const
+ {
+ gray tmp(N, this->val_);
+ return tmp;
+ }
+
+ template <unsigned N, unsigned M>
+ gray operator+(const gray_level<N>& lhs, const gray_level<M>& rhs)
+ {
+ return gray(lhs) + gray(rhs);
+ }
+
+ template <unsigned N, unsigned M>
+ gray operator-(const gray_level<N>& lhs, const gray_level<M>& rhs)
+ {
+ return gray(lhs) - gray(rhs);
+ }
+
+ template <unsigned N>
+ gray operator*(int s, const gray_level<N>& rhs)
+ {
+ precondition(s >= 0);
+ gray tmp(N, s * rhs.enc());
+ return tmp;
+ }
+
+ template <unsigned N>
+ gray operator*(const gray_level<N>& lhs, int s)
+ {
+ precondition(s >= 0);
+ gray tmp(N, lhs.enc() * s);
+ return tmp;
+ }
+
+ template <unsigned N>
+ gray operator/(const gray_level<N>& lhs, int s)
+ {
+ precondition(s > 0);
+ gray tmp(N, lhs.enc() / s);
+ return tmp;
+ }
+
+ */
+
+# endif // ! OLN_INCLUDE_ONLY
+
+ } // end of namespace oln::value
+
+# undef super
+# undef current
+
+} // end of namespace oln
+
+
+/*
+
+namespace xtd
+{
+
+ using oln::value::gray;
+
+ template <> struct set_trait_<op_plus, gray, gray> { typedef gray ret; };
+ template <> struct set_trait_<op_minus, gray, gray> { typedef gray ret; };
+ template <> struct set_trait_<op_mult, int, gray> { typedef gray ret; };
+ template <> struct set_trait_<op_mult, gray, int > { typedef gray ret; };
+ template <> struct set_trait_<op_div, gray, int > { typedef gray ret; };
+
+ using oln::value::gray_level;
+
+ template <unsigned N, unsigned M>
+ struct set_trait_< op_plus, gray_level<N>, gray_level<M> > { typedef gray ret; };
+
+ template <unsigned N, unsigned M>
+ struct set_trait_< op_minus, gray_level<N>, gray_level<M> > { typedef gray ret; };
+
+ template <unsigned N>
+ struct set_trait_< op_mult, int, gray_level<N> > { typedef gray ret; };
+
+ template <unsigned N>
+ struct set_trait_< op_mult, gray_level<N>, int > { typedef gray ret; };
+
+ template <unsigned N>
+ struct set_trait_< op_div, gray_level<N>, int > { typedef gray ret; };
+
+} // end of namespace xtd
+
+*/
+
+
+# include <oln/value/gray.hh>
+
+
+#endif // ! OLN_VALUE_GRAY_LEVEL_HH
Index: oln/value/bool.hh
--- oln/value/bool.hh (revision 0)
+++ oln/value/bool.hh (revision 0)
@@ -0,0 +1,55 @@
+// Copyright (C) 2007 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#ifndef OLN_VALUE_BOOL_HH
+# define OLN_VALUE_BOOL_HH
+
+# include <oln/core/internal/value_base.hh>
+
+
+namespace oln
+{
+
+ // Super type.
+ template<>
+ struct super_trait_< bool >
+ {
+ typedef internal::boolean_value_< bool > ret;
+ };
+
+ // Virtual types.
+ template <>
+ struct vtypes< bool >
+ {
+ typedef bool encoding;
+ // FIXME: ...
+ };
+
+} // end of namespace oln
+
+
+#endif // ! OLN_VALUE_BOOL_HH
Index: oln/value/builtin_traits.hh
--- oln/value/builtin_traits.hh (revision 973)
+++ oln/value/builtin_traits.hh (working copy)
@@ -32,45 +32,41 @@
# include <oln/core/gen/traits.hh>
-namespace oln
-{
-
- template <typename Op>
- struct set_trait_< Value, int, Op, Value, float >
- {
- typedef float ret;
- };
+# define oln_decl_builtin_binary_trait(T1, T2, R) \
+ \
+ template <typename Op> \
+ struct set_trait_< Value, T1, Op, Value, T2 > { typedef R ret; }; \
+ \
+ template <typename Op> \
+ struct set_trait_< Value, T2, Op, Value, T1 > { typedef R ret; }; \
+ \
+ struct e_n_d___w_i_t_h___s_e_m_i_c_o_l_u_m_n
- template <typename Op>
- struct set_trait_< Value, double, Op, Value, double >
- {
- typedef double ret;
- };
- template <typename Op>
- struct set_trait_< Value, int, Op, Value, double >
- {
- typedef double ret;
- };
-
- template <typename Op>
- struct set_trait_< Value, float, Op, Value, int >
+namespace oln
{
- typedef float ret;
- };
+ oln_decl_builtin_binary_trait(unsigned char, float, float);
+ oln_decl_builtin_binary_trait(unsigned short, float, float);
+ oln_decl_builtin_binary_trait(unsigned int, float, float);
+ oln_decl_builtin_binary_trait(unsigned long, float, float);
+
+ oln_decl_builtin_binary_trait(signed char, float, float);
+ oln_decl_builtin_binary_trait(signed short, float, float);
+ oln_decl_builtin_binary_trait(signed int, float, float);
+ oln_decl_builtin_binary_trait(signed long, float, float);
+
+ oln_decl_builtin_binary_trait(unsigned char, double, double);
+ oln_decl_builtin_binary_trait(unsigned short, double, double);
+ oln_decl_builtin_binary_trait(unsigned int, double, double);
+ oln_decl_builtin_binary_trait(unsigned long, double, double);
+
+ oln_decl_builtin_binary_trait(signed char, double, double);
+ oln_decl_builtin_binary_trait(signed short, double, double);
+ oln_decl_builtin_binary_trait(signed int, double, double);
+ oln_decl_builtin_binary_trait(signed long, double, double);
- template <typename Op>
- struct set_trait_< Value, bool, Op, Value, bool >
- {
- typedef bool ret;
- };
-
- template <typename Op>
- struct set_utrait_< Op, Boolean, bool >
- {
- typedef bool ret;
- };
+ oln_decl_builtin_binary_trait(float, double, double);
// FIXME: To be continued...
Index: oln/value/gray.hh
--- oln/value/gray.hh (revision 0)
+++ oln/value/gray.hh (revision 0)
@@ -0,0 +1,420 @@
+// Copyright (C) 2006, 2007 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#ifndef OLN_VALUE_GRAY_HH
+# define OLN_VALUE_GRAY_HH
+
+# include <iostream>
+# include <oln/value/gray_level.hh>
+
+
+
+namespace oln
+{
+
+ // Fwd decls.
+ namespace value
+ {
+ template <unsigned N> class gray_level;
+ class gray;
+ }
+
+ // Super type.
+
+ template <>
+ struct super_trait_< value::gray >
+ {
+ typedef oln::internal::graylevel_value_< value::gray > ret;
+ };
+
+ // Virtual types.
+
+ template <>
+ struct vtypes< value::gray >
+ {
+ typedef unsigned long encoding; // FIXME: std::pair?
+ typedef mlc::uint_<0> nbits; // FIXME: means unknown?
+ };
+
+
+ namespace value
+ {
+
+
+ /// General gray-level class where n bits is not know at compile-time.
+ /// This class is used for exchange between gray-level types purpose.
+
+ class gray : public oln::internal::graylevel_value_< gray >
+ {
+ public:
+
+ /// Ctor.
+ gray();
+
+ /// Ctor.
+ template <unsigned N>
+ gray(const gray_level<N>& val);
+
+ /// Ctor.
+ gray(unsigned nbits, unsigned long val);
+
+ /// Access to std type.
+ unsigned long value() const;
+
+ unsigned nbits() const;
+
+ void set_nbits(unsigned nbits);
+
+ gray to_nbits(unsigned nbits) const;
+
+ template <unsigned N>
+ operator gray_level<N>() const;
+
+ protected:
+ unsigned nbits_;
+ unsigned long val_;
+ };
+
+
+ std::ostream& operator<<(std::ostream& ostr, const gray& g);
+
+ bool operator=(const gray& lhs, const gray& rhs);
+ bool operator<(const gray& lhs, const gray& rhs);
+
+ gray operator+(const gray& lhs, const gray& rhs);
+ gray operator-(const gray& lhs, const gray& rhs);
+
+ gray operator*(int s, const gray& rhs);
+ gray operator*(const gray& lhs, int s);
+
+ gray operator/(const gray& lhs, int s);
+
+
+
+
+# ifndef OLN_INCLUDE_ONLY
+
+ template <unsigned N, unsigned M>
+ gray operator+(const gray_level<N>& lhs, const gray_level<M>& rhs)
+ {
+ return gray(lhs) + gray(rhs);
+ }
+
+ template <unsigned N, unsigned M>
+ gray operator-(const gray_level<N>& lhs, const gray_level<M>& rhs)
+ {
+ return gray(lhs) - gray(rhs);
+ }
+
+ template <unsigned N>
+ gray operator*(int s, const gray_level<N>& rhs)
+ {
+ precondition(s >= 0);
+ gray tmp(N, s * rhs.value());
+ return tmp;
+ }
+
+ template <unsigned N>
+ gray operator*(const gray_level<N>& lhs, int s)
+ {
+ precondition(s >= 0);
+ gray tmp(N, lhs.value() * s);
+ return tmp;
+ }
+
+ template <unsigned N>
+ gray operator/(const gray_level<N>& lhs, int s)
+ {
+ precondition(s > 0);
+ gray tmp(N, lhs.value() / s);
+ return tmp;
+ }
+
+
+
+ // Gray.
+
+ gray::gray()
+ : nbits_(0)
+ {
+ }
+
+ template <unsigned n>
+ gray::gray(const gray_level<n>& g)
+ : nbits_(n),
+ val_(g.value())
+ {
+ }
+
+ gray::gray(unsigned nbits, unsigned long val)
+ : nbits_(nbits),
+ val_(val)
+ {
+ }
+
+ unsigned long gray::value() const
+ {
+ invariant(nbits_ != 0);
+ return val_;
+ }
+
+ unsigned gray::nbits() const
+ {
+ return nbits_;
+ }
+
+ namespace internal
+ {
+
+ unsigned long two_pow_(unsigned n)
+ {
+ if (n = 0)
+ return 1;
+ else
+ return 2 * two_pow_(n - 1);
+ }
+
+ unsigned long two_pow_n_minus_1(unsigned n)
+ {
+ return two_pow_(n) - 1;
+ }
+
+ template <unsigned n_dest>
+ unsigned long convert(unsigned n_src, unsigned long val)
+ {
+ if (n_dest = n_src)
+ return val;
+ else
+ if (n_dest > n_src)
+ return val * two_pow_n_minus_1(n_dest) / two_pow_n_minus_1(n_src);
+ else
+ return val / two_pow_(n_src - n_dest);
+ }
+
+ } // end of oln::value::internal
+
+
+ void gray::set_nbits(unsigned nbits)
+ {
+ precondition(nbits != 0);
+ invariant(nbits_ != 0);
+ if (nbits = nbits_)
+ return;
+ if (nbits > nbits_)
+ {
+ val_ *= internal::two_pow_n_minus_1(nbits);
+ val_ /= internal::two_pow_n_minus_1(nbits_);
+ }
+ else // nbits < nbits_
+ {
+ val_ /= internal::two_pow_(nbits_ - nbits);
+ }
+ nbits_ = nbits;
+ }
+
+
+ gray gray::to_nbits(unsigned nbits) const
+ {
+ precondition(nbits != 0);
+ invariant(nbits_ != 0);
+ gray tmp(*this);
+ tmp.set_nbits(nbits);
+ return tmp;
+ }
+
+
+ template <unsigned n>
+ gray::operator gray_level<n>() const
+ {
+ precondition(nbits_ != 0);
+ gray_level<n> tmp(internal::convert<n>(nbits_, val_));
+ assert(tmp.value() < internal::two_pow_(n));
+ return tmp;
+ }
+
+ // operators
+
+ std::ostream& operator<<(std::ostream& ostr, const gray& g)
+ {
+ return ostr << g.value() << '/' << g.nbits() << "nbits";
+ }
+
+ bool operator=(const gray& lhs, const gray& rhs)
+ {
+ precondition(lhs.nbits() != 0 and rhs.nbits() != 0);
+ if (rhs.nbits() = lhs.nbits())
+ return lhs.value() = rhs.value();
+ if (lhs.nbits() > rhs.nbits())
+ return lhs.value() = rhs.to_nbits(lhs.nbits()).value();
+ else
+ return lhs.to_nbits(rhs.nbits()).value() = rhs.value();
+ }
+
+ bool operator<(const gray& lhs, const gray& rhs)
+ {
+ precondition(lhs.nbits() != 0 and rhs.nbits() != 0);
+ if (rhs.nbits() = lhs.nbits())
+ return lhs.value() < rhs.value();
+ if (lhs.nbits() > rhs.nbits())
+ return lhs.value() < rhs.to_nbits(lhs.nbits()).value();
+ else
+ return lhs.to_nbits(rhs.nbits()).value() < rhs.value();
+ }
+
+ gray operator+(const gray& lhs, const gray& rhs)
+ {
+ precondition(lhs.nbits() != 0 and rhs.nbits() != 0);
+ if (lhs.nbits() > rhs.nbits())
+ {
+ gray tmp(lhs.nbits(),
+ lhs.value() + rhs.to_nbits(lhs.nbits()).value());
+ return tmp;
+ }
+ else
+ {
+ gray tmp(rhs.nbits(),
+ lhs.to_nbits(rhs.nbits()).value() + rhs.value());
+ return tmp;
+ }
+ }
+
+ gray operator-(const gray& lhs, const gray& rhs)
+ {
+ precondition(lhs.nbits() != 0 and rhs.nbits() != 0);
+ if (lhs.nbits() > rhs.nbits())
+ {
+ unsigned long l = rhs.to_nbits(lhs.nbits()).value();
+ assert(lhs.value() >= l);
+ gray tmp(lhs.nbits(),
+ lhs.value() - l);
+ return tmp;
+ }
+ else
+ {
+ unsigned long l = lhs.to_nbits(rhs.nbits()).value();
+ assert(l >= rhs.value());
+ gray tmp(rhs.nbits(),
+ l - rhs.value());
+ return tmp;
+ }
+ }
+
+ gray operator*(int s, const gray& rhs)
+ {
+ precondition(s >= 0);
+ gray tmp(rhs.nbits(), rhs.value() * s);
+ return tmp;
+ }
+
+ gray operator*(const gray& lhs, int s)
+ {
+ precondition(s >= 0);
+ gray tmp(lhs.nbits(), lhs.value() * s);
+ return tmp;
+ }
+
+ gray operator/(const gray& lhs, int s)
+ {
+ precondition(s > 0);
+ gray tmp(lhs.nbits(), lhs.value() / s);
+ return tmp;
+ }
+
+ template <unsigned N>
+ gray_level<N>&
+ gray_level<N>::operator=(const gray& g)
+ {
+ precondition(g.nbits() = N);
+ assert(g.value() < internal::two_pow_(N));
+ this->val = g.value(); // FIXME: Add static_cast.
+ }
+
+# endif // ! OLN_INCLUDE_ONLY
+
+ /*
+
+ template <unsigned N, unsigned M>
+ bool operator=(const gray_level<N>& lhs, const gray_level<M>& rhs);
+
+ template <unsigned N, unsigned M>
+ gray operator+(const gray_level<N>& lhs, const gray_level<M>& rhs);
+
+ template <unsigned N, unsigned M>
+ gray operator-(const gray_level<N>& lhs, const gray_level<M>& rhs);
+
+ template <unsigned N>
+ gray operator*(int s, const gray_level<N>& rhs);
+
+ template <unsigned N>
+ gray operator*(const gray_level<N>& lhs, int s);
+
+ template <unsigned N>
+ gray operator/(const gray_level<N>& lhs, int s);
+
+ */
+
+ } // end of namespace oln::value
+
+} // end of namespace oln
+
+
+/*
+
+namespace xtd
+{
+
+ using oln::value::gray;
+
+ template <> struct set_trait_<op_plus, gray, gray> { typedef gray ret; };
+ template <> struct set_trait_<op_minus, gray, gray> { typedef gray ret; };
+ template <> struct set_trait_<op_mult, int, gray> { typedef gray ret; };
+ template <> struct set_trait_<op_mult, gray, int > { typedef gray ret; };
+ template <> struct set_trait_<op_div, gray, int > { typedef gray ret; };
+
+ using oln::value::gray_level;
+
+ template <unsigned nbits, unsigned M>
+ struct set_trait_< op_plus, gray_level<nbits>, gray_level<M> > { typedef gray ret; };
+
+ template <unsigned nbits, unsigned M>
+ struct set_trait_< op_minus, gray_level<nbits>, gray_level<M> > { typedef gray ret; };
+
+ template <unsigned nbits>
+ struct set_trait_< op_mult, int, gray_level<nbits> > { typedef gray ret; };
+
+ template <unsigned nbits>
+ struct set_trait_< op_mult, gray_level<nbits>, int > { typedef gray ret; };
+
+ template <unsigned nbits>
+ struct set_trait_< op_div, gray_level<nbits>, int > { typedef gray ret; };
+
+} // end of namespace xtd
+
+*/
+
+
+#endif // ! OLN_VALUE_GRAY_HH
Index: oln/value/builtin.hh
--- oln/value/builtin.hh (revision 973)
+++ oln/value/builtin.hh (working copy)
@@ -28,84 +28,59 @@
#ifndef OLN_VALUE_BUILTIN_HH
# define OLN_VALUE_BUILTIN_HH
-# include <oln/core/concept/value.hh>
+# include <oln/core/internal/value_base.hh>
namespace oln
{
+ // int
- // Fwd decl.
- namespace internal { template <typename Exact> struct builtin_base; }
-
-
- // Virtual types.
- template <typename Exact>
- struct vtypes< internal::builtin_base<Exact> >
+ template <>
+ struct super_trait_< int >
{
- typedef stc::final< stc::is<Value> > category;
+ typedef internal::data_value_<int> ret;
};
-
- namespace internal
- {
-
- // Base class for builtin types.
- template <typename Exact>
- struct builtin_base : public Value<Exact>
+ template <>
+ struct vtypes< int >
{
- protected:
- builtin_base();
};
-# ifndef OLN_INCLUDE_ONLY
-
- template <typename Exact>
- builtin_base<Exact>::builtin_base()
- {
- }
-
-# endif // ! OLN_INCLUDE_ONLY
-
- } // end of namespace oln::internal
-
-
-
- // unsigned, int, float, double,...
+ // float
template <>
- struct super_trait_< unsigned >
+ struct super_trait_< float >
{
- typedef internal::builtin_base<unsigned> ret;
+ typedef internal::data_value_<float> ret;
};
template <>
- struct super_trait_< int >
+ struct vtypes< float >
{
- typedef internal::builtin_base<int> ret;
};
+
+ // double
+
template <>
- struct super_trait_< float >
+ struct super_trait_< double >
{
- typedef internal::builtin_base<float> ret;
+ typedef internal::data_value_<double> ret;
};
template <>
- struct super_trait_< double >
+ struct vtypes< double >
{
- typedef internal::builtin_base<double> ret;
};
-
+ // FIXME: To be continued...
} // end of namespace oln
-// FIXME: Bad?
# include <oln/value/builtin_traits.hh>
#endif // ! OLN_VALUE_BUILTIN_HH
-
Index: oln/value/black.hh
--- oln/value/black.hh (revision 0)
+++ oln/value/black.hh (revision 0)
@@ -0,0 +1,91 @@
+// Copyright (C) 2007 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#ifndef OLN_CORE_VALUE_ZERO_HH
+# define OLN_CORE_VALUE_ZERO_HH
+
+# include <oln/core/concept/literal.hh>
+
+
+namespace oln
+{
+
+ struct black_t : public Literal< black_t >
+ {
+
+ template <typename T>
+ operator T() const;
+
+ // builtins:
+ operator unsigned() const;
+ operator int() const;
+ operator float() const;
+ operator double() const;
+ }
+
+ black;
+
+
+
+ // Default unary minus operator.
+
+ template <typename T>
+ T
+ operator - (const Any<T>& rhs); // Use binary -.
+
+
+
+# ifndef OLN_INCLUDE_ONLY
+
+ template <typename T>
+ black_t::operator T() const
+ {
+ mlc::assert_< mlc_is_a(T, Any) >::check(); // FIXME: Add err msg.
+ T tmp;
+ tmp.assign_(*this);
+ return tmp;
+ }
+
+ black_t::operator unsigned() const { return 0u; }
+ black_t::operator int() const { return 0; }
+ black_t::operator float() const { return 0.f; }
+ black_t::operator double() const { return 0.; }
+
+
+ template <typename T>
+ T
+ operator - (const Any<T>& rhs)
+ {
+ return black - exact(rhs);
+ }
+
+# endif // ! OLN_INCLUDE_ONLY
+
+} // end of namespace oln
+
+
+#endif // ! OLN_CORE_VALUE_BLACK_HH
Index: oln/value/mlc_extra.hh
--- oln/value/mlc_extra.hh (revision 0)
+++ oln/value/mlc_extra.hh (revision 0)
@@ -0,0 +1,76 @@
+// Copyright (C) 2007 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#ifndef OLN_VALUE_MLC_EXTRA_HH
+# define OLN_VALUE_MLC_EXTRA_HH
+
+
+
+namespace mlc
+{
+ namespace math
+ {
+
+ template <int X, unsigned N>
+ struct pow_
+ {
+ enum { value = X * pow_<X, N-1>::value };
+ };
+
+ template <int X>
+ struct pow_< X, 0 >
+ {
+ enum { value = 1 };
+ };
+
+ template <>
+ struct pow_< 0, 0 >
+ {
+ enum { value = 1 };
+ };
+
+ template <unsigned N>
+ struct pow_< 0, N >
+ {
+ enum { value = 0 };
+ };
+
+
+ template <unsigned N>
+ struct two_pow_ : public pow_<2, N>
+ {
+ };
+
+
+ } // end of namespace mlc::math
+
+} // end of namespace mlc
+
+
+
+#endif // ! OLN_VALUE_MLC_EXTRA_HH
+
1
0