Olena-patches
Threads by month
- ----- 2025 -----
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- 9625 discussions
04 Apr '05
Index: ChangeLog
from Damien Thivolle <damien(a)lrde.epita.fr>
* oln/convert/ng_to_se.hh: Convert a neighborhood to a structuring
element.
* oln/core/value_box.hh: Fix operator==.
* oln/core/properties.hh: Add window property.
* oln/core/abstract/struct_elt.hh: Add operator-.
* oln/core/abstract/witer.hh (nth): Add method.
* oln/core/abstract/dpoint.hh (nth): Add method.
* oln/core/abstract/neighborhood.hh: Add a window property.
* oln/core/2d/dpoint2d.hh (nth): Add method.
* oln/core/2d/neighborhood2d.hh: Add a window property.
* oln/core/2d/fwd_witer2d.hh: Replace unknown type in constructor.
* oln/utils/clone.hh: Use concrete_type.
* oln/makefile.src: Add new files.
* oln/morpho/reconstruction.hh: New. Sequential and hybrid versions.
* oln/morpho/splitse.hh: New. Split a structuring element.
* oln/morpho/stat.hh: Typo fix.
* oln/morpho/erosion.hh: Fix erroneus function name .
* oln/io/write_image_2d_pnm.hh: Invert binary values (0=>1, 1=>0).
* oln/io/read_image_2d_pnm.hh: Invert binary values.
convert/ng_to_se.hh | 88 +++++
core/2d/dpoint2d.hh | 21 +
core/2d/fwd_witer2d.hh | 4
core/2d/neighborhood2d.hh | 18 -
core/abstract/dpoint.hh | 5
core/abstract/neighborhood.hh | 22 -
core/abstract/struct_elt.hh | 38 +-
core/abstract/witer.hh | 13
core/properties.hh | 1
core/value_box.hh | 18 -
io/read_image_2d_pnm.hh | 4
io/write_image_2d_pnm.hh | 2
makefile.src | 4
morpho/erosion.hh | 6
morpho/reconstruction.hh | 646 ++++++++++++++++++++++++++++++++++++++++++
morpho/splitse.hh | 208 +++++++++++++
morpho/stat.hh | 2
utils/clone.hh | 7
18 files changed, 1062 insertions, 45 deletions
Index: oln/convert/ng_to_se.hh
--- oln/convert/ng_to_se.hh (revision 0)
+++ oln/convert/ng_to_se.hh (revision 0)
@@ -0,0 +1,88 @@
+// Copyright (C) 2002, 2004, 2005 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, 59 Temple Place - Suite 330, 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 OLENA_CONVERT_NG_TO_SE_HH
+# define OLENA_CONVERT_NG_TO_SE_HH
+
+# include <oln/basics.hh>
+
+// because of the internal function in this file
+//# include <oln/basics1d.hh>
+# include <oln/basics2d.hh>
+//# include <oln/basics3d.hh>
+//# include <oln/core/1d/neighborhood1d.hh>
+# include <oln/core/2d/neighborhood2d.hh>
+//# include <oln/core/3d/neighborhood3d.hh>
+
+namespace oln {
+ namespace convert {
+ /*! Convert a neighborhood to a window.
+ **
+ ** \see ng_to_cse
+ */
+ template<class N>
+ oln_type_of(N, window)
+ ng_to_se(const oln::abstract::neighborhood<N>& ng)
+ {
+ oln_type_of(N, window) output;
+
+ for (unsigned i = 0; i < ng.card(); i++)
+ output.add(ng[i]);
+ return output;
+ }
+
+ void dpoint_zero(dpoint2d& dp)
+ {
+ dp.row() = 0;
+ dp.col() = 0;
+ }
+
+ /*! Convert a neighborhood to a window and add the center.
+ **
+ ** \see ng_to_cs
+ */
+ template<class N>
+ oln_type_of(N, window)
+ ng_to_cse(const oln::abstract::neighborhood<N>& ng)
+ {
+ oln_type_of(N, window) output;
+
+ for (unsigned i = 0; i < ng.card(); i++)
+ output.add(ng[i]);
+
+ oln_type_of(N, dpoint) zero;
+ dpoint_zero(zero);
+ output.add(zero);
+ return output;
+ }
+
+
+ } // convert
+} // oln
+
+
+#endif // OLENA_CONVERT_NG_TO_SE_HH
Index: oln/core/value_box.hh
--- oln/core/value_box.hh (revision 106)
+++ oln/core/value_box.hh (working copy)
@@ -81,11 +81,17 @@
/// op==
- bool operator==(const value_box<const I>& rhs) const
+ bool operator==(const value_box<I>& rhs) const
{
return this->value() == rhs.value();
}
+ template <typename II>
+ bool operator==(const value_box<II>& rhs) const
+ {
+ return this->value() < rhs.value();
+ }
+
template <typename V>
bool operator==(const V& rhs) const
{
@@ -113,7 +119,7 @@
template <typename II>
bool operator<(const value_box<II>& rhs) const
{
- return this->value() < value.value();
+ return this->value() < rhs.value();
}
/*! \brief specialized version for value_box<I>
@@ -122,7 +128,7 @@
*/
bool operator<(const value_box<I>& rhs) const
{
- return this->value() < value.value();
+ return this->value() < rhs.value();
}
/*! \brief op=
@@ -277,6 +283,12 @@
return this->value() == rhs.value();
}
+ template <typename II>
+ bool operator==(const value_box<const II>& rhs) const
+ {
+ return this->value() < rhs.value();
+ }
+
template <typename V>
bool operator==(const V& rhs) const
{
Index: oln/core/properties.hh
--- oln/core/properties.hh (revision 106)
+++ oln/core/properties.hh (working copy)
@@ -68,6 +68,7 @@
struct delegated_type;
struct size_type;
struct se_type;
+ struct window_type;
struct image_constness_type;
struct image_dimension_type;
Index: oln/core/abstract/struct_elt.hh
--- oln/core/abstract/struct_elt.hh (revision 106)
+++ oln/core/abstract/struct_elt.hh (working copy)
@@ -47,7 +47,7 @@
// category
template <typename E>
- struct set_category< abstract::struct_elt<E> >
+ struct set_category< abstract::struct_elt<E> >
{
typedef category::struct_elt ret;
};
@@ -71,7 +71,7 @@
<< " fwd_witer_type = " << typeid(fwd_witer_type).name() << "," << std::endl
<< " dpoint_type = " << typeid(dpoint_type).name() << " }" << std::endl;
}
-
+
};
mlc_register_prop(category::struct_elt, dpoint_type);
@@ -137,7 +137,7 @@
get_delta() const
{
return this->exact().impl_get_delta();
- }
+ }
coord_t
delta_update(const dpoint_type& dp)
@@ -145,14 +145,36 @@
return this->exact().impl_delta_update(dp);
}
+ exact_type
+ operator-() const
+ {
+ exact_type se(this->exact());
+
+ se.sym();
+ return se;
+ }
+
+ void
+ sym()
+ {
+ this->exact().impl_sym();
+ }
+
protected:
+ void
+ impl_sym()
+ {
+ for (unsigned i = 0; i < this->card(); ++i)
+ dp_[i] = - dp_[i];
+ }
+
bool
impl_has(const dpoint_type& dp) const
{
return std::find(dp_.begin(), dp_.end(), dp) != dp_.end();
- }
-
+ }
+
exact_type&
impl_add(const dpoint_type& dp)
{
@@ -172,14 +194,14 @@
impl_card() const
{
return dp_.size();
- }
+ }
const dpoint_type
impl_at(unsigned i) const
{
precondition(i < this->card());
return dp_[i];
- }
+ }
struct_elt() : dp_(), delta_(0)
{};
@@ -208,6 +230,6 @@
o << "]";
return o;
}
-
+
#endif // ! OLENA_CORE_STRUCT_ELT_HH
Index: oln/core/abstract/witer.hh
--- oln/core/abstract/witer.hh (revision 106)
+++ oln/core/abstract/witer.hh (working copy)
@@ -64,7 +64,7 @@
}
};
- mlc_register_prop(category::witer, se_type);
+ mlc_register_prop(category::witer, se_type);
namespace abstract {
@@ -104,7 +104,12 @@
this->exact().impl_invalidate();
postcondition(! this->is_valid());
}
-
+
+ coord_t nth(unsigned i)
+ {
+ return this->se_[this->pos_].nth(i);
+ }
+
protected:
void impl_start()
@@ -127,8 +132,8 @@
pos_ = se_.card();
}
- witer(const se_type& se)
- : se_(se), pos_(0)
+ witer(const se_type& se)
+ : se_(se), pos_(0)
{}
const se_type& se_;
Index: oln/core/abstract/dpoint.hh
--- oln/core/abstract/dpoint.hh (revision 106)
+++ oln/core/abstract/dpoint.hh (working copy)
@@ -65,6 +65,11 @@
return not this->operator==(rhs);
}
+ coord_t nth(unsigned i) const
+ {
+ return this->exact().impl_nth(i);
+ }
+
protected:
dpoint() {}
Index: oln/core/abstract/neighborhood.hh
--- oln/core/abstract/neighborhood.hh (revision 106)
+++ oln/core/abstract/neighborhood.hh (working copy)
@@ -47,7 +47,7 @@
// category
template <typename E>
- struct set_category< abstract::neighborhood<E> >
+ struct set_category< abstract::neighborhood<E> >
{
typedef category::neighborhood ret;
};
@@ -61,6 +61,7 @@
mlc_decl_prop(category::neighborhood, dpoint_type);
mlc_decl_prop(category::neighborhood, size_type);
+ mlc_decl_prop(category::neighborhood, window_type);
static void echo(std::ostream& ostr)
{
@@ -69,11 +70,12 @@
<< " size_type = " << typeid(size_type).name() << "," << std::endl
<< " dpoint_type = " << typeid(dpoint_type).name() << " }" << std::endl;
}
-
+
};
mlc_register_prop(category::neighborhood, dpoint_type);
mlc_register_prop(category::neighborhood, size_type);
+ mlc_register_prop(category::neighborhood, window_type);
namespace abstract {
@@ -134,7 +136,7 @@
get_delta() const
{
return this->exact().impl_get_delta();
- }
+ }
coord_t
delta_update(const dpoint_type& dp)
@@ -148,8 +150,8 @@
impl_has(const dpoint_type& dp) const
{
return std::find(dp_.begin(), dp_.end(), dp) != dp_.end();
- }
-
+ }
+
exact_type&
impl_add(const dpoint_type& dp)
{
@@ -161,25 +163,25 @@
this->delta_update(dp);
return this->exact();
}
-
+
coord_t
impl_get_delta() const
{
return delta_;
}
-
+
unsigned
impl_card() const
{
return dp_.size();
- }
+ }
const dpoint_type
impl_at(unsigned i) const
{
precondition(i < this->card());
return dp_[i];
- }
+ }
neighborhood() : dp_(), delta_(0)
{};
@@ -208,6 +210,6 @@
o << "]";
return o;
}
-
+
#endif // ! OLENA_CORE_NEIGHBORHOOD_HH
Index: oln/core/2d/dpoint2d.hh
--- oln/core/2d/dpoint2d.hh (revision 106)
+++ oln/core/2d/dpoint2d.hh (working copy)
@@ -94,10 +94,31 @@
const coord_t row() const { return row_; }
const coord_t col() const { return col_; }
+ //FIXME : name it impl_nth when dpoint2d derives from abstract::dpoint
+ const coord_t nth(unsigned i) const
+ {
+ assert(i < 2);
+ if (i == 0)
+ return row_;
+ else
+ return col_;
+ }
+
+
coord_t& row() { return row_; }
coord_t& col() { return col_; }
+ //FIXME : name it impl_nth when dpoint2d derives from abstract::dpoint
+ coord_t& nth(unsigned i)
+ {
+ assert(i < 2);
+ if (i == 0)
+ return row_;
+ else
+ return col_;
+ }
+
protected:
coord_t row_, col_;
};
Index: oln/core/2d/neighborhood2d.hh
--- oln/core/2d/neighborhood2d.hh (revision 106)
+++ oln/core/2d/neighborhood2d.hh (working copy)
@@ -30,6 +30,7 @@
# include <oln/core/2d/dpoint2d.hh>
# include <oln/core/2d/size2d.hh>
+# include <oln/core/2d/window2d.hh>
# include <oln/core/coord.hh>
# include <oln/core/abstract/neighborhood.hh>
@@ -39,7 +40,7 @@
// category
template <>
- struct set_category< neighborhood2d >
+ struct set_category< neighborhood2d >
{ typedef category::neighborhood ret; };
// super_type
@@ -50,18 +51,19 @@
};
template <>
- struct set_props< category::neighborhood, neighborhood2d >
+ struct set_props< category::neighborhood, neighborhood2d >
: public props_of<category::neighborhood>
{
typedef dpoint2d dpoint_type;
typedef size2d size_type;
+ typedef window2d window_type;
};
class neighborhood2d : public abstract::neighborhood<neighborhood2d>
{
public:
-
+
typedef abstract::neighborhood<neighborhood2d> super_type;
/*!
@@ -86,13 +88,13 @@
{
for (unsigned i = 0; i < 2 * n; i += 2)
this->add(dpoint_type(crd[i], crd[i+1]));
- }
+ }
neighborhood2d&
add(const dpoint_type& dp)
{
return this->exact().impl_add(dp);
- }
+ }
neighborhood2d&
add(coord_t row, coord_t col)
@@ -100,8 +102,8 @@
dpoint_type dp(row, col);
return add(dp);
}
-
+
/// Return the name of the type.
static std::string
name()
@@ -116,7 +118,7 @@
delta_(abs(dp.col()));
return delta_;
}
-
+
};
inline const neighborhood2d&
@@ -134,7 +136,7 @@
static const neighborhood2d neighb(4, crd);
return neighb;
}
-
+
} // end of oln
#endif // OLENA_CORE_NEIGHBORHOOD2D_HH
Index: oln/core/2d/fwd_witer2d.hh
--- oln/core/2d/fwd_witer2d.hh (revision 106)
+++ oln/core/2d/fwd_witer2d.hh (working copy)
@@ -48,13 +48,13 @@
{
typedef window2d se_type;
};
-
+
struct fwd_witer2d : public abstract::witer< fwd_witer2d >
{
typedef abstract::witer<fwd_witer2d> super_type;
- fwd_witer2d(const se_type& se) :
+ fwd_witer2d(const window2d& se) :
super_type(se)
{
this->exact_ptr = this;
Index: oln/utils/clone.hh
--- oln/utils/clone.hh (revision 106)
+++ oln/utils/clone.hh (working copy)
@@ -60,10 +60,11 @@
namespace impl {
template <typename I>
- struct clone_type : public abstract::image_unary_operator<I, I, clone_type<I> >
+ struct clone_type
+ : public abstract::image_unary_operator<oln_type_of(I, concrete), I, clone_type<I> >
// FIXME: use concrete_type; Cf. erosion.hh
{
- typedef abstract::image_unary_operator<I, I, clone_type<I> > super_type;
+ typedef abstract::image_unary_operator<oln_type_of(I, concrete), I, clone_type<I> > super_type;
clone_type(const abstract::image<I>& input) :
super_type(input)
@@ -72,7 +73,7 @@
void impl_run()
{
- I tmp(this->input.size()); // FIXME: trick
+ oln_type_of(I, concrete) tmp(this->input.size()); // FIXME: trick
this->output = tmp;
oln_type_of(I, fwd_piter) p(this->input.size());
Index: oln/makefile.src
--- oln/makefile.src (revision 106)
+++ oln/makefile.src (working copy)
@@ -13,6 +13,7 @@
basics3d.hh \
config/pconf.hh \
config/system.hh \
+ convert/ng_to_se.hh \
convert/value_to_point.hh \
core/1d/array1d.hh \
core/1d/dpoint1d.hh \
@@ -87,6 +88,9 @@
io/write_image_2d_pnm.hh \
level/compare.hh \
level/fill.hh \
+ morpho/dilation.hh \
morpho/erosion.hh \
+ morpho/reconstruction.hh \
+ morpho/splitse.hh \
morpho/stat.hh \
utils/clone.hh
Index: oln/morpho/reconstruction.hh
--- oln/morpho/reconstruction.hh (revision 0)
+++ oln/morpho/reconstruction.hh (revision 0)
@@ -0,0 +1,646 @@
+// Copyright (C) 2001, 2002, 2004, 2005 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, 59 Temple Place - Suite 330, Boston,
+// MA 02111-1307, USA.
+//
+// As a special exception, you may use this filek 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 OLENA_MORPHO_RECONSTRUCTION_HH
+# define OLENA_MORPHO_RECONSTRUCTION_HH
+
+# include <queue>
+
+# include <mlc/contract.hh>
+# include <oln/convert/ng_to_se.hh>
+# include <oln/morpho/splitse.hh>
+# include <oln/level/compare.hh>
+# include <oln/core/abstract/neighborhood.hh>
+# include <oln/core/properties.hh>
+# include <oln/core/abstract/image_operator.hh>
+# include <oln/utils/clone.hh>
+
+// FIXME: ADD TESTS !!!!
+
+namespace oln {
+
+ namespace morpho {
+
+ // fwd decl
+ template <typename I, typename E> struct reconstruction_ret;
+
+ }
+
+ // category
+ template <typename I, typename E>
+ struct set_category< morpho::reconstruction_ret<I,E> > { typedef category::image ret; };
+
+ // super_type
+ template <typename I, typename E>
+ struct set_super_type< morpho::reconstruction_ret<I,E> >
+ {
+ typedef abstract::image_binary_operator<I, I, I, morpho::reconstruction_ret<I, E> > ret;
+ // FIXME: see below
+ };
+
+
+ namespace morpho {
+
+ template <typename I, typename N>
+ struct reconstruction_ret : public abstract::image_binary_operator<I, I, I, reconstruction_ret<I, N> >
+ // FIXME: abstract::image_binary_operator<oln_type_of(I, concrete), ...
+ {
+ typedef abstract::image_binary_operator<I, I, I, reconstruction_ret<I, N> > super_type;
+
+ const N ng;
+
+ reconstruction_ret(const abstract::non_vectorial_image<I>& input1,
+ const abstract::non_vectorial_image<I>& input2,
+ const abstract::neighborhood<N>& ng) :
+ super_type(input1.exact(), input2.exact()),
+ ng(ng.exact())
+ {}
+
+ };
+
+ namespace sequential {
+ /*!
+ ** \brief Perform a geodesic reconstruction dilation.
+ **
+ ** Compute the reconstruction by dilation of marker with respect
+ ** to the mask image using se as structuring element. Soille
+ ** p.160. The algorithm used is the one defined as sequential in
+ ** Vincent(1993), Morphological grayscale reconstruction in
+ ** image analysis: applications and efficient algorithms, itip,
+ ** 2(2), 176--201.
+ **
+ ** \pre Mask must be greater or equal than marker.
+ **
+ ** \param I1 Exact type of image marker.
+ ** \param I2 Exact type of image mask.
+ ** \param N Exact type of neighborhood.
+ **
+ ** \arg marker Image to work on.
+ ** \arg mask Image used for geodesic dilation.
+ ** \arg Ng Neighborhood to use.
+ **
+ ** \code
+ ** #include <oln/basics2d.hh>
+ ** #include <oln/morpho/opening.hh>
+ ** #include <oln/morpho/reconstruction.hh>
+ ** #include <oln/level/compare.hh>
+ ** #include <ntg/all.hh>
+ ** int main()
+ ** {
+ ** typedef oln::image2d<ntg::int_u8> im_type;
+ **
+ ** im_type im1(oln::load(IMG_IN "lena128.pgm"));
+ ** im_type im2 = oln::morpho::opening(im1, oln::win_c4p());
+ **
+ ** oln::save(oln::morpho::sequential::geodesic_reconstruction_dilation(im2,
+ ** im1,
+ ** oln::neighb_c4()),
+ ** IMG_OUT "oln_morpho_sequential_geodesic_reconstruction_dilation.pbm");
+ ** return 0;
+ ** }
+ ** \endcode
+ **
+ ** \image html lena128_pgm.png
+ ** \image latex lena128_pgm.png
+ ** =>
+ ** \image html oln_morpho_sequential_geodesic_reconstruction_dilation.png
+ ** \image latex oln_morpho_sequential_geodesic_reconstruction_dilation.png
+ **
+ */
+
+ namespace impl {
+
+ template <typename I, typename N>
+ struct reconstruction_dilation_ret : public reconstruction_ret<I, N>
+ {
+ typedef reconstruction_ret<I, N> super_type;
+
+ reconstruction_dilation_ret(const abstract::non_vectorial_image<I>& input1, //marker
+ const abstract::non_vectorial_image<I>& input2, //mask
+ const abstract::neighborhood<N>& ng)
+
+ : super_type(input1, input2, ng)
+ {}
+
+ void impl_run()
+ {
+ mlc::is_true<mlc::type::eq<oln_type_of(I, size),
+ oln_type_of(N, size)>::ret>::ensure();
+ precondition(this->input1.size() == this->input2.size());
+ precondition(level::is_greater_or_equal(this->input2, this->input1));
+
+ // Conversion of neighborhood into a SE.
+ oln_type_of(N, window) se_plus = get_plus_se_p(convert::ng_to_cse(this->ng));
+ oln_type_of(N, window) se_minus = get_minus_se_p(convert::ng_to_cse(this->ng));
+
+ I output;
+ output = utils::clone(this->input1);
+ bool non_stability = true;
+ oln_type_of(I, fwd_piter) fwd_p(output.size());
+ oln_type_of(I, fwd_piter) bkd_p(output.size());
+ while (non_stability)
+ {
+ I work;
+ work = utils::clone(output);
+ for_all (fwd_p)
+ work[fwd_p] = ntg::min(morpho::max(work, fwd_p, se_plus), this->input2[fwd_p].value());
+ for_all (bkd_p)
+ work[bkd_p] = ntg::min(morpho::max(work, bkd_p, se_minus), this->input2[bkd_p].value());
+ non_stability = !(level::is_equal(work, output));
+ output = work;
+ }
+ this->output = output;
+ }
+ };
+
+ }
+
+ template<class I, class N>
+ reconstruction_ret<I, N>
+ geodesic_reconstruction_dilation(const abstract::non_vectorial_image<I> & marker,
+ const abstract::non_vectorial_image<I> & mask,
+ const abstract::neighborhood<N>& ng)
+ {
+ impl::reconstruction_dilation_ret<I, N> tmp(marker, mask, ng);
+ tmp.run();
+ return tmp;
+ }
+ }// sequential
+
+
+ namespace hybrid {
+
+ namespace internal {
+
+ /*!
+ ** \brief Check if it exists initialization for dilation.
+ **
+ ** \arg p Point to consider.
+ ** \arg marker Image to work on.
+ ** \arg mask Image used as mask.
+ ** \arg Ng Neighborhood to use.
+ */
+ template<class P, class I1, class I2, class E> inline
+ static bool
+ exist_init_dilation(const abstract::point<P>& p,
+ const abstract::non_vectorial_image<I1>& marker,
+ const abstract::non_vectorial_image<I2>& mask,
+ const abstract::struct_elt<E>& se)
+ {
+ oln_type_of(E, fwd_witer) dp(se.exact());
+ for_all (dp)
+ {
+ P q = (oln_type_of(E, dpoint))dp + p.exact();
+ if (marker.hold(q) && (marker[q] < marker[p.exact()]) &&
+ (marker[q] < mask[q]))
+ return true;
+ }
+ return false;
+ }
+
+ } //internal
+
+ /*!
+ ** \brief Perform a geodesic reconstruction dilation.
+ **
+ ** Compute the reconstruction by dilation of marker with
+ ** respect to the mask image using se as structuring
+ ** element. Soille p.160. The algorithm used is the one defined
+ ** as hybrid in Vincent(1993), Morphological grayscale
+ ** reconstruction in image analysis: applications and efficient
+ ** algorithms, itip, 2(2), 176--201.
+ **
+ ** \pre Mask must be greater or equal than marker.
+ **
+ ** \param I1 Exact type of image marker.
+ ** \param I2 Exact type of image mask.
+ ** \param N Exact type of neighborhood.
+ **
+ ** \arg marker Image to work on.
+ ** \arg mask Image used for geodesic dilation.
+ ** \arg Ng Neighborhood to use.
+ **
+ ** \code
+ ** #include <oln/basics2d.hh>
+ ** #include <oln/morpho/opening.hh>
+ ** #include <oln/morpho/reconstruction.hh>
+ ** #include <oln/level/compare.hh>
+ ** #include <ntg/all.hh>
+ ** int main()
+ ** {
+ ** typedef oln::image2d<ntg::int_u8> im_type;
+ **
+ ** im_type im1(oln::load(IMG_IN "lena128.pgm"));
+ ** im_type im2 = oln::morpho::opening(im1, oln::win_c4p());
+ **
+ ** oln::save(oln::morpho::hybrid::geodesic_reconstruction_dilation(im2,
+ ** im1,
+ ** oln::neighb_c4()),
+ ** IMG_OUT "oln_morpho_hybrid_geodesic_reconstruction_dilation.pbm");
+ ** return 0;
+ ** }
+ ** \endcode
+ **
+ ** \image html lena128_pgm.png
+ ** \image latex lena128_pgm.png
+ ** =>
+ ** \image html oln_morpho_hybrid_geodesic_reconstruction_dilation.png
+ ** \image latex oln_morpho_hybrid_geodesic_reconstruction_dilation.png
+ **
+ */
+
+ namespace impl {
+
+ template <typename I, typename N>
+ struct reconstruction_dilation_ret : public reconstruction_ret<I, N>
+ {
+ typedef reconstruction_ret<I, N> super_type;
+
+ reconstruction_dilation_ret(const abstract::non_vectorial_image<I>& input1, //marker
+ const abstract::non_vectorial_image<I>& input2, //mask
+ const abstract::neighborhood<N>& ng)
+
+ : super_type(input1, input2, ng)
+ {}
+
+ void impl_run()
+ {
+ mlc::is_true<mlc::type::eq<oln_type_of(I, size),
+ oln_type_of(N, size)>::ret>::ensure();
+ precondition(this->input1.size() == this->input2.size());
+ precondition(level::is_greater_or_equal(this->input2, this->input1));
+
+ oln_type_of(I, concrete) output;
+ output = utils::clone(this->input1);
+ {
+ oln_type_of(N, window) se_plus = get_plus_se_p(convert::ng_to_cse(this->ng));
+ oln_type_of(N, window) se_minus = get_minus_se_p(convert::ng_to_cse(this->ng));
+ oln_type_of(I, fwd_piter) fwd_p(output.size());
+ oln_type_of(I, fwd_piter) bkd_p(output.size());
+
+ for_all (fwd_p)
+ output[fwd_p] = ntg::min(morpho::max(output, fwd_p, se_plus),
+ this->input2[fwd_p].value());
+
+ std::queue<oln_type_of(I, point) > fifo;
+ for_all (bkd_p)
+ {
+ output[bkd_p] = ntg::min(morpho::max(output, bkd_p, se_minus),
+ this->input2[bkd_p].value());
+ if (internal::exist_init_dilation((oln_type_of(I, point))bkd_p, output,
+ this->input2, se_minus))
+ fifo.push(bkd_p);
+ }
+ // Propagation Step
+ while (!fifo.empty())
+ {
+ oln_type_of(I, point) p = fifo.front();
+ fifo.pop();
+ typedef oln_type_of(N, window) window_type;
+ window_type w = convert::ng_to_se(this->ng);
+ oln_type_of(window_type, fwd_witer) dp(w);
+
+ for_all (dp)
+ {
+ oln_type_of(I, point) q = (oln_type_of(window_type, dpoint))dp + p;
+ if (output.hold(q))
+ {
+ if ((output[q] < output[p]) &&
+ (this->input2[q] != output[q]))
+ {
+ output[q] = ntg::min(output[p].value(),
+ this->input2[q].value());
+ fifo.push(q);
+ }
+ }
+ }
+ }
+ }
+ this->output = output;
+ }
+ };
+
+ }
+
+ template<class I, class N>
+ reconstruction_ret<I, N>
+ geodesic_reconstruction_dilation(const abstract::non_vectorial_image<I> & marker,
+ const abstract::non_vectorial_image<I> & mask,
+ const abstract::neighborhood<N>& ng)
+ {
+ impl::reconstruction_dilation_ret<I, N> tmp(marker, mask, ng);
+ tmp.run();
+ return tmp;
+ }
+ }// hybrid
+
+
+ namespace sequential {
+
+ /*!
+ ** \brief Perform a geodesic reconstruction erosion.
+ **
+ ** Compute the reconstruction by erosion of marker with respect
+ ** to the mask image using se as structuring element. Soille
+ ** p.160. The algorithm used is the one defined as sequential
+ ** in Vincent(1993), Morphological grayscale reconstruction in
+ ** image analysis: applications and efficient algorithms, itip,
+ ** 2(2), 176--201.
+ **
+ ** \pre Marker must be greater or equal than mask.
+ **
+ ** \param I1 Exact type of image marker.
+ ** \param I2 Exact type of image mask.
+ ** \param N Exact type of neighborhood.
+ **
+ ** \arg marker Image to work on.
+ ** \arg mask Image used for geodesic erosion.
+ ** \arg Ng Neighborhood to use.
+ **
+ ** \code
+ ** #include <oln/basics2d.hh>
+ ** #include <oln/morpho/opening.hh>
+ ** #include <oln/morpho/reconstruction.hh>
+ ** #include <oln/level/compare.hh>
+ ** #include <ntg/all.hh>
+ ** int main()
+ ** {
+ ** typedef oln::image2d<ntg::int_u8> im_type;
+ **
+ ** im_type im1(oln::load(IMG_IN "lena128.pgm"));
+ ** im_type im2 = oln::morpho::opening(im1, oln::win_c4p());
+ **
+ ** oln::save(oln::morpho::sequential::geodesic_reconstruction_erosion(im1,
+ ** im2,
+ ** oln::neighb_c4()),
+ ** IMG_OUT "oln_morpho_sequential_geodesic_reconstruction_erosion.pbm");
+ ** return 0;
+ ** }
+ ** \endcode
+ **
+ ** \image html lena128_pgm.png
+ ** \image latex lena128_pgm.png
+ ** =>
+ ** \image html oln_morpho_sequential_geodesic_reconstruction_erosion.png
+ ** \image latex oln_morpho_sequential_geodesic_reconstruction_erosion.png
+ **
+ */
+
+
+ namespace impl {
+
+ template <typename I, typename N>
+ struct reconstruction_erosion_ret : public reconstruction_ret<I, N>
+ {
+ typedef reconstruction_ret<I, N> super_type;
+
+ reconstruction_erosion_ret(const abstract::non_vectorial_image<I>& input1, //marker
+ const abstract::non_vectorial_image<I>& input2, //mask
+ const abstract::neighborhood<N>& ng)
+
+ : super_type(input1, input2, ng)
+ {}
+
+ void impl_run()
+ {
+ mlc::is_true<mlc::type::eq<oln_type_of(I, size),
+ oln_type_of(N, size)>::ret>::ensure();
+ precondition(this->input1.size() == this->input2.size());
+ precondition(level::is_greater_or_equal(this->input2, this->input1));
+
+ // Conversion of neighborhood into a SE.
+ oln_type_of(N, window) se_plus = get_plus_se_p(convert::ng_to_cse(this->ng));
+ oln_type_of(N, window) se_minus = get_minus_se_p(convert::ng_to_cse(this->ng));
+
+ I output;
+ output = utils::clone(this->input1);
+ bool non_stability = true;
+ oln_type_of(I, fwd_piter) fwd_p(output.size());
+ oln_type_of(I, fwd_piter) bkd_p(output.size());
+ while (non_stability)
+ {
+ I work;
+ work = utils::clone(output);
+ for_all (fwd_p)
+ work[fwd_p] = ntg::max(morpho::min(work, fwd_p, se_plus),
+ this->input2[fwd_p].value());
+ for_all (bkd_p)
+ work[bkd_p] = ntg::max(morpho::min(work, bkd_p, se_minus),
+ this->input2[bkd_p].value());
+ non_stability = !(level::is_equal(work, output));
+ output = work;
+ }
+ this->output = output;
+ }
+ };
+
+ }
+
+ template<class I, class N>
+ reconstruction_ret<I, N>
+ geodesic_reconstruction_erosion(const abstract::non_vectorial_image<I> & marker,
+ const abstract::non_vectorial_image<I> & mask,
+ const abstract::neighborhood<N>& ng)
+ {
+ impl::reconstruction_erosion_ret<I, N> tmp(marker, mask, ng);
+ tmp.run();
+ return tmp;
+ }
+
+ } // sequential
+
+ namespace hybrid {
+
+ namespace internal {
+
+ /*!
+ ** \brief Check if it exists initialization for erosion.
+ **
+ ** \arg p Point to consider.
+ ** \arg marker Image to work on.
+ ** \arg mask Image used as mask.
+ ** \arg Ng Neighborhood to use.
+ */
+ template<class P, class I1, class I2, class E> inline
+ static bool
+ exist_init_erosion(const abstract::point<P>& p,
+ const abstract::non_vectorial_image<I1>& marker,
+ const abstract::non_vectorial_image<I2>& mask,
+ const abstract::struct_elt<E>& se)
+ {
+ oln_type_of(E, fwd_witer) dp(se.exact());
+ for_all (dp)
+ {
+ P q = (oln_type_of(E, dpoint))dp + p.exact();
+ if (marker.hold(q) && (marker[q] > marker[p.exact()]) &&
+ (marker[q] > mask[q]))
+ return true;
+ }
+ return false;
+ }
+
+ } //internal
+
+ /*!
+ ** \brief Perform a geodesic reconstruction erosion.
+ **
+ ** Compute the reconstruction by erosion of marker with respect
+ ** to the mask mask image using se as structuring
+ ** element. Soille p.160. The algorithm used is the one defined
+ ** as hybrid in Vincent(1993), Morphological grayscale
+ ** reconstruction in image analysis: applications and efficient
+ ** algorithms, itip, 2(2), 176--201.
+ **
+ ** \pre Marker must be greater or equal than mask.
+ **
+ ** \param I1 Exact type of image marker.
+ ** \param I2 Exact type of image mask.
+ ** \param N Exact type of neighborhood.
+ **
+ ** \arg marker Image to work on.
+ ** \arg mask Image used for geodesic erosion.
+ ** \arg Ng Neighborhood to use.
+ **
+ ** \code
+ ** #include <oln/basics2d.hh>
+ ** #include <oln/morpho/opening.hh>
+ ** #include <oln/morpho/reconstruction.hh>
+ ** #include <oln/level/compare.hh>
+ ** #include <ntg/all.hh>
+ ** int main()
+ ** {
+ ** typedef oln::image2d<ntg::int_u8> im_type;
+ **
+ ** im_type im1(oln::load(IMG_IN "lena128.pgm"));
+ ** im_type im2 = oln::morpho::opening(im1, oln::win_c4p());
+ **
+ ** oln::save(oln::morpho::hybrid::geodesic_reconstruction_erosion(im1,
+ ** im2,
+ ** oln::neighb_c4()),
+ ** IMG_OUT "oln_morpho_hybrid_geodesic_reconstruction_erosion.pbm");
+ ** return 0;
+ ** }
+ ** \endcode
+ **
+ ** \image html lena128_pgm.png
+ ** \image latex lena128_pgm.png
+ ** =>
+ ** \image html oln_morpho_hybrid_geodesic_reconstruction_erosion.png
+ ** \image latex oln_morpho_hybrid_geodesic_reconstruction_erosion.png
+ **
+ */
+
+ namespace impl {
+
+ template <typename I, typename N>
+ struct reconstruction_erosion_ret : public reconstruction_ret<I, N>
+ {
+ typedef reconstruction_ret<I, N> super_type;
+
+ reconstruction_erosion_ret(const abstract::non_vectorial_image<I>& input1, //marker
+ const abstract::non_vectorial_image<I>& input2, //mask
+ const abstract::neighborhood<N>& ng)
+
+ : super_type(input1, input2, ng)
+ {}
+
+ void impl_run()
+ {
+ mlc::is_true<mlc::type::eq<oln_type_of(I, size),
+ oln_type_of(N, size)>::ret>::ensure();
+ precondition(this->input1.size() == this->input2.size());
+ precondition(level::is_greater_or_equal(this->input2, this->input1));
+
+ oln_type_of(I, concrete) output;
+ output = utils::clone(this->input1);
+ {
+ oln_type_of(N, window) se_plus = get_plus_se_p(convert::ng_to_cse(this->ng));
+ oln_type_of(N, window) se_minus = get_minus_se_p(convert::ng_to_cse(this->ng));
+ oln_type_of(I, fwd_piter) fwd_p(output.size());
+ oln_type_of(I, fwd_piter) bkd_p(output.size());
+
+ for_all (fwd_p)
+ output[fwd_p] = ntg::max(morpho::min(output, fwd_p, se_plus),
+ this->input2[fwd_p].value());
+
+ std::queue<oln_type_of(I, point) > fifo;
+ for_all (bkd_p)
+ {
+ output[bkd_p] = ntg::max(morpho::min(output, bkd_p, se_minus),
+ this->input2[bkd_p].value());
+ if (internal::exist_init_erosion((oln_type_of(I, point))bkd_p, output,
+ this->input2, se_minus))
+ fifo.push(bkd_p);
+ }
+ // Propagation Step
+ while (!fifo.empty())
+ {
+ oln_type_of(I, point) p = fifo.front();
+ fifo.pop();
+ typedef oln_type_of(N, window) window_type;
+ window_type w = convert::ng_to_se(this->ng);
+ oln_type_of(window_type, fwd_witer) dp(w);
+
+ for_all (dp)
+ {
+ oln_type_of(I, point) q = (oln_type_of(window_type, dpoint))dp + p;
+ if (output.hold(q))
+ {
+ if ((output[q] > output[p]) &&
+ (this->input2[q] != output[q]))
+ {
+ output[q] = ntg::max(output[p].value(),
+ this->input2[q].value());
+ fifo.push(q);
+ }
+ }
+ }
+ }
+ }
+ this->output = output;
+ }
+ };
+
+ }
+
+ template<class I, class N>
+ reconstruction_ret<I, N>
+ geodesic_reconstruction_erosion(const abstract::non_vectorial_image<I> & marker,
+ const abstract::non_vectorial_image<I> & mask,
+ const abstract::neighborhood<N>& ng)
+ {
+ impl::reconstruction_erosion_ret<I, N> tmp(marker, mask, ng);
+ tmp.run();
+ return tmp;
+ }
+ }// hybrid
+
+ }
+
+}
+
+#endif // ! OLENA_MORPHO_RECONSTRUCTION_HH
Index: oln/morpho/splitse.hh
--- oln/morpho/splitse.hh (revision 0)
+++ oln/morpho/splitse.hh (revision 0)
@@ -0,0 +1,208 @@
+// Copyright (C) 2001, 2002, 2004, 2005 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, 59 Temple Place - Suite 330, 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 OLENA_MORPHO_SPLITSE_HH
+# define OLENA_MORPHO_SPLITSE_HH
+
+# include <oln/basics.hh>
+
+# include <oln/core/1d/size1d.hh>
+# include <oln/core/2d/size2d.hh>
+# include <oln/core/3d/size3d.hh>
+
+namespace oln {
+ namespace morpho {
+
+ template <class S>
+ struct dim_traits
+ {
+ };
+
+ template <>
+ struct dim_traits<size1d>
+ {
+ enum {dim = 1};
+ };
+
+ template <>
+ struct dim_traits<size2d>
+ {
+ enum {dim = 2};
+ };
+
+ template <>
+ struct dim_traits<size3d>
+ {
+ enum {dim = 3};
+ };
+
+ /*!
+ ** \brief Get a sub part of a structuring element.
+ **
+ ** \param E Exact type of the structuring element.
+ **
+ ** \arg se The structuring element.
+ **
+ ** A point p take part of the new structuring element if it exists
+ ** a i that belongs to [[0..dim-1]] like p(i) < 0 and for all j
+ ** that belongs to [[0..i-1]] p(j) = 0.
+ **
+ */
+
+
+ template<class E>
+ E
+ get_plus_se_only(const abstract::struct_elt<E>& se)
+ {
+ oln_type_of(E, fwd_witer) dp(se.exact());
+ E out;
+
+ for_all (dp)
+ {
+ unsigned n;
+ for (n = 0; n < dim_traits<oln_type_of(E, size)>::dim; ++n)
+ if (dp.nth(n) < 0) {
+ out.add(dp);
+ break;
+ } else if (dp.nth(n) > 0) {
+ break;
+ }
+ }
+ return out;
+ }
+
+ /*!
+ ** \brief Get a sub part of a structuring element.
+ **
+ ** \param E Exact type of the structuring element.
+ **
+ ** \arg se The structuring element.
+ **
+ ** A point p take part of the new structuring element if it exists
+ ** a i that belongs to [[0..dim-1]] like p(i) < 0 and for all j
+ ** that belongs to [[0..i-1]] p(j) = 0 or if for all i that
+ ** belongs to [[0..dim-1]] p(i) = 0.
+ **
+ */
+ template<class E>
+ E
+ get_plus_se_p(const abstract::struct_elt<E>& se)
+ {
+ oln_type_of(E, fwd_witer) dp(se.exact());
+ E out;
+
+ for_all (dp)
+ {
+ unsigned n;
+ for (n = 0; n < dim_traits<oln_type_of(E, size)>::dim; ++n)
+ if (dp.nth(n) < 0) {
+ out.add(dp);
+ break;
+ } else if (dp.nth(n) > 0) {
+ break;
+ }
+ // All p.nth(n) are 0.
+ if (n == dim_traits<oln_type_of(E, size)>::dim)
+ out.add(dp);
+ }
+ return out;
+ }
+
+ /*!
+ ** \brief Get a sub part of a structuring element.
+ **
+ ** \param E Exact type of the structuring element.
+ **
+ ** \arg se The structuring element.
+ **
+ ** A point p take part of the new structuring element if it exists
+ ** a i that belongs to [[0..dim-1]] like p(i) > 0 and for all j
+ ** that belongs to [[0..i-1]] p(j) = 0.
+ **
+ */
+ template<class E>
+ E
+ get_minus_se_only(const abstract::struct_elt<E>& se)
+ {
+ oln_type_of(E, fwd_witer) dp(se.exact());
+ E out;
+
+ for_all (dp)
+ {
+ unsigned n;
+ for (n = 0; n < dim_traits<oln_type_of(E, size)>::dim; ++n)
+ if (dp.nth(n) > 0) {
+ out.add(dp);
+ break;
+ } else if (dp.nth(n) < 0) {
+ break;
+ }
+ }
+ return out;
+ }
+
+ /*!
+ ** \brief Get a sub part of a structuring element.
+ **
+ ** \param E Exact type of the structuring element.
+ **
+ ** \arg se The structuring element.
+ **
+ ** A point p take part of the new structuring element if it exists
+ ** a i that belongs to [[0..dim-1]] like p(i) > 0 and for all j
+ ** that belongs to [[0..i-1]] p(j) = 0 or if for all i that
+ ** belongs to [[0..dim-1]] p(i) = 0.
+ **
+ */
+ template<class E>
+ E
+ get_minus_se_p(const abstract::struct_elt<E>& se)
+ {
+ oln_type_of(E, fwd_witer) dp(se.exact());
+ E out;
+
+ for_all (dp)
+ {
+ unsigned n;
+ for (n = 0; n < dim_traits<oln_type_of(E, size)>::dim; ++n)
+ if (dp.nth(n) > 0) {
+ out.add(dp);
+ break;
+ } else if (dp.nth(n) < 0) {
+ break;
+ }
+ // All p.nth(n) are 0.
+ if (n == dim_traits<oln_type_of(E, size)>::dim)
+ out.add(dp);
+ }
+ return out;
+ }
+
+ } // morpho
+} // oln
+
+#endif // OLENA_MORPHO_SPLITSE_HH
Index: oln/morpho/stat.hh
--- oln/morpho/stat.hh (revision 106)
+++ oln/morpho/stat.hh (working copy)
@@ -47,7 +47,7 @@
** \param E Structuring element type.
** \param V Associated value type.
*/
- template <class I, class E, class V =oln_type_of(I, value)>
+ template <class I, class E, class V = oln_type_of(I, value)>
struct stat_
{
/*!
Index: oln/morpho/erosion.hh
--- oln/morpho/erosion.hh (revision 106)
+++ oln/morpho/erosion.hh (working copy)
@@ -43,7 +43,7 @@
/// Erosion as a procedure (do not use it; prefer morpho::erosion).
template<typename I, typename S>
- oln_type_of(I, concrete) dilation(const abstract::image<I>& input,
+ oln_type_of(I, concrete) erosion(const abstract::image<I>& input,
const abstract::struct_elt<S>& se)
{
oln_type_of(I, concrete) output(input.size());
@@ -131,14 +131,14 @@
typedef typename super_type::output_type output_type;
const E se;
-
+
erosion_ret(const abstract::image<I>& input,
const abstract::struct_elt<E>& se) :
super_type(input),
se(se.exact())
{
}
-
+
};
Index: oln/io/write_image_2d_pnm.hh
--- oln/io/write_image_2d_pnm.hh (revision 106)
+++ oln/io/write_image_2d_pnm.hh (working copy)
@@ -122,7 +122,7 @@
bin_v = 0;
ret = true;
}
- if (c == value_type(1))
+ if (c == value_type(0))
bin_v |= 1 << bin_offset;
bin_offset--;
return ret;
Index: oln/io/read_image_2d_pnm.hh
--- oln/io/read_image_2d_pnm.hh (revision 106)
+++ oln/io/read_image_2d_pnm.hh (working copy)
@@ -172,9 +172,9 @@
offset = 7;
}
if ((int)(v & (1<<offset--)) == 0)
+ c = 0;
+ else
c = 1;
- else
- c = 0;
}
};
1
1
proto-1.0 106: Add connected component labelling algorithm using the Tarjan Union-Find (naive version)
by Simon Odou 03 Apr '05
by Simon Odou 03 Apr '05
03 Apr '05
Index: ChangeLog
from Simon Odou <simon(a)lrde.epita.fr>
* oln/morpho/cc_tarjan.hh: New. Add the connected component
labelling algorithm using the Tarjan Union-Find.
cc_tarjan.hh | 234 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 234 insertions(+)
Index: oln/morpho/cc_tarjan.hh
--- oln/morpho/cc_tarjan.hh (revision 0)
+++ oln/morpho/cc_tarjan.hh (revision 0)
@@ -0,0 +1,234 @@
+// Copyright (C) 2005 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, 59 Temple Place - Suite 330, 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 OLENA_CC_TARJAN_HH
+# define OLENA_CC_TARJAN_HH
+
+# include <vector>
+
+# include <oln/basics2d.hh>
+# include <oln/core/abstract/image_operator.hh>
+# include <oln/level/fill.hh>
+
+//
+// Based on "Ruminations on Tarjan's Union-Find algorithm and connected
+// operators" of Thierry Geraud.
+//
+
+
+namespace oln {
+
+ // fwd decl
+ namespace morpho {
+ template <typename T, typename I, typename E> struct cc_tarjan_ret;
+ }
+
+ // FIXME: this macro is waiting for the mute.
+ // (we may use a property to do it)
+ #define tmp_mute(I, T) image2d< T >
+
+ // category
+ template <typename T, typename I, typename E>
+ struct set_category< morpho::cc_tarjan_ret<T,I,E> >
+ { typedef category::image ret; };
+
+ // super_type
+ template <typename T, typename I, typename E>
+ struct set_super_type< morpho::cc_tarjan_ret<T,I,E> >
+ {
+ typedef abstract::image_unary_operator
+ <tmp_mute(I, T), I, morpho::cc_tarjan_ret<T, I, E> >
+ ret;
+ };
+
+
+ namespace morpho {
+
+ template <typename T, typename I, typename E>
+ struct cc_tarjan_ret
+ : public abstract::image_unary_operator
+ <tmp_mute(I, T), I, cc_tarjan_ret<T, I, E> >
+ {
+ typedef abstract::image_unary_operator
+ <tmp_mute(I, T), I, cc_tarjan_ret<T, I, E> >
+ super_type;
+ typedef typename super_type::output_type output_type;
+
+ const E ng;
+
+ cc_tarjan_ret(const abstract::image<I>& input,
+ const abstract::neighborhood<E>& ng) :
+ super_type(input),
+ ng(ng.exact())
+ {
+ }
+
+ };
+
+
+ namespace impl {
+
+
+ namespace misc {
+
+ // FIXME: This code should be generalized.
+ // While iterating on image and then on a neighborhood, here we do
+ // not want to see the neighborhood points ever seen.
+ std::vector<dpoint2d> get_superior(const neighborhood2d& n)
+ {
+ std::vector<dpoint2d> output;
+ for (unsigned i = 0; i < n.card(); ++i)
+ {
+ dpoint2d dp = n.dp(i);
+ if (dp.row() < 0 || (dp.row() == 0 && dp.col() < 0))
+ output.push_back(dp);
+ }
+ return output;
+ }
+
+ std::vector<dpoint2d> get_inferior(const neighborhood2d& n)
+ {
+ std::vector<dpoint2d> output;
+ for (unsigned i = 0; i < n.card(); ++i)
+ {
+ dpoint2d dp = n.dp(i);
+ if (dp.row() > 0 || (dp.row() == 0 && dp.col() > 0))
+ output.push_back(dp);
+ }
+ return output;
+ }
+
+ } // end of misc namespace
+
+
+ template <typename T, typename I, typename N>
+ struct generic_cc_tarjan : public cc_tarjan_ret<T, I, N>
+ {
+ typedef cc_tarjan_ret<T, I, N> super_type;
+ typedef typename super_type::output_type output_type;
+
+ tmp_mute(I, oln_type_of(I, point)) parent;
+ T ncomps;
+
+ generic_cc_tarjan(const abstract::image<I>& input,
+ const abstract::neighborhood<N>& ng) :
+ super_type(input, ng),
+ parent(input.size())
+ {
+ }
+
+ void impl_run()
+ {
+ mlc::is_true<mlc::type::eq<oln_type_of(I, size),
+ oln_type_of(N, size)>::ret>::ensure();
+
+ output_type tmp(this->input.size()); // FIXME: trick
+ this->output = tmp;
+
+ first_pass();
+ second_pass();
+ }
+
+ void first_pass()
+ {
+ std::vector<dpoint2d> neighb = misc::get_inferior(this->ng);
+ oln_type_of(I, bkd_piter) p(this->input.size());
+ for_all(p)
+ if (this->input[p])
+ {
+ make_set(p);
+ for (unsigned v = 0; v < neighb.size(); ++v)
+ {
+ oln_type_of(I, point) n = oln_type_of(I, point)(p) + neighb[v];
+ if (this->input[n])
+ do_union(n, p);
+ }
+ }
+ }
+
+ void second_pass()
+ {
+ oln_type_of(I, fwd_piter) p(this->input.size());
+ level::fill(output, 0);
+ ncomps = 0;
+ for_all(p)
+ if (this->input[p])
+ {
+ oln_type_of(I, point) q = parent[p];
+ // FIXME: test if ncomps > T::max()
+ output[p] = (q == p ? ++ncomps : output[q]);
+ }
+ }
+
+ void make_set(const oln_type_of(I, point)& x)
+ {
+ parent[x] = x;
+ }
+
+ oln_type_of(I, point) find_root(const oln_type_of(I, point)& x)
+ {
+ if (parent[x] != x)
+ {
+ parent[x] = find_root(parent[x]);
+ return parent[x];
+ }
+ return x;
+ }
+
+ void do_union(const oln_type_of(I, point)& n,
+ const oln_type_of(I, point)& p)
+ {
+ oln_type_of(I, point) r = find_root(n);
+ if (r != p)
+ parent[r] = p;
+ }
+
+
+ };
+
+ } // end of namespace oln::morpho::impl
+
+
+ /// Connected component labelling via Tarjan Union-Find generic routine.
+
+ // T is the component label type (usually unsigned).
+ template<typename T, typename I, typename N>
+ cc_tarjan_ret<T, I, N> cc_tarjan(const abstract::image<I>& input,
+ const abstract::neighborhood<N>& ng)
+ {
+ impl::generic_cc_tarjan<T, I, N> tmp(input, ng);
+ tmp.run();
+ return tmp;
+ }
+
+
+ } // end of namespace oln::morpho
+
+} // end of namespace oln
+
+
+#endif // ! OLENA_CC_TARJAN_HH
1
0
proto-1.0 105: Fix the backward point iterator (missing property declaration)
by Simon Odou 03 Apr '05
by Simon Odou 03 Apr '05
03 Apr '05
Index: ChangeLog
from Simon Odou <simon(a)lrde.epita.fr>
* oln/core/properties.hh: Add missing property declaration for
backward point iterator and point iterator.
* oln/core/abstract/image.hh: Likewise.
abstract/image.hh | 4 ++++
properties.hh | 1 +
2 files changed, 5 insertions(+)
Index: oln/core/properties.hh
--- oln/core/properties.hh (revision 104)
+++ oln/core/properties.hh (working copy)
@@ -60,6 +60,7 @@
struct point_type;
struct concrete_type;
struct dpoint_type;
+ struct piter_type;
struct fwd_piter_type;
struct bkd_piter_type;
struct fwd_witer_type;
Index: oln/core/abstract/image.hh
--- oln/core/abstract/image.hh (revision 104)
+++ oln/core/abstract/image.hh (working copy)
@@ -64,7 +64,9 @@
mlc_decl_prop(category::image, value_type);
mlc_decl_prop(category::image, point_type);
mlc_decl_prop(category::image, size_type);
+ mlc_decl_prop(category::image, piter_type);
mlc_decl_prop(category::image, fwd_piter_type);
+ mlc_decl_prop(category::image, bkd_piter_type);
mlc_decl_prop_with_default(category::image, value_storage_type, mlc::no_type);
mlc_decl_prop_with_default(category::image, storage_type, mlc::no_type);
mlc_decl_prop_with_default(category::image, delegated_type, mlc::no_type);
@@ -101,7 +103,9 @@
mlc_register_prop(category::image, value_type);
mlc_register_prop(category::image, point_type);
mlc_register_prop(category::image, size_type);
+ mlc_register_prop(category::image, piter_type);
mlc_register_prop(category::image, fwd_piter_type);
+ mlc_register_prop(category::image, bkd_piter_type);
mlc_register_prop(category::image, value_storage_type);
mlc_register_prop(category::image, storage_type);
mlc_register_prop(category::image, delegated_type);
1
0
03 Apr '05
Index: ChangeLog
from Simon Odou <simon(a)lrde.epita.fr>
* oln/core/pw/times.hh: Add missing header.
* oln/core/pw/div.hh: Likewise.
* oln/core/pw/plus.hh: Likewise.
* oln/core/pw/minus.hh: Likewise.
* oln/core/any/dpoint.hh: Likewise.
* oln/core/any/point.hh: g++-3.4 compliance.
* oln/utils/clone.hh: Likewise.
* oln/morpho/dilation.hh: Likewise.
* oln/morpho/erosion.hh: Likewise.
core/any/dpoint.hh | 1 +
core/any/point.hh | 1 +
core/pw/div.hh | 1 +
core/pw/minus.hh | 1 +
core/pw/plus.hh | 1 +
core/pw/times.hh | 1 +
morpho/dilation.hh | 8 ++++----
morpho/erosion.hh | 8 ++++----
utils/clone.hh | 8 ++++----
9 files changed, 18 insertions(+), 12 deletions(-)
Index: oln/core/pw/times.hh
--- oln/core/pw/times.hh (revision 103)
+++ oln/core/pw/times.hh (working copy)
@@ -29,6 +29,7 @@
# define OLENA_CORE_PW_TIMES_HH
# include <oln/core/pw/abstract/function.hh>
+# include <oln/core/pw/literal.hh>
# include <ntg/all.hh>
Index: oln/core/pw/div.hh
--- oln/core/pw/div.hh (revision 103)
+++ oln/core/pw/div.hh (working copy)
@@ -29,6 +29,7 @@
# define OLENA_CORE_PW_DIV_HH
# include <oln/core/pw/abstract/function.hh>
+# include <oln/core/pw/literal.hh>
# include <ntg/all.hh>
Index: oln/core/pw/plus.hh
--- oln/core/pw/plus.hh (revision 103)
+++ oln/core/pw/plus.hh (working copy)
@@ -29,6 +29,7 @@
# define OLENA_CORE_PW_PLUS_HH
# include <oln/core/pw/abstract/function.hh>
+# include <oln/core/pw/literal.hh>
# include <ntg/all.hh>
Index: oln/core/pw/minus.hh
--- oln/core/pw/minus.hh (revision 103)
+++ oln/core/pw/minus.hh (working copy)
@@ -29,6 +29,7 @@
# define OLENA_CORE_PW_MINUS_HH
# include <oln/core/pw/abstract/function.hh>
+# include <oln/core/pw/literal.hh>
# include <ntg/all.hh>
Index: oln/core/any/point.hh
--- oln/core/any/point.hh (revision 103)
+++ oln/core/any/point.hh (working copy)
@@ -39,6 +39,7 @@
struct any_dpoint;
// category
+ template <>
struct set_category< any_point > { typedef category::point ret; };
// props
Index: oln/core/any/dpoint.hh
--- oln/core/any/dpoint.hh (revision 103)
+++ oln/core/any/dpoint.hh (working copy)
@@ -29,6 +29,7 @@
# define OLENA_CORE_ANY_DPOINT_HH
# include <oln/core/abstract/dpoint.hh>
+# include <oln/core/any/point.hh>
namespace oln {
Index: oln/utils/clone.hh
--- oln/utils/clone.hh (revision 103)
+++ oln/utils/clone.hh (working copy)
@@ -72,12 +72,12 @@
void impl_run()
{
- I tmp(input.size()); // FIXME: trick
- output = tmp;
+ I tmp(this->input.size()); // FIXME: trick
+ this->output = tmp;
- oln_type_of(I, fwd_piter) p(input.size());
+ oln_type_of(I, fwd_piter) p(this->input.size());
for_all(p)
- output[p] = input[p];
+ this->output[p] = this->input[p];
}
};
Index: oln/morpho/dilation.hh
--- oln/morpho/dilation.hh (revision 103)
+++ oln/morpho/dilation.hh (working copy)
@@ -172,12 +172,12 @@
mlc::is_true<mlc::type::eq<oln_type_of(I, size),
oln_type_of(S, size)>::ret>::ensure();
- output_type tmp(input.size()); // FIXME: trick
- output = tmp;
+ output_type tmp(this->input.size()); // FIXME: trick
+ this->output = tmp;
- oln_type_of(I, fwd_piter) p(input.size());
+ oln_type_of(I, fwd_piter) p(this->input.size());
for_all (p)
- output[p] = morpho::max(input, p, se);
+ this->output[p] = morpho::max(this->input, p, this->se);
}
};
Index: oln/morpho/erosion.hh
--- oln/morpho/erosion.hh (revision 103)
+++ oln/morpho/erosion.hh (working copy)
@@ -163,12 +163,12 @@
mlc::is_true<mlc::type::eq<oln_type_of(I, size),
oln_type_of(S, size)>::ret>::ensure();
- output_type tmp(input.size()); // FIXME: trick
- output = tmp;
+ output_type tmp(this->input.size()); // FIXME: trick
+ this->output = tmp;
- oln_type_of(I, fwd_piter) p(input.size());
+ oln_type_of(I, fwd_piter) p(this->input.size());
for_all (p)
- output[p] = morpho::min(input, p, se);
+ this->output[p] = morpho::min(this->input, p, this->se);
}
};
1
0
2005-04-02 Thierry GERAUD <theo(a)tegucigalpa.lrde.epita.fr>
* oln/core/pw/times.hh: New file.
* oln/core/pw/image.hh: New file.
* oln/core/pw/div.hh: New file.
* oln/core/pw/plus.hh: New file.
* oln/core/pw/abstract/function.hh: New file.
* oln/core/pw/all.hh: New file.
* oln/core/pw/minus.hh: New file.
* oln/core/pw/literal.hh: New file.
* oln/core/pw/cmp.hh: New file.
* oln/core/any/all.hh: New file.
* oln/core/any/point.hh: New file.
* oln/core/any/size.hh: New file.
* oln/core/any/dpoint.hh: New file.
* oln/core/abstract/point.hh (operator any_point): New.
* oln/core/abstract/size.hh: Cosmetic changes.
* oln/core/1d/size1d.hh (impl_eq(any_size)): New.
* oln/core/2d/size2d.hh (impl_eq(any_size)): New.
* oln/core/3d/size3d.hh (impl_eq(any_size)): New.
* oln/basics2d.hh: Include core/2d/fwd_piter2d and
core/2d/bkd_piter2d.
* oln/basics.hh: Include core/any/all.hh and core/pw/all.hh.
* oln/makefile.src (OLN_DEP): Add new files.
Index: oln/core/pw/times.hh
===================================================================
--- oln/core/pw/times.hh (revision 0)
+++ oln/core/pw/times.hh (revision 0)
@@ -0,0 +1,112 @@
+// Copyright (C) 2005 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, 59 Temple Place - Suite 330, 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 OLENA_CORE_PW_TIMES_HH
+# define OLENA_CORE_PW_TIMES_HH
+
+# include <oln/core/pw/abstract/function.hh>
+# include <ntg/all.hh>
+
+
+namespace oln {
+
+
+ namespace pw { // means "point-wise"
+
+ // fwd decl
+ template <typename L, typename R> struct times;
+
+ template <typename L, typename R>
+ struct traits < times<L, R> >
+ {
+ typedef oln_pw_point_type(L) point_type;
+ typedef ntg_return_type(times, oln_pw_value_type(L), oln_pw_value_type(R)) value_type;
+ typedef oln_pw_size_type(L) size_type;
+ };
+
+ template <typename L, typename R>
+ struct times : public abstract::function < times<L, R> >
+ {
+ typedef times<L, R> self_type;
+
+ typedef oln_pw_point_type(self_type) point_type;
+ typedef oln_pw_value_type(self_type) value_type;
+ typedef oln_pw_size_type(self_type) size_type;
+
+ L left;
+ R right;
+
+ times(const abstract::function<L>& left,
+ const abstract::function<R>& right) :
+ left(left.exact()),
+ right(right.exact())
+ {
+ }
+
+ const size_type& impl_size() const
+ {
+ return this->left.size();
+ }
+
+ const value_type impl_get(const point_type& p) const
+ {
+ return this->left(p) * this->right(p);
+ }
+
+ bool impl_hold(const point_type& p) const
+ {
+ return this->left.hold(p);
+ }
+
+ bool impl_hold_large(const point_type& p) const
+ {
+ return this->left.hold_large(p);
+ }
+ };
+
+ } // end of namespace oln::pw
+
+} // end of namespace oln
+
+
+/// Operator * on pwf
+
+template <typename L, typename R>
+oln::pw::times<L, R> operator * (const oln::pw::abstract::function<L>& lhs,
+ const oln::pw::abstract::function<R>& rhs)
+{
+ precondition(lhs.size() == rhs.size());
+ oln::pw::times<L, R> tmp(lhs, rhs);
+ return tmp;
+}
+
+oln_pw_operator(times, *, int)
+oln_pw_operator(times, *, float)
+oln_pw_operator(times, *, double)
+
+
+#endif // ! OLENA_CORE_PW_TIMES_HH
Index: oln/core/pw/image.hh
===================================================================
--- oln/core/pw/image.hh (revision 0)
+++ oln/core/pw/image.hh (revision 0)
@@ -0,0 +1,262 @@
+// Copyright (C) 2005 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, 59 Temple Place - Suite 330, 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 OLENA_CORE_PW_IMAGE_HH
+# define OLENA_CORE_PW_IMAGE_HH
+
+# include <mlc/any.hh>
+# include <mlc/cmp.hh>
+# include <oln/core/box.hh>
+# include <oln/core/abstract/entry.hh>
+# include <oln/core/pw/abstract/function.hh>
+
+// FIXME: remove
+# include <oln/core/2d/fwd_piter2d.hh>
+# include <oln/core/2d/bkd_piter2d.hh>
+
+
+namespace oln {
+
+
+ namespace pw { // means "point-wise"
+
+ // fwd decl
+ template <typename I> struct image;
+
+ template <typename I>
+ struct traits < image<I> >
+ {
+ typedef oln_type_of(I, point) point_type;
+ typedef oln_type_of(I, value) value_type;
+ typedef oln_type_of(I, size) size_type;
+ };
+
+ template <typename I>
+ struct image : public abstract::function < image<I> >
+ {
+ oln::box<const I> ima;
+
+ image(const oln::abstract::image<I>& ima) :
+ ima(ima)
+ {
+ }
+
+ typedef oln_type_of(I, point) point_type;
+ typedef oln_type_of(I, value) value_type;
+ typedef oln_type_of(I, size) size_type;
+
+ const size_type& impl_size() const
+ {
+ return this->ima.size();
+ }
+
+ const value_type impl_get(const point_type& p) const
+ {
+ return this->ima.get(p);
+ }
+
+ bool impl_hold(const point_type& p) const
+ {
+ return this->ima.hold(p);
+ }
+
+ bool impl_hold_large(const point_type& p) const
+ {
+ return this->ima.hold_large(p);
+ }
+
+ };
+
+ } // end of namespace oln::pw
+
+
+ /// Routine that takes an image and outputs a "point value" object
+
+ template <typename I>
+ pw::image<I> p_value(const abstract::image<I>& ima)
+ {
+ pw::image<I> tmp(ima);
+ return tmp;
+ }
+
+
+ // fwd decl
+ template <typename F> class image_from_pw;
+
+ // category
+ template <typename F>
+ struct set_category< image_from_pw<F> > { typedef category::image ret; };
+
+ // super
+ template <typename F>
+ struct set_super_type < image_from_pw<F> >
+ {
+ typedef abstract::image_entry< image_from_pw<F> > ret;
+ };
+
+ // props
+ template <typename F>
+ struct set_props < category::image, image_from_pw<F> > : public props_of <category::image>
+ {
+ typedef oln_pw_point_type(F) point_type;
+ typedef oln_pw_value_type(F) value_type;
+ typedef oln_pw_size_type(F) size_type;
+
+ typedef mlc::no_type delegated_type;
+
+ // FIXME: we do not know if it is 2d...
+ typedef is_a<abstract::image2d> image_dimension_type;
+ typedef vectorialness_from_valuetype(value_type) image_vectorialness_type;
+
+ typedef fwd_piter2d piter_type;
+ typedef fwd_piter2d fwd_piter_type;
+ typedef bkd_piter2d bkd_piter_type;
+ };
+
+
+ /// Class image_from_pw<F>.
+
+ template <typename F>
+ struct image_from_pw : public abstract::image_entry< image_from_pw<F> >
+ {
+ typedef image_from_pw<F> self_type;
+
+ F fun;
+
+ image_from_pw(const pw::abstract::function<F>& fun) :
+ fun(fun.exact())
+ {
+ this->exact_ptr = this;
+ }
+
+ image_from_pw(const self_type& rhs) :
+ fun(rhs.fun)
+ {
+ this->exact_ptr = this;
+ }
+
+ /// typedefs
+
+ typedef image_from_pw<F> self_type;
+
+ typedef oln_type_of(self_type, size) size_type;
+ typedef oln_type_of(self_type, value) value_type;
+ typedef oln_type_of(self_type, point) point_type;
+
+ const size_type& impl_size() const
+ {
+ return this->fun.size();
+ }
+
+ bool impl_hold(const point_type& p) const
+ {
+ return this->fun.hold(p);
+ }
+
+ bool impl_hold_large(const point_type& p) const
+ {
+ return this->fun.hold_large(p);
+ }
+
+ const value_type impl_get(const point_type& p) const
+ {
+ return this->fun(p);
+ }
+
+ // FIXME: remove below
+ unsigned long impl_npoints() const
+ {
+ return 1;
+ }
+ void impl_resize_border(size_t new_border, bool copy_border) const
+ {
+ }
+
+ };
+
+
+ /// Routine
+
+ template <typename F>
+ image_from_pw<F> for_all_p(const pw::abstract::function<F>& fun)
+ {
+ image_from_pw<F> tmp(fun);
+ return tmp;
+ }
+
+
+ /// Specialization of p_value (so that "p_value(for_all_p(fun)) == fun").
+
+ template <typename F>
+ F p_value(const image_from_pw<F>& ima)
+ {
+ return ima.fun;
+ }
+
+
+
+
+ /// Routine check.
+ // FIXME: this should be an algorithm (pred = binary_image)
+
+ template <typename I>
+ bool check(const abstract::image<I>& pred)
+ {
+ // FIXME: input should be binary
+ oln_type_of(I, fwd_piter) p(pred.size());
+ for_all (p)
+ if (! pred[p])
+ return false;
+ return true;
+ }
+
+
+
+ namespace pw {
+
+ /// Routine oln::pw::check.
+
+ template <typename F>
+ bool check(const pw::abstract::function<F>& pred)
+ {
+ // FIXME: ugly syntax
+ // FIXME: bool or bin or...
+ mlc::is_true<
+ mlc::type::eq< oln_pw_value_type(F), bool >::ret
+ >::ensure();
+
+ return oln::check(for_all_p(pred));
+ }
+
+ } // end of namespace oln::pw
+
+
+} // end of namespace oln
+
+
+
+#endif // ! OLENA_CORE_PW_IMAGE_HH
Index: oln/core/pw/div.hh
===================================================================
--- oln/core/pw/div.hh (revision 0)
+++ oln/core/pw/div.hh (revision 0)
@@ -0,0 +1,109 @@
+// Copyright (C) 2005 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, 59 Temple Place - Suite 330, 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 OLENA_CORE_PW_DIV_HH
+# define OLENA_CORE_PW_DIV_HH
+
+# include <oln/core/pw/abstract/function.hh>
+# include <ntg/all.hh>
+
+
+namespace oln {
+
+
+ namespace pw { // means "point-wise"
+
+ // fwd decl
+ template <typename L, typename R> struct div;
+
+ template <typename L, typename R>
+ struct traits < div<L, R> >
+ {
+ typedef oln_pw_point_type(L) point_type;
+ typedef ntg_return_type(div, oln_pw_value_type(L), oln_pw_value_type(R)) value_type;
+ typedef oln_pw_size_type(L) size_type;
+ };
+
+ template <typename L, typename R>
+ struct div : public abstract::function < div<L, R> >
+ {
+ typedef div<L, R> self_type;
+
+ typedef oln_pw_point_type(self_type) point_type;
+ typedef oln_pw_value_type(self_type) value_type;
+ typedef oln_pw_size_type(self_type) size_type;
+
+ L left;
+ R right;
+
+ div(const abstract::function<L>& left,
+ const abstract::function<R>& right) :
+ left(left.exact()),
+ right(right.exact())
+ {
+ }
+
+ const size_type& impl_size() const
+ {
+ return this->left.size();
+ }
+
+ const value_type impl_get(const point_type& p) const
+ {
+ precondition(this->right(p) != 0);
+ return this->left(p) / this->right(p);
+ }
+
+ bool impl_hold(const point_type& p) const
+ {
+ return this->left.hold(p);
+ }
+
+ bool impl_hold_large(const point_type& p) const
+ {
+ return this->left.hold_large(p);
+ }
+ };
+
+ } // end of namespace oln::pw
+
+} // end of namespace oln
+
+
+/// Operator / on pwf
+
+template <typename L, typename R>
+oln::pw::div<L, R> operator / (const oln::pw::abstract::function<L>& lhs,
+ const oln::pw::abstract::function<R>& rhs)
+{
+ precondition(lhs.size() == rhs.size());
+ oln::pw::div<L, R> tmp(lhs, rhs);
+ return tmp;
+}
+
+
+#endif // ! OLENA_CORE_PW_DIV_HH
Index: oln/core/pw/plus.hh
===================================================================
--- oln/core/pw/plus.hh (revision 0)
+++ oln/core/pw/plus.hh (revision 0)
@@ -0,0 +1,127 @@
+// Copyright (C) 2005 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, 59 Temple Place - Suite 330, 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 OLENA_CORE_PW_PLUS_HH
+# define OLENA_CORE_PW_PLUS_HH
+
+# include <oln/core/pw/abstract/function.hh>
+# include <ntg/all.hh>
+
+
+namespace oln {
+
+
+ namespace pw { // means "point-wise"
+
+ // fwd decl
+ template <typename L, typename R> struct plus;
+
+ template <typename L, typename R>
+ struct traits < plus<L, R> >
+ {
+ typedef oln_pw_point_type(L) point_type;
+ typedef ntg_return_type(plus, oln_pw_value_type(L), oln_pw_value_type(R)) value_type;
+ typedef oln_pw_size_type(L) size_type;
+ };
+
+ template <typename L, typename R>
+ struct plus : public abstract::function < plus<L, R> >
+ {
+ typedef plus<L, R> self_type;
+
+ typedef oln_pw_point_type(self_type) point_type;
+ typedef oln_pw_value_type(self_type) value_type;
+ typedef oln_pw_size_type(self_type) size_type;
+
+ L left;
+ R right;
+
+ plus(const abstract::function<L>& left,
+ const abstract::function<R>& right) :
+ left(left.exact()),
+ right(right.exact())
+ {
+ }
+
+ const size_type& impl_size() const
+ {
+ return this->left.size();
+ }
+
+ const value_type impl_get(const point_type& p) const
+ {
+ return this->left(p) + this->right(p);
+ }
+
+ bool impl_hold(const point_type& p) const
+ {
+ return this->left.hold(p);
+ }
+
+ bool impl_hold_large(const point_type& p) const
+ {
+ return this->left.hold_large(p);
+ }
+ };
+
+ } // end of namespace oln::pw
+
+} // end of namespace oln
+
+
+/// Operator + on pwf
+
+template <typename L, typename R>
+oln::pw::plus<L, R> operator + (const oln::pw::abstract::function<L>& lhs,
+ const oln::pw::abstract::function<R>& rhs)
+{
+ precondition(lhs.size() == rhs.size());
+ oln::pw::plus<L, R> tmp(lhs, rhs);
+ return tmp;
+}
+
+oln_pw_operator(plus, +, int)
+oln_pw_operator(plus, +, float)
+oln_pw_operator(plus, +, double)
+
+// template <typename L>
+// oln::pw::plus<L, oln::pw::literal<int> >
+// operator + (const oln::pw::abstract::function<L>& lhs,
+// int value)
+// {
+// return lhs + oln::pw::literal<int>(value);
+// }
+// template <typename R>
+// oln::pw::plus<oln::pw::literal<int>, R>
+// operator + (int value,
+// const oln::pw::abstract::function<R>& rhs)
+// {
+// return oln::pw::literal<int>(value) + rhs;
+// }
+
+
+#endif // ! OLENA_CORE_PW_PLUS_HH
Index: oln/core/pw/abstract/function.hh
===================================================================
--- oln/core/pw/abstract/function.hh (revision 0)
+++ oln/core/pw/abstract/function.hh (revision 0)
@@ -0,0 +1,133 @@
+// Copyright (C) 2005 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, 59 Temple Place - Suite 330, 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 OLENA_CORE_PW_ABSTRACT_FUNCTION_HH
+# define OLENA_CORE_PW_ABSTRACT_FUNCTION_HH
+
+# include <mlc/any.hh>
+# include <oln/core/properties.hh>
+
+
+# define oln_pw_point_type(T) typename oln::pw::traits<T>::point_type
+# define oln_pw_value_type(T) typename oln::pw::traits<T>::value_type
+# define oln_pw_size_type(T) typename oln::pw::traits<T>::size_type
+
+
+namespace oln {
+
+
+ namespace pw { // means "point-wise"
+
+ template <typename T> struct traits;
+
+
+ // fwd decls
+ namespace abstract {
+ template <typename E> struct function;
+ }
+ template <typename L, typename R> struct minus;
+ template <typename T> struct literal;
+
+
+
+ template <typename E>
+ struct traits < abstract::function<E> >
+ {
+ typedef oln_pw_point_type(E) point_type;
+ typedef oln_pw_value_type(E) value_type;
+ typedef oln_pw_size_type(E) size_type;
+ };
+
+ namespace abstract {
+
+ template <typename E>
+ struct function : public mlc::any<E>
+ {
+ typedef oln_pw_point_type(E) point_type;
+ typedef oln_pw_value_type(E) value_type;
+ typedef oln_pw_size_type(E) size_type;
+
+ const size_type& size() const
+ {
+ return this->exact().impl_size();
+ }
+
+ const value_type operator()(const point_type& p) const
+ {
+ return this->exact().impl_get(p);
+ }
+
+ bool hold(const point_type& p) const
+ {
+ return this->exact().impl_hold(p);
+ }
+
+ bool hold_large(const point_type& p) const
+ {
+ return this->exact().impl_hold_large(p);
+ }
+
+// minus< literal<value_type>, E> operator-() const;
+
+ protected:
+ function() {}
+
+ ~function()
+ {
+ { // impl_size
+ typedef const size_type& (E::*meth)() const;
+ meth adr = &E::impl_size;
+ adr = 0;
+ }
+ { // impl_get
+ typedef const value_type (E::*meth)(const point_type&) const;
+ meth adr = &E::impl_get;
+ adr = 0;
+ }
+ { // impl_hold
+ typedef bool (E::*meth)(const point_type&) const;
+ meth adr = &E::impl_hold;
+ adr = 0;
+ }
+ { // impl_hold_large
+ typedef bool (E::*meth)(const point_type&) const;
+ meth adr = &E::impl_hold_large;
+ adr = 0;
+ }
+
+ }
+ };
+
+ } // end of namespace oln::pw::abstract
+
+ } // end of namespace oln::pw
+
+} // end of namespace oln
+
+
+
+#endif // ! OLENA_CORE_PW_ABSTRACT_FUNCTION_HH
Index: oln/core/pw/all.hh
===================================================================
--- oln/core/pw/all.hh (revision 0)
+++ oln/core/pw/all.hh (revision 0)
@@ -0,0 +1,46 @@
+// Copyright (C) 2005 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, 59 Temple Place - Suite 330, 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 OLENA_CORE_PW_ALL_HH
+# define OLENA_CORE_PW_ALL_HH
+
+
+# include <oln/core/pw/abstract/function.hh>
+# include <oln/core/pw/image.hh>
+# include <oln/core/pw/literal.hh>
+
+# include <oln/core/pw/cmp.hh>
+
+# include <oln/core/pw/plus.hh>
+# include <oln/core/pw/minus.hh>
+# include <oln/core/pw/times.hh>
+# include <oln/core/pw/div.hh>
+
+// FIXME: not xor mod...
+
+
+#endif // ! OLENA_CORE_PW_ALL_HH
Index: oln/core/pw/minus.hh
===================================================================
--- oln/core/pw/minus.hh (revision 0)
+++ oln/core/pw/minus.hh (revision 0)
@@ -0,0 +1,126 @@
+// Copyright (C) 2005 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, 59 Temple Place - Suite 330, 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 OLENA_CORE_PW_MINUS_HH
+# define OLENA_CORE_PW_MINUS_HH
+
+# include <oln/core/pw/abstract/function.hh>
+# include <ntg/all.hh>
+
+
+namespace oln {
+
+
+ namespace pw { // means "point-wise"
+
+ // fwd decl
+ template <typename L, typename R> struct minus;
+
+ template <typename L, typename R>
+ struct traits < minus<L, R> >
+ {
+ typedef oln_pw_point_type(L) point_type;
+ typedef ntg_return_type(minus, oln_pw_value_type(L), oln_pw_value_type(R)) value_type;
+ typedef oln_pw_size_type(L) size_type;
+ };
+
+ template <typename L, typename R>
+ struct minus : public abstract::function < minus<L, R> >
+ {
+ typedef minus<L, R> self_type;
+
+ typedef oln_pw_point_type(self_type) point_type;
+ typedef oln_pw_value_type(self_type) value_type;
+ typedef oln_pw_size_type(self_type) size_type;
+
+ L left;
+ R right;
+
+ minus(const abstract::function<L>& left,
+ const abstract::function<R>& right) :
+ left(left.exact()),
+ right(right.exact())
+ {
+ }
+
+ const size_type& impl_size() const
+ {
+ return this->left.size();
+ }
+
+ const value_type impl_get(const point_type& p) const
+ {
+ return this->left(p) - this->right(p);
+ }
+
+ bool impl_hold(const point_type& p) const
+ {
+ return this->left.hold(p);
+ }
+
+ bool impl_hold_large(const point_type& p) const
+ {
+ return this->left.hold_large(p);
+ }
+
+ };
+
+
+ // FIXME: uncomment?
+
+// namespace abstract {
+
+// template <typename E>
+// minus< literal<oln_pw_value_type(E)>, E>
+// function<E>::operator-() const
+// {
+// literal<oln_pw_value_type(E)> lhs(0);
+// return lhs - *this;
+// }
+
+// }
+
+
+ } // end of namespace oln::pw
+
+} // end of namespace oln
+
+
+/// Operator - on pwf
+
+template <typename L, typename R>
+oln::pw::minus<L, R> operator - (const oln::pw::abstract::function<L>& lhs,
+ const oln::pw::abstract::function<R>& rhs)
+{
+ precondition(lhs.size() == rhs.size());
+ oln::pw::minus<L, R> tmp(lhs, rhs);
+ return tmp;
+}
+
+
+
+#endif // ! OLENA_CORE_PW_MINUS_HH
Index: oln/core/pw/literal.hh
===================================================================
--- oln/core/pw/literal.hh (revision 0)
+++ oln/core/pw/literal.hh (revision 0)
@@ -0,0 +1,120 @@
+// Copyright (C) 2005 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, 59 Temple Place - Suite 330, 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 OLENA_CORE_PW_LITERAL_HH
+# define OLENA_CORE_PW_LITERAL_HH
+
+# include <oln/core/pw/abstract/function.hh>
+# include <oln/core/any/all.hh>
+
+
+
+namespace oln {
+
+
+ namespace pw { // means "point-wise"
+
+ // fwd decl
+ template <typename T> struct literal;
+
+ template <typename T>
+ struct traits < literal<T> >
+ {
+ typedef any_point point_type;
+ typedef T value_type;
+ typedef any_size size_type;
+ };
+
+ template <typename T>
+ struct literal : public abstract::function < literal<T> >
+ {
+ typedef literal<T> self_type;
+
+ T value;
+
+ literal(T value) :
+ value(value)
+ {
+ }
+
+ const any_size& impl_size() const
+ {
+ static const any_size the;
+ return the;
+ }
+
+ const T impl_get(const any_point& p) const
+ {
+ return value;
+ }
+
+ bool impl_hold(const any_point& p) const
+ {
+ return true;
+ }
+
+ bool impl_hold_large(const any_point& p) const
+ {
+ return true;
+ }
+ };
+
+ } // end of namespace oln::pw
+
+
+ /// Routine that takes a literal and outputs a "point-wise literal" object
+
+ template <typename T>
+ pw::literal<T> p_lit(const T& value)
+ {
+ pw::literal<T> tmp(value);
+ return tmp;
+ }
+
+
+} // end of namespace oln
+
+
+# define oln_pw_operator(NAME, SYMBOL, TYPE) \
+template <typename L> \
+oln::pw::NAME<L, oln::pw::literal<TYPE> > \
+operator SYMBOL (const oln::pw::abstract::function<L>& lhs, \
+ TYPE value) \
+{ \
+ return lhs SYMBOL oln::pw::literal<TYPE>(value); \
+} \
+template <typename R> \
+oln::pw::NAME<oln::pw::literal<TYPE>, R> \
+operator SYMBOL (TYPE value, \
+ const oln::pw::abstract::function<R>& rhs) \
+{ \
+ return oln::pw::literal<TYPE>(value) SYMBOL rhs; \
+}
+
+
+
+#endif // ! OLENA_CORE_PW_LITERAL_HH
Index: oln/core/pw/cmp.hh
===================================================================
--- oln/core/pw/cmp.hh (revision 0)
+++ oln/core/pw/cmp.hh (revision 0)
@@ -0,0 +1,205 @@
+// Copyright (C) 2005 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, 59 Temple Place - Suite 330, 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 OLENA_CORE_PW_CMP_HH
+# define OLENA_CORE_PW_CMP_HH
+
+# include <oln/core/pw/abstract/function.hh>
+
+
+namespace oln {
+
+
+ namespace pw { // means "point-wise"
+
+
+ // FIXME: move somewhere else
+ namespace internal
+ {
+ struct eq {
+ template <typename L, typename R>
+ bool operator()(const L& lhs, const R& rhs) const {
+ return lhs == rhs;
+ }
+ };
+ struct neq {
+ template <typename L, typename R>
+ bool operator()(const L& lhs, const R& rhs) const {
+ return lhs != rhs;
+ }
+ };
+ struct geq {
+ template <typename L, typename R>
+ bool operator()(const L& lhs, const R& rhs) const {
+ return lhs >= rhs;
+ }
+ };
+ struct leq {
+ template <typename L, typename R>
+ bool operator()(const L& lhs, const R& rhs) const {
+ return lhs <= rhs;
+ }
+ };
+ struct g {
+ template <typename L, typename R>
+ bool operator()(const L& lhs, const R& rhs) const {
+ return lhs > rhs;
+ }
+ };
+ struct l {
+ template <typename L, typename R>
+ bool operator()(const L& lhs, const R& rhs) const {
+ return lhs < rhs;
+ }
+ };
+ }
+
+
+ // fwd decl
+ template <typename L, typename R, typename C> struct cmp;
+
+ template <typename L, typename R, typename C>
+ struct traits < cmp<L, R, C> >
+ {
+ typedef oln_pw_point_type(L) point_type;
+ typedef bool value_type;
+ typedef oln_pw_size_type(L) size_type;
+ };
+
+ template <typename L, typename R, typename C>
+ struct cmp : public abstract::function < cmp<L, R, C> >
+ {
+ typedef cmp<L, R, C> self_type;
+
+ typedef oln_pw_point_type(self_type) point_type;
+ typedef oln_pw_size_type(self_type) size_type;
+
+ L left;
+ R right;
+
+ cmp(const abstract::function<L>& left,
+ const abstract::function<R>& right) :
+ left(left.exact()),
+ right(right.exact())
+ {
+ }
+
+ const size_type& impl_size() const
+ {
+ return this->left.size();
+ }
+
+ const bool impl_get(const point_type& p) const
+ {
+ static const C cmpfun = C();
+ return cmpfun(this->left(p), this->right(p));
+ }
+
+ bool impl_hold(const point_type& p) const
+ {
+ return this->left.hold(p);
+ }
+
+ bool impl_hold_large(const point_type& p) const
+ {
+ return this->left.hold_large(p);
+ }
+
+ };
+
+ } // end of namespace oln::pw
+
+
+} // end of namespace oln
+
+
+
+/// Op+ on pwf
+
+template <typename L, typename R>
+oln::pw::cmp<L, R, oln::pw::internal::eq>
+operator == (const oln::pw::abstract::function<L>& lhs,
+ const oln::pw::abstract::function<R>& rhs)
+{
+ precondition(lhs.size() == rhs.size());
+ oln::pw::cmp<L, R, oln::pw::internal::eq> tmp(lhs, rhs);
+ return tmp;
+}
+
+template <typename L, typename R>
+oln::pw::cmp<L, R, oln::pw::internal::neq>
+operator != (const oln::pw::abstract::function<L>& lhs,
+ const oln::pw::abstract::function<R>& rhs)
+{
+ precondition(lhs.size() == rhs.size());
+ oln::pw::cmp<L, R, oln::pw::internal::neq> tmp(lhs, rhs);
+ return tmp;
+}
+
+template <typename L, typename R>
+oln::pw::cmp<L, R, oln::pw::internal::geq>
+operator >= (const oln::pw::abstract::function<L>& lhs,
+ const oln::pw::abstract::function<R>& rhs)
+{
+ precondition(lhs.size() == rhs.size());
+ oln::pw::cmp<L, R, oln::pw::internal::geq> tmp(lhs, rhs);
+ return tmp;
+}
+
+template <typename L, typename R>
+oln::pw::cmp<L, R, oln::pw::internal::leq>
+operator <= (const oln::pw::abstract::function<L>& lhs,
+ const oln::pw::abstract::function<R>& rhs)
+{
+ precondition(lhs.size() == rhs.size());
+ oln::pw::cmp<L, R, oln::pw::internal::leq> tmp(lhs, rhs);
+ return tmp;
+}
+
+template <typename L, typename R>
+oln::pw::cmp<L, R, oln::pw::internal::g>
+operator > (const oln::pw::abstract::function<L>& lhs,
+ const oln::pw::abstract::function<R>& rhs)
+{
+ precondition(lhs.size() == rhs.size());
+ oln::pw::cmp<L, R, oln::pw::internal::g> tmp(lhs, rhs);
+ return tmp;
+}
+
+template <typename L, typename R>
+oln::pw::cmp<L, R, oln::pw::internal::l>
+operator < (const oln::pw::abstract::function<L>& lhs,
+ const oln::pw::abstract::function<R>& rhs)
+{
+ precondition(lhs.size() == rhs.size());
+ oln::pw::cmp<L, R, oln::pw::internal::l> tmp(lhs, rhs);
+ return tmp;
+}
+
+
+
+#endif // ! OLENA_CORE_PW_CMP_HH
Index: oln/core/any/all.hh
===================================================================
--- oln/core/any/all.hh (revision 0)
+++ oln/core/any/all.hh (revision 0)
@@ -0,0 +1,36 @@
+// Copyright (C) 2005 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, 59 Temple Place - Suite 330, 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 OLENA_CORE_ANY_ALL_HH
+# define OLENA_CORE_ANY_ALL_HH
+
+
+# include <oln/core/any/point.hh>
+# include <oln/core/any/size.hh>
+
+
+#endif // ! OLENA_CORE_ANY_ALL_HH
Index: oln/core/any/point.hh
===================================================================
--- oln/core/any/point.hh (revision 0)
+++ oln/core/any/point.hh (revision 0)
@@ -0,0 +1,106 @@
+// Copyright (C) 2005 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, 59 Temple Place - Suite 330, 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 OLENA_CORE_ANY_POINT_HH
+# define OLENA_CORE_ANY_POINT_HH
+
+# include <oln/core/abstract/point.hh>
+# include <oln/core/abstract/dpoint.hh>
+
+
+namespace oln {
+
+ // fwd decls
+ struct any_point;
+ struct any_dpoint;
+
+ // category
+ struct set_category< any_point > { typedef category::point ret; };
+
+ // props
+ template <>
+ struct set_props < category::point, any_point > : public props_of<category::point>
+ {
+ typedef any_dpoint dpoint_type;
+ };
+
+
+ struct any_point : public abstract::point < any_point >
+ {
+
+ bool impl_eq(const exact_type& rhs) const
+ {
+ return this->exact().impl_eq(rhs.exact());
+ }
+
+ template <typename D>
+ const any_point impl_plus(const abstract::dpoint<D>& rhs) const
+ {
+ return any_point();
+ }
+
+ template <typename P>
+ const any_dpoint impl_minus(const abstract::point<P>& rhs) const;
+
+ };
+
+
+ namespace abstract {
+
+ template <typename E>
+ point<E>::operator any_point() const
+ {
+ return any_point();
+ }
+
+ } // end of namespace oln::abstract
+
+
+} // end of namespace oln
+
+
+std::ostream& operator<<(std::ostream& ostr, const oln::any_point& p)
+{
+ return ostr << "any";
+}
+
+
+# include <oln/core/any/dpoint.hh>
+
+
+namespace oln {
+
+ template <typename P>
+ const any_dpoint any_point::impl_minus(const abstract::point<P>& rhs) const
+ {
+ return any_dpoint();
+ }
+
+} // end of namespace oln
+
+
+#endif // ! OLENA_CORE_ANY_POINT_HH
Index: oln/core/any/size.hh
===================================================================
--- oln/core/any/size.hh (revision 0)
+++ oln/core/any/size.hh (revision 0)
@@ -0,0 +1,54 @@
+// Copyright (C) 2005 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, 59 Temple Place - Suite 330, 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 OLENA_CORE_ANY_SIZE_HH
+# define OLENA_CORE_ANY_SIZE_HH
+
+# include <oln/core/abstract/size.hh>
+
+namespace oln {
+
+ struct any_size : public abstract::size< any_size >
+ {
+
+ template <typename S>
+ bool impl_eq(const abstract::size<S>& rhs) const
+ {
+ return true;
+ }
+
+ // FIXME: remove below
+ unsigned long impl_npoints() const
+ {
+ return 1;
+ }
+ };
+
+} // end of namespace oln
+
+
+#endif // ! OLENA_CORE_ANY_SIZE_HH
Index: oln/core/any/dpoint.hh
===================================================================
--- oln/core/any/dpoint.hh (revision 0)
+++ oln/core/any/dpoint.hh (revision 0)
@@ -0,0 +1,90 @@
+// Copyright (C) 2005 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, 59 Temple Place - Suite 330, 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 OLENA_CORE_ANY_DPOINT_HH
+# define OLENA_CORE_ANY_DPOINT_HH
+
+# include <oln/core/abstract/dpoint.hh>
+
+
+namespace oln {
+
+
+ struct any_dpoint : public abstract::dpoint < any_dpoint >
+ {
+
+ template <typename D>
+ bool operator==(const abstract::dpoint<D>& rhs) const
+ {
+ return true;
+ }
+
+ template <typename D>
+ bool operator!=(const abstract::dpoint<D>& rhs) const
+ {
+ return false;
+ }
+
+ template <typename D>
+ const any_dpoint operator+(const abstract::dpoint<D>& rhs) const
+ {
+ return any_dpoint();
+ }
+
+ template <typename P>
+ const any_point operator+(const abstract::point<P>& rhs) const;
+
+ const any_dpoint operator-() const
+ {
+ return any_dpoint();
+ }
+
+ };
+
+} // end of namespace oln
+
+
+std::ostream& operator<<(std::ostream& ostr, const oln::any_dpoint& dp)
+{
+ return ostr << "any";
+}
+
+
+# include <oln/core/any/point.hh>
+
+
+namespace oln {
+
+ template <typename P>
+ const any_point any_dpoint::operator+(const abstract::point<P>& rhs) const
+ {
+ return any_point();
+ }
+
+}
+
+#endif // ! OLENA_CORE_ANY_DPOINT_HH
Index: oln/core/abstract/point.hh
===================================================================
--- oln/core/abstract/point.hh (revision 102)
+++ oln/core/abstract/point.hh (working copy)
@@ -40,7 +40,10 @@
namespace oln {
- // fwd decl
+ // fwd decls
+
+ struct any_point;
+
namespace abstract {
template <typename E> struct point;
}
@@ -89,6 +92,13 @@
typedef E exact_type;
+
+
+ /// Conversion to any_point (implemented in oln/core/any/point.hh).
+
+ operator any_point() const;
+
+
/*! \brief Test equality of two points. Nota bene: this method
** is abstract-like.
**
@@ -99,6 +109,12 @@
return this->exact().impl_eq(rhs.exact());
}
+// // FIXME: compiler error (cannot be overloaded)
+// bool operator==(const any_point& rhs) const
+// {
+// return true;
+// }
+
/*! \brief Test difference of two points. Nota bene: this method
** is concrete (and based on abstract::point::operator==).
**
Index: oln/core/abstract/size.hh
===================================================================
--- oln/core/abstract/size.hh (revision 102)
+++ oln/core/abstract/size.hh (working copy)
@@ -34,23 +34,27 @@
namespace abstract {
+
+ /// Abstract class for size classes.
+
template <typename E>
struct size : public mlc::any__best_memory<E>
{
+ // FIXME: remove?
unsigned long npoints() const
{
return this->exact().impl_npoints();
}
- template <typename Ep>
- bool operator==(const size<Ep>& rhs) const
+ template <typename S>
+ bool operator==(const size<S>& rhs) const
{
return this->exact().impl_eq(rhs.exact());
}
- template <typename Ep>
- bool operator!=(const size<Ep>& rhs) const
+ template <typename S>
+ bool operator!=(const size<S>& rhs) const
{
return ! this->operator==(rhs);
}
@@ -59,9 +63,15 @@
size() {}
};
+
} // end of namespace abstract
} // end of namespace oln
+
+# include <oln/core/any/size.hh>
+
+
+
#endif // ! OLENA_CORE_ABSTRACT_SIZE_HH
Index: oln/core/1d/size1d.hh
===================================================================
--- oln/core/1d/size1d.hh (revision 102)
+++ oln/core/1d/size1d.hh (working copy)
@@ -69,6 +69,11 @@
return (unsigned long)nindices_;
}
+ bool impl_eq(const any_size& rhs) const
+ {
+ return true;
+ }
+
bool impl_eq(const size1d& rhs) const
{
return this->nindices_ == rhs.nindices_;
Index: oln/core/2d/size2d.hh
===================================================================
--- oln/core/2d/size2d.hh (revision 102)
+++ oln/core/2d/size2d.hh (working copy)
@@ -73,6 +73,11 @@
return (unsigned long)nrows_ * (unsigned long)ncols_;
}
+ bool impl_eq(const any_size& rhs) const
+ {
+ return true;
+ }
+
bool impl_eq(const size2d& rhs) const
{
return this->nrows_ == rhs.nrows_ &&
Index: oln/core/3d/size3d.hh
===================================================================
--- oln/core/3d/size3d.hh (revision 102)
+++ oln/core/3d/size3d.hh (working copy)
@@ -80,6 +80,11 @@
(unsigned long)ncols_;
}
+ bool impl_eq(const any_size& rhs) const
+ {
+ return true;
+ }
+
bool impl_eq(const size3d& rhs) const
{
return this->nslices_ == rhs.nslices_ &&
Index: oln/basics2d.hh
===================================================================
--- oln/basics2d.hh (revision 102)
+++ oln/basics2d.hh (working copy)
@@ -35,6 +35,8 @@
# include <oln/core/2d/size2d.hh>
# include <oln/core/2d/point2d.hh>
# include <oln/core/2d/image2d.hh>
+# include <oln/core/2d/fwd_piter2d.hh>
+# include <oln/core/2d/bkd_piter2d.hh>
# include <oln/core/2d/fwd_witer2d.hh>
# include <oln/core/2d/window2d.hh>
# include <oln/core/2d/neighborhood2d.hh>
Index: oln/basics.hh
===================================================================
--- oln/basics.hh (revision 102)
+++ oln/basics.hh (working copy)
@@ -56,10 +56,13 @@
# include <oln/core/abstract/size.hh>
# include <oln/core/abstract/point.hh>
+# include <oln/core/any/all.hh>
# include <oln/core/abstract/images.hh>
# include <oln/core/abstract/entry.hh>
# include <oln/core/abstract/image_operator.hh>
+# include <oln/core/pw/all.hh>
+
# include <oln/core/abstract/piter.hh>
# include <oln/core/abstract/witer.hh>
// # include <oln/core/abstract/niter.hh>
@@ -68,4 +71,6 @@
# include <oln/core/abstract/neighborhood.hh>
+
+
#endif // ! OLENA_BASICS_HH
Index: oln/makefile.src
===================================================================
--- oln/makefile.src (revision 102)
+++ oln/makefile.src (working copy)
@@ -57,12 +57,25 @@
core/abstract/struct_elt.hh \
core/abstract/witer.hh \
core/accum.hh \
+ core/any/all.hh \
+ core/any/dpoint.hh \
+ core/any/point.hh \
+ core/any/size.hh \
core/apply.hh \
core/ch_value_type.hh \
core/compose.hh \
core/coord.hh \
core/gen/identity.hh \
core/properties.hh \
+ core/pw/abstract/function.hh \
+ core/pw/all.hh \
+ core/pw/cmp.hh \
+ core/pw/div.hh \
+ core/pw/image.hh \
+ core/pw/literal.hh \
+ core/pw/minus.hh \
+ core/pw/plus.hh \
+ core/pw/times.hh \
core/value_box.hh \
fancy/iota.hh \
fancy/print.hh \
1
0
01 Apr '05
oln::ch_value_type a été introduit avec ce patch, mais je ne suis
absolument pas sûr de la façon dont je l'ai écrite ; apparemment,
oln/core/properties.hh ne fournit pas autant de sucre pour les
propriétés-fonctions (ch_value_type, par ex.) que pour les propriétés
« usuelles ». Je suis preneur d'aides/explications ! :)
https://svn.lrde.epita.fr/svn/oln/prototypes/proto-1.0
ChangeLog | 17 +++++
oln/core/abstract/image.hh | 1
oln/core/abstract/image_dimension.hh | 12 +++-
oln/core/apply.hh | 102 +++++++++++++++++++++++++++++++++++
oln/core/ch_value_type.hh | 47 ++++++++++++++++
oln/makefile.src | 25 +++++---
tests/core/tests/apply | 22 +++++++
7 files changed, 213 insertions(+), 13 deletions(-)
Index: olena/ChangeLog
from Roland Levillain <roland(a)lrde.epita.fr>
First version of oln::apply, for Adapatble Unary Functions.
* oln/core/apply.hh: New file.
* oln/core/ch_value_type.hh: New file.
* oln/makefile.src (OLN_DEP): Add core/apply.hh and
core/ch_value_type.hh.
* tests/core/tests/apply: New test.
* oln/makefile.src (OLN_DEP): Add
core/abstract/image_by_delegation.hh, core/abstract/image_like_.hh,
core/abstract/image_operator.hh and core/gen/identity.hh.
Remove core/abstract/image_identity.hh.
* oln/core/abstract/image.hh (echo): Print concrete_type.
* oln/core/abstract/image_dimension.hh: Add missing comments.
Index: olena/tests/core/tests/apply
--- olena/tests/core/tests/apply (revision 0)
+++ olena/tests/core/tests/apply (revision 0)
@@ -0,0 +1,22 @@
+ // -*- C++ -*-
+#include <functional>
+#include <oln/basics2d.hh>
+#include <oln/core/apply.hh>
+#include <oln/level/fill.hh>
+#include <oln/level/compare.hh>
+#include <ntg/int.hh>
+
+
+bool check()
+{
+ oln::image2d<ntg::int_u8> ima1(10, 10);
+ oln::level::fill(ima1, 10);
+ oln::image2d<ntg::int_u8> ima2(10, 10);
+ oln::level::fill(ima2, 30);
+ oln::image2d<ntg::int_u8> ima;
+ ima = oln::apply (std::bind2nd(std::multiplies<ntg::int_u8>(), 3), ima1);
+
+ if (oln::level::is_equal(ima, ima2))
+ return false;
+ return true;
+}
Index: olena/oln/core/abstract/image.hh
--- olena/oln/core/abstract/image.hh (revision 100)
+++ olena/oln/core/abstract/image.hh (working copy)
@@ -79,6 +79,7 @@
{
ostr << "props_of(" // FIXME: << typeid(oln::category::image).name()
<< ", " << typeid(type).name() << ") = {"
+ << " concrete_type = " << typeid(concrete_type).name()
<< " value_type = " << typeid(value_type).name()
<< " point_type = " << typeid(point_type).name()
<< " size_type = " << typeid(size_type).name()
Index: olena/oln/core/abstract/image_dimension.hh
--- olena/oln/core/abstract/image_dimension.hh (revision 100)
+++ olena/oln/core/abstract/image_dimension.hh (working copy)
@@ -40,12 +40,10 @@
*/
namespace abstract {
- /*! \class abstract::image2d<E>
+ /*! \class abstract::image1d<E>
**
** Class of 1d images.
*/
-
-
template <typename E>
struct image1d : public virtual image<E>
{
@@ -56,6 +54,10 @@
image1d() {}
};
+ /*! \class abstract::image2d<E>
+ **
+ ** Class of 2d images.
+ */
template <typename E>
struct image2d : public virtual image<E>
{
@@ -66,6 +68,10 @@
image2d() {}
};
+ /*! \class abstract::image3d<E>
+ **
+ ** Class of 3d images.
+ */
template <typename E>
struct image3d : public virtual image<E>
{
Index: olena/oln/core/apply.hh
--- olena/oln/core/apply.hh (revision 0)
+++ olena/oln/core/apply.hh (revision 0)
@@ -0,0 +1,102 @@
+// Copyright (C) 2001, 2002, 2003, 2004, 2005 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, 59 Temple Place - Suite 330, 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 OLENA_CORE_APPLY_HH
+# define OLENA_CORE_APPLY_HH
+
+# include <oln/basics.hh>
+# include <oln/core/abstract/op.hh>
+# include <oln/core/ch_value_type.hh>
+
+namespace oln {
+
+ // fwd decl
+ namespace impl {
+ template <typename AdaptableUnaryFun, typename I> struct apply_type;
+ }
+
+ // category
+ template <typename AdaptableUnaryFun, typename I>
+ struct set_category< impl::apply_type<AdaptableUnaryFun, I> >
+ {
+ typedef category::image ret;
+ };
+
+ // super_type
+ template <typename AdaptableUnaryFun, typename I>
+ struct set_super_type< impl::apply_type<AdaptableUnaryFun, I> >
+ {
+ typedef typename abstract::op<I, impl::apply_type<AdaptableUnaryFun, I> >
+ ret;
+ };
+
+ namespace impl {
+
+ template <typename AdaptableUnaryFun, typename I>
+ struct apply_type :
+ public abstract::op<
+ typename ch_value_type<
+ I, typename AdaptableUnaryFun::result_type>::ret,
+ apply_type<AdaptableUnaryFun, I> >
+ {
+ typedef typename
+ ch_value_type<I, typename AdaptableUnaryFun::result_type>::ret
+ output_type;
+
+ const AdaptableUnaryFun& f_;
+ box<const I> input_;
+
+ apply_type(const AdaptableUnaryFun& f, const abstract::image<I>& input) :
+ f_ (f),
+ input_ (input.exact ())
+ {
+ }
+
+ void impl_run()
+ {
+ output_type output(input_.size());
+ oln_type_of(I, fwd_piter) p(input_.size());
+ for_all(p)
+ output[p] = f_(input_[p]);
+ this->image_ = output;
+ }
+ };
+
+ } // end of namespace impl
+
+ template <class AdaptableUnaryFun, typename I>
+ impl::apply_type<AdaptableUnaryFun, I>
+ apply (const AdaptableUnaryFun& f, const abstract::image<I>& input)
+ {
+ impl::apply_type<AdaptableUnaryFun, I> tmp (f, input);
+ tmp.run ();
+ return tmp;
+ }
+
+} // end of namespace oln
+
+#endif // ! OLENA_CORE_APPLY_HH
Index: olena/oln/core/ch_value_type.hh
--- olena/oln/core/ch_value_type.hh (revision 0)
+++ olena/oln/core/ch_value_type.hh (revision 0)
@@ -0,0 +1,47 @@
+// Copyright (C) 2005 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, 59 Temple Place - Suite 330, 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 OLENA_CORE_CH_VALUE_TYPE_HH
+# define OLENA_CORE_CH_VALUE_TYPE_HH
+
+# include <oln/core/properties.hh>
+
+namespace oln {
+
+ template<class I, class T = oln_type_of(I, value)>
+ struct ch_value_type
+ {
+ // FIXME: Use/extend oln/core/properties.hh mechanisms, instead of
+ // using mlc/properties.hh directly.
+ typedef typename
+ internal::get_props<category::image, I>::template ch_value_type<T>::ret
+ ret;
+ };
+
+} // end of namespace oln
+
+#endif // ! OLENA_CORE_CH_VALUE_TYPE_HH
Index: olena/oln/makefile.src
--- olena/oln/makefile.src (revision 100)
+++ olena/oln/makefile.src (working copy)
@@ -1,4 +1,4 @@
-##
+## -*- Makefile -*-
## List of headers in olena
## Include this file to have access to their name.
##
@@ -14,8 +14,6 @@
config/pconf.hh \
config/system.hh \
convert/value_to_point.hh \
- morpho/stat.hh \
- morpho/erosion.hh \
core/1d/array1d.hh \
core/1d/dpoint1d.hh \
core/1d/fwd_piter1d.hh \
@@ -26,39 +24,44 @@
core/2d/bkd_piter2d.hh \
core/2d/dpoint2d.hh \
core/2d/fwd_piter2d.hh \
+ core/2d/fwd_witer2d.hh \
core/2d/image2d.hh \
+ core/2d/neighborhood2d.hh \
core/2d/point2d.hh \
core/2d/size2d.hh \
- core/2d/neighborhood2d.hh \
- core/2d/fwd_witer2d.hh \
core/2d/window2d.hh \
core/3d/array3d.hh \
+ core/3d/dpoint3d.hh \
core/3d/fwd_piter3d.hh \
core/3d/image3d.hh \
core/3d/point3d.hh \
- core/3d/dpoint3d.hh \
core/3d/size3d.hh \
core/abstract/data_storage.hh \
core/abstract/dpoint.hh \
core/abstract/entry.hh \
core/abstract/image.hh \
+ core/abstract/image_by_delegation.hh \
core/abstract/image_constness.hh \
core/abstract/image_dimension.hh \
+ core/abstract/image_like_.hh \
+ core/abstract/image_operator.hh \
core/abstract/image_vectorialness.hh \
- core/abstract/image_identity.hh \
core/abstract/image_with_data.hh \
core/abstract/images.hh \
core/abstract/internal/image_impl.hh \
+ core/abstract/neighborhood.hh \
core/abstract/op.hh \
core/abstract/piter.hh \
- core/abstract/witer.hh \
core/abstract/point.hh \
core/abstract/size.hh \
- core/abstract/neighborhood.hh \
core/abstract/struct_elt.hh \
+ core/abstract/witer.hh \
core/accum.hh \
- core/coord.hh \
+ core/apply.hh \
+ core/ch_value_type.hh \
core/compose.hh \
+ core/coord.hh \
+ core/gen/identity.hh \
core/properties.hh \
core/value_box.hh \
fancy/iota.hh \
@@ -71,4 +74,6 @@
io/write_image_2d_pnm.hh \
level/compare.hh \
level/fill.hh \
+ morpho/erosion.hh \
+ morpho/stat.hh \
utils/clone.hh
Property changes on: olena/img
___________________________________________________________________
Name: svn:ignore
+ Makefile
Makefile.in
Property changes on: metalic/tests/array
___________________________________________________________________
Name: svn:ignore
+ Makefile
Makefile.in
1
0
2005-03-31 Thierry GERAUD <theo(a)tegucigalpa.lrde.epita.fr>
* oln/core/abstract/image_like_.hh: Set concrete_type property.
* oln/core/abstract/image_operator.hh: Add typedefs.
* oln/morpho/dilation.hh
(proc::dilation): New.
(impl::dilation_type): Rename as...
(dilation_ret): ...this.
(dilation_type_classic): Rename as...
(generic_dilation): ...this.
* oln/morpho/erosion.hh: Likewise.
Index: oln/core/abstract/image_like_.hh
===================================================================
--- oln/core/abstract/image_like_.hh (revision 99)
+++ oln/core/abstract/image_like_.hh (working copy)
@@ -54,9 +54,16 @@
typedef abstract::image_by_delegation<I, E> ret;
};
+ // props
+ template <typename I, typename E>
+ struct set_props < category::image, abstract::image_like_<I, E> > : public props_of<category::image>
+ {
+ typedef oln_type_of(I, concrete) concrete_type;
+ };
+
namespace abstract {
/// Mutable version of image_like_.
Index: oln/core/abstract/image_operator.hh
===================================================================
--- oln/core/abstract/image_operator.hh (revision 99)
+++ oln/core/abstract/image_operator.hh (working copy)
@@ -107,6 +107,7 @@
}
box<O> output;
+ typedef O output_type;
protected:
image_operator() {}
@@ -120,6 +121,7 @@
struct image_unary_operator : public image_operator<O, E>
{
box<const I> input;
+ typedef I input_type;
protected:
@@ -140,7 +142,10 @@
{
box<const I1> input1;
+ typedef I1 input1_type;
+
box<const I2> input2;
+ typedef I2 input2_type;
protected:
Index: oln/morpho/dilation.hh
===================================================================
--- oln/morpho/dilation.hh (revision 99)
+++ oln/morpho/dilation.hh (working copy)
@@ -31,13 +31,33 @@
# include <oln/basics.hh>
# include <oln/morpho/stat.hh>
# include <oln/core/abstract/image_operator.hh>
-// # include <oln/morpho/fast_morpho.hh>
# include <mlc/cmp.hh>
namespace oln {
namespace morpho {
+
+
+ namespace proc {
+
+ /// Dilation as a procedure (do not use it; prefer morpho::dilation).
+
+ template<typename I, typename S>
+ oln_type_of(I, concrete) dilation(const abstract::image<I>& input,
+ const abstract::struct_elt<S>& se)
+ {
+ oln_type_of(I, concrete) output(input.size());
+ oln_type_of(I, fwd_piter) p(input.size());
+ for_all (p)
+ output[p] = morpho::max(input, p, se);
+ return output;
+ }
+
+ } // end of namespace oln::morpho::proc
+
+
+
/*!
** \brief Processing dilation.
**
@@ -89,60 +109,70 @@
** \image latex oln_morpho_dilation.png
*/
- // fwd decl
- namespace impl {
- template <typename I, typename E> struct dilation_type;
- }
+ // fwd decl
+ template <typename I, typename E> struct dilation_ret;
}
// category
template <typename I, typename E>
- struct set_category< morpho::impl::dilation_type<I,E> > { typedef category::image ret; };
+ struct set_category< morpho::dilation_ret<I,E> > { typedef category::image ret; };
// super_type
template <typename I, typename E>
- struct set_super_type< morpho::impl::dilation_type<I,E> >
+ struct set_super_type< morpho::dilation_ret<I,E> >
{
- typedef abstract::image_unary_operator<I, I, morpho::impl::dilation_type<I, E> > ret; // FIXME: see below
+ typedef abstract::image_unary_operator<oln_type_of(I, concrete), I, morpho::dilation_ret<I, E> > ret;
};
+
+
namespace morpho {
- namespace impl {
+ /// Dilatation return.
- template <typename I, typename E>
- struct dilation_type : public abstract::image_unary_operator<I, I, dilation_type<I, E> >
- // FIXME: abstract::image_unary_operator<oln_type_of(I, concrete), ...
- {
- typedef abstract::image_unary_operator<I, I, dilation_type<I, E> > super_type;
+ template <typename I, typename S>
+ struct dilation_ret : public abstract::image_unary_operator<oln_type_of(I, concrete), I, dilation_ret<I, S> >
+ {
+ typedef abstract::image_unary_operator<oln_type_of(I, concrete), I, dilation_ret<I, S> > super_type;
+ typedef typename super_type::output_type output_type;
- const E se;
+ const S se;
- dilation_type(const abstract::non_vectorial_image<I>& input,
- const abstract::struct_elt<E>& se) :
- super_type(input.exact()),
- se(se.exact())
- {}
+ dilation_ret(const abstract::image<I>& input,
+ const abstract::struct_elt<S>& se) :
+ super_type(input.exact()),
+ se(se.exact())
+ {
+ }
- };
+ };
- template <typename I, typename E>
- struct dilation_type_classic : public dilation_type<I, E>
+
+ // Implementation:
+
+ namespace impl {
+
+ /// Dilation generic implementation.
+
+ template <typename I, typename S>
+ struct generic_dilation : public dilation_ret<I, S>
{
- typedef dilation_type<I, E> super_type;
+ typedef dilation_ret<I, S> super_type;
+ typedef typename super_type::output_type output_type;
- dilation_type_classic(const abstract::non_vectorial_image<I>& input,
- const abstract::struct_elt<E>& se) :
+ generic_dilation(const abstract::image<I>& input,
+ const abstract::struct_elt<S>& se) :
super_type(input, se)
- {}
+ {
+ }
void impl_run()
{
mlc::is_true<mlc::type::eq<oln_type_of(I, size),
- oln_type_of(E, size)>::ret>::ensure();
+ oln_type_of(S, size)>::ret>::ensure();
- I tmp(input.size()); // FIXME: trick
+ output_type tmp(input.size()); // FIXME: trick
output = tmp;
oln_type_of(I, fwd_piter) p(input.size());
@@ -151,29 +181,20 @@
}
};
- }
+ } // end of namespace oln::morpho::impl
- template<typename I, typename E>
- impl::dilation_type<I, E>
- dilation(const abstract::non_vectorial_image<I>& input,
- const abstract::struct_elt<E>& se)
+
+ /// Dilation generic routine.
+
+ template<typename I, typename S>
+ dilation_ret<I, S> dilation(const abstract::image<I>& input,
+ const abstract::struct_elt<S>& se)
{
- impl::dilation_type_classic<I, E> tmp(input, se);
+ impl::generic_dilation<I, S> tmp(input, se);
tmp.run();
return tmp;
}
-
-// namespace fast {
-// template<class I, class E>
-// oln_concrete_type(I)
-// dilation(const abstract::non_vectorial_image<I>& input,
-// const abstract::struct_elt<E>& se)
-// {
-// return fast_morpho<I, E, utils::histogram_max<oln_value_type(I)> >
-// (input, se);
-// }
-// }
} // end of morpho
} // end of oln
Index: oln/morpho/erosion.hh
===================================================================
--- oln/morpho/erosion.hh (revision 99)
+++ oln/morpho/erosion.hh (working copy)
@@ -30,13 +30,33 @@
# include <oln/basics.hh>
# include <oln/morpho/stat.hh>
-// # include <oln/morpho/fast_morpho.hh>
# include <oln/core/abstract/image_operator.hh>
# include <mlc/cmp.hh>
namespace oln {
namespace morpho {
+
+
+ namespace proc {
+
+ /// Erosion as a procedure (do not use it; prefer morpho::erosion).
+
+ template<typename I, typename S>
+ oln_type_of(I, concrete) dilation(const abstract::image<I>& input,
+ const abstract::struct_elt<S>& se)
+ {
+ oln_type_of(I, concrete) output(input.size());
+ oln_type_of(I, fwd_piter) p(input.size());
+ for_all (p)
+ output[p] = morpho::min(input, p, se);
+ return output;
+ }
+
+ } // end of namespace oln::morpho::proc
+
+
+
/*!
** \brief Perform a morphological erosion.
**
@@ -84,58 +104,66 @@
*/
// fwd decl
- namespace impl {
- template <typename I, typename E> struct erosion_type;
- }
+ template <typename I, typename E> struct erosion_ret;
}
// category
template <typename I, typename E>
- struct set_category< morpho::impl::erosion_type<I,E> > { typedef category::image ret; };
+ struct set_category< morpho::erosion_ret<I,E> > { typedef category::image ret; };
// super_type
template <typename I, typename E>
- struct set_super_type< morpho::impl::erosion_type<I,E> >
+ struct set_super_type< morpho::erosion_ret<I,E> >
{
- typedef abstract::image_unary_operator<I, I, morpho::impl::erosion_type<I, E> > ret; // FIXME: see below
+ typedef abstract::image_unary_operator<oln_type_of(I, concrete), I, morpho::erosion_ret<I, E> > ret;
};
+
namespace morpho {
- namespace impl {
+ /// Erosion return.
- template <typename I, typename E>
- struct erosion_type : abstract::image_unary_operator<I, I, erosion_type<I, E> >
- // FIXME: abstract::image_unary_operator<oln_type_of(I, concrete), ...
- {
- typedef abstract::image_unary_operator<I, I, erosion_type<I, E> > super_type;
- const E se;
+ template <typename I, typename E>
+ struct erosion_ret : public abstract::image_unary_operator<oln_type_of(I, concrete), I, erosion_ret<I, E> >
+ {
+ typedef abstract::image_unary_operator<oln_type_of(I, concrete), I, erosion_ret<I, E> > super_type;
+ typedef typename super_type::output_type output_type;
- erosion_type(const abstract::non_vectorial_image<I>& input,
- const abstract::struct_elt<E>& se) :
- super_type(input),
- se(se.exact())
- {}
+ const E se;
+
+ erosion_ret(const abstract::image<I>& input,
+ const abstract::struct_elt<E>& se) :
+ super_type(input),
+ se(se.exact())
+ {
+ }
+
+ };
- };
- template <typename I, typename E>
- struct erosion_type_classic : public erosion_type<I, E>
+ namespace impl {
+
+ /// Erosion generic implementation.
+
+ template <typename I, typename S>
+ struct generic_erosion : public erosion_ret<I, S>
{
- typedef erosion_type<I, E> super_type;
+ typedef erosion_ret<I, S> super_type;
+ typedef typename super_type::output_type output_type;
- erosion_type_classic(const abstract::non_vectorial_image<I>& input,
- const abstract::struct_elt<E>& se) :
+ generic_erosion(const abstract::image<I>& input,
+ const abstract::struct_elt<S>& se) :
super_type(input, se)
- {}
+ {
+ }
void impl_run()
{
mlc::is_true<mlc::type::eq<oln_type_of(I, size),
- oln_type_of(E, size)>::ret>::ensure();
+ oln_type_of(S, size)>::ret>::ensure();
- I tmp(input.size()); // FIXME: trick
+ output_type tmp(input.size()); // FIXME: trick
output = tmp;
oln_type_of(I, fwd_piter) p(input.size());
@@ -144,67 +172,24 @@
}
};
- }
+ } // end of namespace oln::morpho::impl
- template<typename I, typename E>
- impl::erosion_type<I, E>
- erosion(const abstract::non_vectorial_image<I>& input,
- const abstract::struct_elt<E>& se)
+ /// Erosion generic routine.
+
+ template<typename I, typename S>
+ erosion_ret<I, S> erosion(const abstract::image<I>& input,
+ const abstract::struct_elt<S>& se)
{
- impl::erosion_type_classic<I, E> tmp(input, se);
+ impl::generic_erosion<I, S> tmp(input, se);
tmp.run();
return tmp;
}
- namespace fast {
- /*!
- ** \brief Perform a morphological erosion.
- **
- ** Compute the morphological erosion of input using se
- ** as structuring element.
- **
- ** \param I Exact type of the input image.
- ** \param E Exact type of the structuring element.
- **
- **
- ** \arg input Input image.
- ** \arg se Structuring element to use.
- **
- ** \code
- ** #include <oln/basics2d.hh>
- ** #include <oln/morpho/erosion.hh>
- ** #include <oln/level/compare.hh>
- ** #include <ntg/all.hh>
- ** int main()
- ** {
- ** typedef oln::image2d<ntg::bin> im_type;
- **
- ** im_type im1(oln::load(IMG_IN "object.pbm"));
- ** save(oln::morpho::fast::erosion(im1, oln::win_c8p()),
- ** IMG_OUT "oln_morpho_fast_erosion.pbm");
- ** }
- ** \endcode
- **
- ** \image html object_pbm.png
- ** \image latex object_pbm.png
- ** =>
- ** \image html oln_morpho_fast_erosion.png
- ** \image latex oln_morpho_fast_erosion.png
- */
-// template<typename I, typename E>
-// oln_concrete_type(I)
-// erosion(const abstract::non_vectorial_image<I>& input,
-// const abstract::struct_elt<E>& se)
-// {
-// return fast_morpho<I, E, utils::histogram_min<oln_value_type(I)> >
-// (input, se);
-// }
- } // end of fast
- } // end of morpho
+ } // end of namespace oln::morpho
-} // end of oln
+} // end of namespace oln
#endif // ! OLENA_MORPHO_EROSION_HH
1
0
(désolé ! le système de commit auto a chié)
2005-03-31 Thierry GERAUD <theo(a)tegucigalpa.lrde.epita.fr>
* oln/core/abstract/image_like_.hh: New.
* oln/core/abstract/image_operator.hh: New.
* oln/core/abstract/image_by_delegation.hh: New.
* oln/core/abstract/image_identity.hh: Move to...
* oln/core/gen/identity.hh: here.
* tests/core/tests/image_identity: Update.
* oln/core/abstract/op.hh: Update.
* oln/core/2d/image2d.hh: Update.
* oln/core/box.hh (image()): Rename into...
* oln/core/box.hh (unbox()): this.
* oln/utils/clone.hh: Update.
* oln/basics.hh: Likewise.
* oln/morpho/dilation.hh: Likewise.
* oln/morpho/erosion.hh: Likewise.
* oln/io/read_image_2d_pnm.hh: Cosmetic change.
* oln/arith/min.hh: Likewise.
* oln/arith/max.hh: Likewise.
Index: tests/core/tests/image_identity
===================================================================
--- tests/core/tests/image_identity (revision 98)
+++ tests/core/tests/image_identity (working copy)
@@ -1,47 +1,18 @@
-#include <oln/core/abstract/image_identity.hh>
#include <oln/core/2d/image2d.hh>
+#include <oln/core/gen/identity.hh>
#include <ntg/all.hh>
-template <typename I>
-struct image_identity;
-namespace oln {
-
- template <typename I>
- struct set_category< image_identity<I> >
- {
- typedef category::image ret;
- };
-
- template <typename I>
- struct set_props < category::image, image_identity<I> >
- : public get_props < category::image, I >
- {
- typedef I delegated_type;
- };
-
-}
-
-template <typename I>
-struct image_identity : public oln::abstract::image_identity<I, image_identity<I> >
-{
- typedef oln::abstract::image_identity<I, image_identity<I> > super_type;
-
- image_identity(I& ima) : super_type(ima)
- {
- this->exact_ptr = (image_identity<I>*)(void*)(this);
- }
-};
-
-
bool check()
{
- oln::image2d<ntg::int_u8> ima(10, 10);
- image_identity<oln::image2d<ntg::int_u8> > _ima(ima);
- image_identity<image_identity<oln::image2d<ntg::int_u8> > > __ima(_ima);
- oln::point2d p(0, 0);
+ using namespace oln;
+ point2d p(0, 0);
+ image2d<ntg::int_u8> ima(10, 10);
+ internal::image_identity< image2d<ntg::int_u8> > _ima(ima);
+ internal::image_identity< internal::image_identity< image2d<ntg::int_u8> > > __ima(_ima);
+
__ima[p] = 'a';
ntg::int_u8 b = ima[p];
if (b == 'a')
Index: oln/core/abstract/image_like_.hh
===================================================================
--- oln/core/abstract/image_like_.hh (revision 0)
+++ oln/core/abstract/image_like_.hh (revision 0)
@@ -0,0 +1,99 @@
+// Copyright (C) 2005 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, 59 Temple Place - Suite 330, 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 OLENA_CORE_ABSTRACT_IMAGE_LIKE__HH
+# define OLENA_CORE_ABSTRACT_IMAGE_LIKE__HH
+
+# include <oln/core/abstract/image_by_delegation.hh>
+
+
+namespace oln {
+
+
+ // fwd decl
+ namespace abstract {
+ template <typename I, typename E> struct image_like_;
+ }
+
+ // category
+
+ template <typename I, typename E>
+ struct set_category< abstract::image_like_<I, E> > {
+ typedef category::image ret;
+ };
+
+ // super type
+
+ template <typename I, typename E>
+ struct set_super_type < abstract::image_like_<I, E> >
+ {
+ typedef abstract::image_by_delegation<I, E> ret;
+ };
+
+
+
+
+ namespace abstract {
+
+ /// Mutable version of image_like_.
+
+ template <typename I, typename E>
+ struct image_like_ : public image_by_delegation<I, E>
+ {
+ typedef image_by_delegation<I, E> super_type;
+
+ public:
+
+ image_like_ ()
+ {
+ }
+
+ image_like_(abstract::image<I>& image) :
+ super_type(image)
+ {
+ }
+
+ const I& real() const
+ {
+ return this->image_.unbox();
+ }
+
+ I& real()
+ {
+ return this->image_.unbox();
+ }
+
+ };
+
+ } // end of namespace oln::abstract
+
+
+
+} // end of namespace oln
+
+
+#endif // ! OLENA_CORE_ABSTRACT_IMAGE_LIKE__HH
Index: oln/core/abstract/image_identity.hh
===================================================================
--- oln/core/abstract/image_identity.hh (revision 98)
+++ oln/core/abstract/image_identity.hh (working copy)
@@ -1,124 +0,0 @@
-// Copyright (C) 2005 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, 59 Temple Place - Suite 330, 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 OLENA_CORE_ABSTRACT_IMAGE_IDENTITY_HH
-# define OLENA_CORE_ABSTRACT_IMAGE_IDENTITY_HH
-
-# include <mlc/box.hh>
-
-# include <oln/core/properties.hh>
-# include <oln/core/abstract/entry.hh>
-
-
-namespace oln {
-
-
- // fwd decl
- namespace abstract {
- template <typename I, typename E> struct image_identity;
- }
-
- // category
- template <typename I, typename E>
- struct set_category< abstract::image_identity<I,E> > {
- typedef category::image ret;
- };
-
- // props
- template <typename I, typename E>
- struct set_props < category::image, abstract::image_identity<I,E> >
- : public get_props< category::image, I >
- {
- typedef I delegated_type;
- };
-
-
-
- namespace abstract {
-
- template <typename I, typename E>
- struct image_identity : public abstract::image_entry<E>
- {
- protected:
-
- image_identity () {}
-
- image_identity(abstract::image<I>& image) : image_(image.exact())
- {}
-
- image_identity(const image_identity& rhs) : image_(rhs.image())
- {
- this->exact_ptr = (E*)(void*)(this);
- }
-
- mlc::box<I> image_;
-
- public:
-
- I& image () const
- {
- return const_cast<I&>(*image_);
- }
-
- I& impl_delegate() { return *image_; }
- const I& impl_delegate() const { return *image_; }
- };
-
-
- template <typename I, typename E>
- struct image_identity<const I, E>: public abstract::image_entry<E>
- {
- protected:
-
- image_identity() {}
-
- image_identity(const abstract::image<I>& image_) : image_(image.exact())
- {}
-
- image_identity(const image_identity& rhs) : image_(rhs.image())
- {
- this->exact_ptr = (E*)(void*)(this);
- }
-
- mlc::box<const I> image_;
-
- public:
- const I& image () const
- {
- return *image_;
- }
-
- I& impl_delegate() { return *image_; }
- const I& impl_delegate() const { return *image_; }
- };
-
- }
-
-}
-
-
-#endif // ! OLENA_CORE_ABSTRACT_IMAGE_IDENTITY_HH
Index: oln/core/abstract/image_operator.hh
===================================================================
--- oln/core/abstract/image_operator.hh (revision 0)
+++ oln/core/abstract/image_operator.hh (revision 0)
@@ -0,0 +1,166 @@
+// Copyright (C) 2005 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, 59 Temple Place - Suite 330, 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 OLENA_CORE_ABSTRACT_IMAGE_OPERATOR_HH
+# define OLENA_CORE_ABSTRACT_IMAGE_OPERATOR_HH
+
+# include <oln/core/abstract/image_like_.hh>
+
+namespace oln {
+
+ // fwd decls
+ namespace abstract {
+ template <typename O, typename E> struct image_operator;
+ template <typename O, typename I, typename E> struct image_unary_operator;
+ template <typename O, typename I1, typename I2, typename E> struct image_binary_operator;
+ }
+
+ // category
+ template <typename O, typename E>
+ struct set_category< abstract::image_operator<O, E> > { typedef category::image ret; };
+ template <typename O, typename I, typename E>
+ struct set_category< abstract::image_unary_operator<O, I, E> > { typedef category::image ret; };
+ template <typename O, typename I1, typename I2, typename E>
+ struct set_category< abstract::image_binary_operator<O, I1, I2, E> > { typedef category::image ret; };
+
+ // super types
+ template <typename O, typename E>
+ struct set_super_type< abstract::image_operator<O, E> > { typedef abstract::image_like_<O, E> ret; };
+ template <typename O, typename I, typename E>
+ struct set_super_type< abstract::image_unary_operator<O, I, E> > { typedef abstract::image_operator<O, E> ret; };
+ template <typename O, typename I1, typename I2, typename E>
+ struct set_super_type< abstract::image_binary_operator<O, I1, I2, E> > { typedef abstract::image_operator<O, E> ret; };
+
+
+ namespace abstract {
+
+
+ /// Class image_operator.
+ // FIXME: some methods here should be defined in a real OO abstraction
+
+ template <typename O, typename E>
+ struct image_operator : public image_like_<O, E>
+ {
+
+ /// run
+
+ void run()
+ {
+ this->impl_precondition();
+ this->impl_before_run();
+ this->impl_run();
+ this->impl_after_run();
+
+ this->image_ = this->output;
+
+ this->impl_postcondition();
+ }
+
+ virtual void impl_run()
+ {
+ // impl_run is defined here so that base operators can be instantiated
+ std::cerr << "oops: nothing done!" << std::endl;
+ }
+
+ virtual void impl_before_run()
+ {
+ // nothing
+ }
+
+ virtual void impl_after_run()
+ {
+ // nothing
+ }
+
+ virtual void impl_precondition()
+ {
+ // none
+ }
+
+ virtual void impl_postcondition()
+ {
+ // none
+ }
+
+ box<O> output;
+
+ protected:
+ image_operator() {}
+
+ };
+
+
+ /// Class image_unary_operator.
+
+ template <typename O, typename I, typename E>
+ struct image_unary_operator : public image_operator<O, E>
+ {
+ box<const I> input;
+
+ protected:
+
+ image_unary_operator() {}
+
+ image_unary_operator(const abstract::image<I>& input) :
+ input(input)
+ {
+ }
+
+ };
+
+
+ /// Class image_binary_operator.
+
+ template <typename O, typename I1, typename I2, typename E>
+ struct image_binary_operator : public image_operator<O, E>
+ {
+
+ box<const I1> input1;
+ box<const I2> input2;
+
+ protected:
+
+ image_binary_operator() {}
+
+ image_binary_operator(const abstract::image<I1>& input1,
+ const abstract::image<I2>& input2) :
+ input1(input1),
+ input2(input2)
+ {
+ }
+
+ };
+
+
+ } // end of namespace oln::abstract
+
+
+
+} // end of namespace oln
+
+
+#endif // ! OLENA_CORE_ABSTRACT_IMAGE_OPERATOR_HH
Index: oln/core/abstract/image_by_delegation.hh
===================================================================
--- oln/core/abstract/image_by_delegation.hh (revision 0)
+++ oln/core/abstract/image_by_delegation.hh (revision 0)
@@ -0,0 +1,145 @@
+// Copyright (C) 2005 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, 59 Temple Place - Suite 330, 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 OLENA_CORE_ABSTRACT_IMAGE_BY_DELEGATION_HH
+# define OLENA_CORE_ABSTRACT_IMAGE_BY_DELEGATION_HH
+
+# include <oln/core/box.hh>
+# include <oln/core/properties.hh>
+# include <oln/core/abstract/entry.hh>
+
+
+namespace oln {
+
+
+ // fwd decl
+ namespace abstract {
+ template <typename I, typename E> struct image_by_delegation;
+ }
+
+ // category
+
+ template <typename I, typename E>
+ struct set_category< abstract::image_by_delegation<I, E> > {
+ typedef category::image ret;
+ };
+
+ template <typename I, typename E>
+ struct set_category< abstract::image_by_delegation<const I, E> > {
+ typedef category::image ret;
+ };
+
+ // props
+
+ template <typename I, typename E>
+ struct set_props < category::image, abstract::image_by_delegation<I, E> >
+ : public get_props< category::image, I >
+ {
+ typedef I delegated_type;
+ };
+
+ template <typename I, typename E>
+ struct set_props < category::image, abstract::image_by_delegation<const I, E> >
+ : public get_props< category::image, I >
+ {
+ typedef I delegated_type;
+ };
+
+
+
+
+ namespace abstract {
+
+ /// Mutable version of image_by_delegation
+
+ template <typename I, typename E>
+ struct image_by_delegation : public image_entry<E>
+ {
+ protected:
+
+ image_by_delegation ()
+ {
+ this->exact_ptr = (E*)(void*)(this);
+ }
+
+ image_by_delegation(abstract::image<I>& image) :
+ image_(image.exact())
+ {
+ this->exact_ptr = (E*)(void*)(this);
+ }
+
+ image_by_delegation(const image_by_delegation& rhs) :
+ image_(rhs.image_)
+ {
+ this->exact_ptr = (E*)(void*)(this);
+ }
+
+ box<I> image_;
+
+ public:
+
+ I& impl_delegate() { return this->image_.unbox(); }
+ const I& impl_delegate() const { return this->image_.unbox(); }
+ };
+
+ /// Const version of image_by_delegation
+
+ template <typename I, typename E>
+ struct image_by_delegation<const I, E> : public image_entry<E>
+ {
+ protected:
+
+ image_by_delegation()
+ {
+ this->exact_ptr = (E*)(void*)(this);
+ }
+
+ image_by_delegation(const abstract::image<I>& ima) :
+ image_(ima.exact())
+ {
+ this->exact_ptr = (E*)(void*)(this);
+ }
+
+ image_by_delegation(const image_by_delegation& rhs) :
+ image_(rhs.image())
+ {
+ this->exact_ptr = (E*)(void*)(this);
+ }
+
+ box<const I> image_;
+
+ public:
+
+ const I& impl_delegate() const { return this->image_.unbox(); }
+ };
+
+ }
+
+}
+
+
+#endif // ! OLENA_CORE_ABSTRACT_IMAGE_BY_DELEGATION_HH
Index: oln/core/abstract/op.hh
===================================================================
--- oln/core/abstract/op.hh (revision 98)
+++ oln/core/abstract/op.hh (working copy)
@@ -29,7 +29,7 @@
# define OLENA_CORE_ABSTRACT_OP_HH
# include <oln/core/box.hh>
-# include <oln/core/abstract/image_identity.hh>
+# include <oln/core/abstract/image_like_.hh>
namespace oln {
@@ -44,15 +44,15 @@
// super_type
template <typename O, typename E>
- struct set_super_type< abstract::op<O,E> > { typedef abstract::image_identity<O, E> ret; };
+ struct set_super_type< abstract::op<O,E> > { typedef abstract::image_like_<O, E> ret; };
namespace abstract {
template <typename O, typename E>
- struct op : public image_identity<O, E>
+ struct op : public image_like_<O, E>
{
- typedef image_identity<O, E> super_type;
+ typedef image_like_<O, E> super_type;
op(O& ref) : super_type(ref)
{
Index: oln/core/2d/image2d.hh
===================================================================
--- oln/core/2d/image2d.hh (revision 98)
+++ oln/core/2d/image2d.hh (working copy)
@@ -30,7 +30,7 @@
# include <mlc/traits.hh>
-# include <oln/core/abstract/image_identity.hh>
+# include <oln/core/abstract/image_like_.hh>
# include <oln/core/abstract/image_with_data.hh>
# include <oln/core/abstract/image_vectorialness.hh>
# include <oln/core/2d/array2d.hh>
@@ -155,9 +155,10 @@
};
template <typename I, typename E>
- image2d& operator=(const abstract::image_identity<I, E>& rhs)
+ image2d& operator=(abstract::image_like_<I, E> rhs)
{
- return *this = rhs.image();
+ *this = rhs.real();
+ return *this;
}
image2d& operator=(const io::filename& rhs)
Index: oln/core/box.hh
===================================================================
--- oln/core/box.hh (revision 98)
+++ oln/core/box.hh (working copy)
@@ -117,15 +117,15 @@
/// Hooks.
-// I& image()
-// {
-// return this->image_;
-// }
+ I& unbox()
+ {
+ return this->image_;
+ }
-// const I& image() const
-// {
-// return this->image_;
-// }
+ const I& unbox() const
+ {
+ return this->image_;
+ }
private:
@@ -194,10 +194,10 @@
/// Hook.
-// const I& image() const
-// {
-// return this->image_;
-// }
+ const I& unbox() const
+ {
+ return this->image_;
+ }
private:
Index: oln/utils/clone.hh
===================================================================
--- oln/utils/clone.hh (revision 98)
+++ oln/utils/clone.hh (working copy)
@@ -28,18 +28,15 @@
#ifndef OLN_UTILS_CLONE_HH
# define OLN_UTILS_CLONE_HH
-# include <oln/core/abstract/op.hh>
-# include <oln/core/abstract/piter.hh>
+# include <oln/basics.hh>
namespace oln {
// fwd decl
namespace utils {
-
namespace impl {
template <typename I> struct clone_type;
}
-
}
// category
@@ -53,7 +50,7 @@
template <typename I>
struct set_super_type < utils::impl::clone_type<I> >
{
- typedef abstract::op<I, utils::impl::clone_type<I> > ret;
+ typedef abstract::image_unary_operator<I, I, utils::impl::clone_type<I> > ret;
};
@@ -63,40 +60,41 @@
namespace impl {
template <typename I>
- struct clone_type : abstract::op<I, clone_type<I> >
+ struct clone_type : public abstract::image_unary_operator<I, I, clone_type<I> >
+ // FIXME: use concrete_type; Cf. erosion.hh
{
- typedef abstract::op<I, clone_type<I> > super_type;
+ typedef abstract::image_unary_operator<I, I, clone_type<I> > super_type;
- box<I> input_;
-
- clone_type(I& input) :
- input_(input)
+ clone_type(const abstract::image<I>& input) :
+ super_type(input)
{
}
void impl_run()
{
- I ima(input_.size());
- oln_type_of(I, fwd_piter) p(input_.size());
+ I tmp(input.size()); // FIXME: trick
+ output = tmp;
+ oln_type_of(I, fwd_piter) p(input.size());
for_all(p)
- ima[p] = input_[p];
-
- *this->image_ = ima;
+ output[p] = input[p];
}
};
- }
+ } // end of namespace oln::utils::impl
+
template <typename I>
- impl::clone_type<I> clone(abstract::image<I>& ima)
+ impl::clone_type<I> clone(const abstract::image<I>& ima)
{
impl::clone_type<I> tmp(ima.exact());
tmp.run();
return tmp;
}
- }
-}
+ } // end of namespace oln::utils
+} // end of namespace oln
+
+
#endif // ! OLN_UTILS_CLONE_HH
Index: oln/basics.hh
===================================================================
--- oln/basics.hh (revision 98)
+++ oln/basics.hh (working copy)
@@ -52,13 +52,13 @@
# include <oln/core/coord.hh>
# include <oln/core/properties.hh>
# include <oln/core/value_box.hh>
+# include <oln/core/box.hh>
# include <oln/core/abstract/size.hh>
# include <oln/core/abstract/point.hh>
# include <oln/core/abstract/images.hh>
# include <oln/core/abstract/entry.hh>
-# include <oln/core/box.hh>
-# include <oln/core/abstract/op.hh>
+# include <oln/core/abstract/image_operator.hh>
# include <oln/core/abstract/piter.hh>
# include <oln/core/abstract/witer.hh>
Index: oln/morpho/dilation.hh
===================================================================
--- oln/morpho/dilation.hh (revision 98)
+++ oln/morpho/dilation.hh (working copy)
@@ -30,6 +30,7 @@
# include <oln/basics.hh>
# include <oln/morpho/stat.hh>
+# include <oln/core/abstract/image_operator.hh>
// # include <oln/morpho/fast_morpho.hh>
# include <mlc/cmp.hh>
@@ -103,34 +104,36 @@
template <typename I, typename E>
struct set_super_type< morpho::impl::dilation_type<I,E> >
{
- typedef abstract::op<I, morpho::impl::dilation_type<I, E> > ret;
+ typedef abstract::image_unary_operator<I, I, morpho::impl::dilation_type<I, E> > ret; // FIXME: see below
};
namespace morpho {
namespace impl {
- template <class I, class E>
- struct dilation_type : abstract::op<I, dilation_type<I, E> >
+ template <typename I, typename E>
+ struct dilation_type : public abstract::image_unary_operator<I, I, dilation_type<I, E> >
+ // FIXME: abstract::image_unary_operator<oln_type_of(I, concrete), ...
{
- box<const I> input_;
- const E se_;
+ typedef abstract::image_unary_operator<I, I, dilation_type<I, E> > super_type;
+ const E se;
+
dilation_type(const abstract::non_vectorial_image<I>& input,
- const abstract::struct_elt<E>& se) :
- input_(input.exact()),
- se_(se.exact())
+ const abstract::struct_elt<E>& se) :
+ super_type(input.exact()),
+ se(se.exact())
{}
};
- template <class I, class E>
- struct dilation_type_classic : dilation_type<I, E>
+ template <typename I, typename E>
+ struct dilation_type_classic : public dilation_type<I, E>
{
typedef dilation_type<I, E> super_type;
dilation_type_classic(const abstract::non_vectorial_image<I>& input,
- const abstract::struct_elt<E>& se) :
+ const abstract::struct_elt<E>& se) :
super_type(input, se)
{}
@@ -138,25 +141,22 @@
{
mlc::is_true<mlc::type::eq<oln_type_of(I, size),
oln_type_of(E, size)>::ret>::ensure();
- I output(this->input_.size());
- // FIXME: see erosion.hh
- this->input_.resize_border(this->se_.get_delta());
+ I tmp(input.size()); // FIXME: trick
+ output = tmp;
- oln_type_of(I, fwd_piter) p(this->input_.size());
-
+ oln_type_of(I, fwd_piter) p(input.size());
for_all (p)
- output[p] = morpho::max(this->input_, p, this->se_);
- *this->image_ = output;
+ output[p] = morpho::max(input, p, se);
}
};
}
- template<class I, class E>
+ template<typename I, typename E>
impl::dilation_type<I, E>
dilation(const abstract::non_vectorial_image<I>& input,
- const abstract::struct_elt<E>& se)
+ const abstract::struct_elt<E>& se)
{
impl::dilation_type_classic<I, E> tmp(input, se);
tmp.run();
Index: oln/morpho/erosion.hh
===================================================================
--- oln/morpho/erosion.hh (revision 98)
+++ oln/morpho/erosion.hh (working copy)
@@ -31,7 +31,7 @@
# include <oln/basics.hh>
# include <oln/morpho/stat.hh>
// # include <oln/morpho/fast_morpho.hh>
-# include <oln/core/abstract/op.hh>
+# include <oln/core/abstract/image_operator.hh>
# include <mlc/cmp.hh>
namespace oln {
@@ -98,29 +98,30 @@
template <typename I, typename E>
struct set_super_type< morpho::impl::erosion_type<I,E> >
{
- typedef abstract::op<I, morpho::impl::erosion_type<I, E> > ret;
+ typedef abstract::image_unary_operator<I, I, morpho::impl::erosion_type<I, E> > ret; // FIXME: see below
};
namespace morpho {
namespace impl {
- template <class I, class E>
- struct erosion_type : abstract::op<I, erosion_type<I, E> >
+ template <typename I, typename E>
+ struct erosion_type : abstract::image_unary_operator<I, I, erosion_type<I, E> >
+ // FIXME: abstract::image_unary_operator<oln_type_of(I, concrete), ...
{
- box<const I> input_;
- const E se_;
+ typedef abstract::image_unary_operator<I, I, erosion_type<I, E> > super_type;
+ const E se;
erosion_type(const abstract::non_vectorial_image<I>& input,
const abstract::struct_elt<E>& se) :
- input_(input.exact()),
- se_(se.exact())
+ super_type(input),
+ se(se.exact())
{}
};
- template <class I, class E>
- struct erosion_type_classic : erosion_type<I, E>
+ template <typename I, typename E>
+ struct erosion_type_classic : public erosion_type<I, E>
{
typedef erosion_type<I, E> super_type;
@@ -133,26 +134,20 @@
{
mlc::is_true<mlc::type::eq<oln_type_of(I, size),
oln_type_of(E, size)>::ret>::ensure();
- I output(this->input_.size());
- // FIXME: not only resize but also set values in border!
- // FIXME: code commented below cause only valid with bordered_image
+ I tmp(input.size()); // FIXME: trick
+ output = tmp;
- this->input_.resize_border(this->se_.get_delta());
-
- oln_type_of(I, fwd_piter) p(this->input_.size());
-
+ oln_type_of(I, fwd_piter) p(input.size());
for_all (p)
- output[p] = morpho::min(this->input_, p, this->se_);
- // FIXME: remove * below (oln::box)
- *this->image_ = output;
+ output[p] = morpho::min(input, p, se);
}
};
}
- template<class I, class E>
+ template<typename I, typename E>
impl::erosion_type<I, E>
erosion(const abstract::non_vectorial_image<I>& input,
const abstract::struct_elt<E>& se)
@@ -197,7 +192,7 @@
** \image html oln_morpho_fast_erosion.png
** \image latex oln_morpho_fast_erosion.png
*/
-// template<class I, class E>
+// template<typename I, typename E>
// oln_concrete_type(I)
// erosion(const abstract::non_vectorial_image<I>& input,
// const abstract::struct_elt<E>& se)
Index: oln/io/read_image_2d_pnm.hh
===================================================================
--- oln/io/read_image_2d_pnm.hh (revision 98)
+++ oln/io/read_image_2d_pnm.hh (working copy)
@@ -74,8 +74,7 @@
namespace impl {
template <typename I>
- struct read_image_2d_raw :
- public oln::abstract::op<I, read_image_2d_raw<I> >
+ struct read_image_2d_raw : public oln::abstract::op<I, read_image_2d_raw<I> >
{
typedef oln::abstract::op<I, read_image_2d_raw<I> > super_type;
Index: oln/arith/min.hh
===================================================================
--- oln/arith/min.hh (revision 98)
+++ oln/arith/min.hh (working copy)
@@ -29,6 +29,7 @@
# define OLENA_ARITH_MIN_HH
# include <oln/basics.hh>
+# include <oln/core/abstract/op.hh>
# include <ntg/all.hh>
namespace oln {
@@ -60,7 +61,7 @@
namespace impl {
template <class I>
- struct min_type : abstract::op<I, min_type<I> >
+ struct min_type : public abstract::op<I, min_type<I> >
{
box<const I> input1_;
box<const I> input2_;
@@ -80,7 +81,7 @@
for_all(p)
output[p] = ntg::min(input1_[p].value(), input2_[p].value());
- *this->image_ = output;
+ this->image_ = output;
}
};
Index: oln/arith/max.hh
===================================================================
--- oln/arith/max.hh (revision 98)
+++ oln/arith/max.hh (working copy)
@@ -29,6 +29,7 @@
# define OLENA_ARITH_MAX_HH
# include <oln/basics.hh>
+# include <oln/core/abstract/op.hh>
# include <ntg/all.hh>
namespace oln {
@@ -60,7 +61,7 @@
namespace impl {
template <class I>
- struct max_type : abstract::op<I, max_type<I> >
+ struct max_type : public abstract::op<I, max_type<I> >
{
box<const I> input1_;
box<const I> input2_;
@@ -80,7 +81,7 @@
for_all(p)
output[p] = ntg::max(input1_[p].value(), input2_[p].value());
- *this->image_ = output; // FIXME: remove * when image_ is oln::box
+ this->image_ = output;
}
};
1
0
hop :
---
:from: Thierry Geraud <theo(a)lrde.epita.fr>
:server:
:subject: "proto-1.0 98: Use oln::box"
:groups:
- lrde.olena.patches
---
Index: ChangeLog
from Thierry Geraud <theo(a)lrde.epita.fr>
* oln/core/box.hh: New.
* oln/core/abstract/image.hh
(resize_border): Temporary method to pass make check.
* oln/core/abstract/image_with_data.hh: Update.
* oln/core/abstract/op.hh: Likewise.
* oln/utils/clone.hh: Likewise.
* oln/basics.hh: Likewise.
* oln/morpho/dilation.hh: Likewise.
* oln/morpho/erosion.hh: Likewise.
* oln/arith/min.hh: Likewise.
* oln/arith/max.hh: Likewise.
* oln/morpho/stat.hh: Add test (hold) to pass make check.
arith/max.hh | 14 +-
arith/min.hh | 14 +-
basics.hh | 2
core/abstract/image.hh | 17 ++-
core/abstract/image_with_data.hh | 2
core/abstract/op.hh | 1
core/box.hh | 212 +++++++++++++++++++++++++++++++++++++++
morpho/dilation.hh | 15 +-
morpho/erosion.hh | 18 ++-
morpho/stat.hh | 20 ++-
utils/clone.hh | 18 +--
11 files changed, 288 insertions(+), 45 deletions(-)
Index: oln/core/abstract/image.hh
--- oln/core/abstract/image.hh (revision 97)
+++ oln/core/abstract/image.hh (working copy)
@@ -303,6 +303,14 @@
return this->exact().impl_get(p);
}
+
+ // FIXME: patch!
+
+ void resize_border(size_t new_border, bool copy_border = false) const
+ {
+ this->exact().impl_resize_border(new_border, copy_border);
+ }
+
protected:
/*! \brief Constructor (protected, empty).
@@ -382,9 +390,16 @@
const value_type impl_get(const point_type& p) const
{
this->exact().impl_get_extra(p);
- return this->delegate().impl_get(p);
+ return this->delegate().get(p);
}
+ // FIXME: patch
+
+ void impl_resize_border(size_t new_border, bool copy_border) const
+ {
+ this->delegate().impl_resize_border(new_border, copy_border);
+ }
+
// extra code; default is "do nothing"
void impl_size_extra(const size_type& s) const {}
Index: oln/core/abstract/image_with_data.hh
--- oln/core/abstract/image_with_data.hh (revision 97)
+++ oln/core/abstract/image_with_data.hh (working copy)
@@ -179,7 +179,7 @@
return data_ != 0;
}
- void resize_border(size_t new_border, bool copy_border = false) const
+ void impl_resize_border(size_t new_border, bool copy_border) const
{
(const_cast<storage_type&>(*this->data_)).resize_border(new_border, copy_border);
}
Index: oln/core/abstract/op.hh
--- oln/core/abstract/op.hh (revision 97)
+++ oln/core/abstract/op.hh (working copy)
@@ -28,6 +28,7 @@
#ifndef OLENA_CORE_ABSTRACT_OP_HH
# define OLENA_CORE_ABSTRACT_OP_HH
+# include <oln/core/box.hh>
# include <oln/core/abstract/image_identity.hh>
namespace oln {
Index: oln/core/box.hh
--- oln/core/box.hh (revision 0)
+++ oln/core/box.hh (revision 0)
@@ -0,0 +1,212 @@
+// Copyright (C) 2005 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, 59 Temple Place - Suite 330, 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 OLENA_CORE_BOX_HH
+# define OLENA_CORE_BOX_HH
+
+# include <oln/core/properties.hh>
+# include <oln/core/abstract/entry.hh>
+
+namespace oln {
+
+
+ // fwd decl
+ template <typename I> struct box;
+
+ // category
+
+ template <typename I>
+ struct set_category< box<I> > {
+ typedef category::image ret;
+ };
+
+ template <typename I>
+ struct set_category< box<const I> > {
+ typedef category::image ret;
+ };
+
+ // props
+
+ template <typename I>
+ struct set_props < category::image, box<I> >
+ : public get_props< category::image, I >
+ {
+ typedef I delegated_type;
+ };
+
+ template <typename I>
+ struct set_props < category::image, box<const I> >
+ : public get_props< category::image, I >
+ {
+ typedef I delegated_type;
+ };
+
+
+ /// Class oln::box...
+
+ template <typename I>
+ struct box : public abstract::image_entry< box<I> >
+ {
+ public:
+
+ box () :
+ image_()
+ {
+ this->exact_ptr = this;
+ }
+
+ box(abstract::image<I>& ima) :
+ image_(ima.exact())
+ {
+ this->exact_ptr = this;
+ }
+
+ box<I>& operator=(abstract::image<I>& rhs)
+ {
+ this->image_ = rhs.exact();
+ return *this;
+ }
+
+ box(const box<I>& rhs) :
+ image_(const_cast<I&>(rhs.image_))
+ {
+ this->exact_ptr = this;
+ }
+
+ box<I> operator=(const box<I>& rhs)
+ {
+ this->image_ = const_cast<I&>(rhs.image_);
+ return *this;
+ }
+
+ // FIXME: add versions for I2 (neq I) to produce explicit errors
+
+ I& impl_delegate()
+ {
+ return this->image_;
+ }
+
+ const I& impl_delegate() const
+ {
+ return this->image_;
+ }
+
+ /// Hooks.
+
+// I& image()
+// {
+// return this->image_;
+// }
+
+// const I& image() const
+// {
+// return this->image_;
+// }
+
+ private:
+
+ /// attribute
+ mutable I image_;
+
+ };
+
+
+ template <typename I>
+ struct box<const I> : public abstract::image_entry< box<const I> >
+ {
+ public:
+
+ box() :
+ image_()
+ {
+ this->exact_ptr = this;
+ }
+
+ box(const abstract::image<I>& ima) :
+ image_(const_cast<I&>(ima.exact()))
+ {
+ this->exact_ptr = this;
+ }
+
+ box<const I> operator=(const abstract::image<I>& rhs)
+ {
+ this->image_ = const_cast<I&>(rhs.exact());
+ return *this;
+ }
+
+ /// Classical copy ctor (image remains const).
+ box(const box<const I>& rhs) :
+ image_(const_cast<I&>(rhs.image_))
+ {
+ this->exact_ptr = this;
+ }
+
+ /// Classical op= (image remains const).
+ box<const I> operator=(const box<const I>& rhs)
+ {
+ this->image_ = const_cast<I&>(rhs.image_);
+ return *this;
+ }
+
+ /// Copy ctor with promotion (image becomes const).
+ box(const box<I>& rhs) :
+ image_(const_cast<I&>(rhs.image_))
+ {
+ this->exact_ptr = this;
+ }
+
+ /// Op= with promotion (image becomes const).
+ box<const I> operator=(const box<I>& rhs)
+ {
+ this->image_ = const_cast<I&>(rhs.image_);
+ return *this;
+ }
+
+ /// Delegation relies on a constant image.
+ const I& impl_delegate() const
+ {
+ return this->image_;
+ }
+
+ /// Hook.
+
+// const I& image() const
+// {
+// return this->image_;
+// }
+
+ private:
+
+ /// attribute
+ mutable I image_;
+
+ };
+
+}
+
+
+#endif // ! OLENA_CORE_BOX_HH
Index: oln/utils/clone.hh
--- oln/utils/clone.hh (revision 97)
+++ oln/utils/clone.hh (working copy)
@@ -67,20 +67,20 @@
{
typedef abstract::op<I, clone_type<I> > super_type;
- mlc::box<I> input_;
+ box<I> input_;
- clone_type(I& input) : input_(input)
- {}
+ clone_type(I& input) :
+ input_(input)
+ {
+ }
void impl_run()
{
- I ima(input_->size());
- oln_type_of(I, fwd_piter) it(input_->size());
+ I ima(input_.size());
+ oln_type_of(I, fwd_piter) p(input_.size());
- for_all(it)
- {
- ima[it] = (*input_)[it];
- }
+ for_all(p)
+ ima[p] = input_[p];
*this->image_ = ima;
}
Index: oln/basics.hh
--- oln/basics.hh (revision 97)
+++ oln/basics.hh (working copy)
@@ -43,7 +43,6 @@
# include <mlc/traits.hh>
# include <mlc/any.hh>
# include <mlc/types.hh>
-# include <mlc/box.hh>
// ntg::
@@ -58,6 +57,7 @@
# include <oln/core/abstract/point.hh>
# include <oln/core/abstract/images.hh>
# include <oln/core/abstract/entry.hh>
+# include <oln/core/box.hh>
# include <oln/core/abstract/op.hh>
# include <oln/core/abstract/piter.hh>
Index: oln/morpho/dilation.hh
--- oln/morpho/dilation.hh (revision 97)
+++ oln/morpho/dilation.hh (working copy)
@@ -113,8 +113,8 @@
template <class I, class E>
struct dilation_type : abstract::op<I, dilation_type<I, E> >
{
- mlc::box<const I> input_;
- mlc::box<const E> se_;
+ box<const I> input_;
+ const E se_;
dilation_type(const abstract::non_vectorial_image<I>& input,
const abstract::struct_elt<E>& se) :
@@ -138,12 +138,15 @@
{
mlc::is_true<mlc::type::eq<oln_type_of(I, size),
oln_type_of(E, size)>::ret>::ensure();
- I output(this->input_->size());
- this->input_->resize_border(this->se_->get_delta());
- oln_type_of(I, fwd_piter) p(this->input_->size());
+ I output(this->input_.size());
+ // FIXME: see erosion.hh
+ this->input_.resize_border(this->se_.get_delta());
+
+ oln_type_of(I, fwd_piter) p(this->input_.size());
+
for_all (p)
- output[p] = morpho::max(*this->input_, p, *this->se_);
+ output[p] = morpho::max(this->input_, p, this->se_);
*this->image_ = output;
}
};
Index: oln/morpho/stat.hh
--- oln/morpho/stat.hh (revision 97)
+++ oln/morpho/stat.hh (working copy)
@@ -71,8 +71,9 @@
dp.start();
V val = input[p + dp];
for_all_remaining (dp)
- if (val < input[p + dp].value())
- val = input[p + dp].value();
+ if (input.hold(p + dp))
+ if (val < input[p + dp].value())
+ val = input[p + dp].value();
return val;
}
@@ -97,8 +98,9 @@
dp.start();
V val = input[p + dp];
for_all_remaining (dp)
- if (val > input[p + dp].value())
- val = input[p + dp].value();
+ if (input.hold(p + dp))
+ if (val > input[p + dp].value())
+ val = input[p + dp].value();
return val;
}
@@ -116,8 +118,9 @@
oln_type_of(E, size)>::ret>::ensure();
oln_type_of(E, fwd_witer) dp(se);
for_all (dp)
- if (input[p + dp] == true)
- return true;
+ if (input.hold(p + dp))
+ if (input[p + dp] == true)
+ return true;
return false;
}
@@ -128,8 +131,9 @@
oln_type_of(E, size)>::ret>::ensure();
oln_type_of(E, fwd_witer) dp(se);
for_all (dp)
- if (input[p + dp] == false)
- return false;
+ if (input.hold(p + dp))
+ if (input[p + dp] == false)
+ return false;
return true;
}
Index: oln/morpho/erosion.hh
--- oln/morpho/erosion.hh (revision 97)
+++ oln/morpho/erosion.hh (working copy)
@@ -108,8 +108,8 @@
template <class I, class E>
struct erosion_type : abstract::op<I, erosion_type<I, E> >
{
- mlc::box<const I> input_;
- mlc::box<const E> se_;
+ box<const I> input_;
+ const E se_;
erosion_type(const abstract::non_vectorial_image<I>& input,
const abstract::struct_elt<E>& se) :
@@ -133,12 +133,18 @@
{
mlc::is_true<mlc::type::eq<oln_type_of(I, size),
oln_type_of(E, size)>::ret>::ensure();
- I output(this->input_->size());
- this->input_->resize_border(this->se_->get_delta());
- oln_type_of(I, fwd_piter) p(this->input_->size());
+ I output(this->input_.size());
+ // FIXME: not only resize but also set values in border!
+ // FIXME: code commented below cause only valid with bordered_image
+
+ this->input_.resize_border(this->se_.get_delta());
+
+ oln_type_of(I, fwd_piter) p(this->input_.size());
+
for_all (p)
- output[p] = morpho::min(*this->input_, p, *this->se_);
+ output[p] = morpho::min(this->input_, p, this->se_);
+ // FIXME: remove * below (oln::box)
*this->image_ = output;
}
};
Index: oln/arith/min.hh
--- oln/arith/min.hh (revision 97)
+++ oln/arith/min.hh (working copy)
@@ -62,8 +62,8 @@
template <class I>
struct min_type : abstract::op<I, min_type<I> >
{
- mlc::box<const I> input1_;
- mlc::box<const I> input2_;
+ box<const I> input1_;
+ box<const I> input2_;
min_type(const abstract::non_vectorial_image<I>& input1,
const abstract::non_vectorial_image<I>& input2) :
@@ -73,12 +73,12 @@
void impl_run()
{
- precondition(input1_->size() == input2_->size());
- I output(input1_->size());
- oln_type_of(I, fwd_piter) p(input1_->size());
+ precondition(input1_.size() == input2_.size());
+ I output(input1_.size());
+ oln_type_of(I, fwd_piter) p(input1_.size());
for_all(p)
- output[p] = ntg::min((*input1_)[p].value(), (*input2_)[p].value());
+ output[p] = ntg::min(input1_[p].value(), input2_[p].value());
*this->image_ = output;
}
@@ -87,6 +87,8 @@
}
+ // FIXME: replace non_vectorial_image by scalar_image
+ // FIXME: cause arithmetics is not defined for Booleans and labels...
template <typename I>
impl::min_type<I> min(const abstract::non_vectorial_image<I>& input1,
const abstract::non_vectorial_image<I>& input2)
Index: oln/arith/max.hh
--- oln/arith/max.hh (revision 97)
+++ oln/arith/max.hh (working copy)
@@ -62,8 +62,8 @@
template <class I>
struct max_type : abstract::op<I, max_type<I> >
{
- mlc::box<const I> input1_;
- mlc::box<const I> input2_;
+ box<const I> input1_;
+ box<const I> input2_;
max_type(const abstract::non_vectorial_image<I>& input1,
const abstract::non_vectorial_image<I>& input2) :
@@ -73,14 +73,14 @@
void impl_run()
{
- precondition(input1_->size() == input2_->size());
- I output(input1_->size());
- oln_type_of(I, fwd_piter) p(input1_->size());
+ precondition(input1_.size() == input2_.size());
+ I output(input1_.size());
+ oln_type_of(I, fwd_piter) p(input1_.size());
for_all(p)
- output[p] = ntg::max((*input1_)[p].value(), (*input2_)[p].value());
+ output[p] = ntg::max(input1_[p].value(), input2_[p].value());
- *this->image_ = output;
+ *this->image_ = output; // FIXME: remove * when image_ is oln::box
}
};
1
0
Index: ChangeLog
from Damien Thivolle <damien(a)lrde.epita.fr>
* oln/core/abstract/piter.hh: Correct for_all.
piter.hh | 2 +-
1 files changed, 1 insertion(+), 1 deletion(-)
Index: oln/core/abstract/piter.hh
--- oln/core/abstract/piter.hh (revision 64)
+++ oln/core/abstract/piter.hh (working copy)
@@ -37,7 +37,7 @@
-# define for_all(P) for(p.start(); p.is_valid(); p.next())
+# define for_all(p) for(p.start(); p.is_valid(); p.next())
namespace oln {
2
2