Index: ChangeLog
from Nicolas Ballas <ballas(a)lrde.epita.fr>
fix a bug on rle_encode, add a test.
* olena/tests/core/3dtorle.cc: New test.
* olena/tests/core/rle_image.cc: Update test.
* olena/tests/core/Makefile.am: Update.
* olena/oln/core/gen/rle_image.hh,
* olena/oln/core/gen/rle_encode.hh: fix a bug.
* olena/oln/core/concept/iterator_on_values.hh: change vit.to_point() to vit.to_value().
* olena/oln/core/internal/encoded_image.hh: small modifications.
oln/core/concept/iterator_on_values.hh | 2
oln/core/gen/rle_encode.hh | 20 ++++++-
oln/core/gen/rle_image.hh | 1
oln/core/internal/encoded_image.hh | 2
tests/core/3dtorle.cc | 91 +++++++++++++++++++++++++++++++++
tests/core/Makefile.am | 4 +
tests/core/rle_image.cc | 6 ++
7 files changed, 121 insertions(+), 5 deletions(-)
Index: olena/tests/core/3dtorle.cc
--- olena/tests/core/3dtorle.cc (revision 0)
+++ olena/tests/core/3dtorle.cc (revision 0)
@@ -0,0 +1,91 @@
+// Copyright (C) 2006 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#include <cassert>
+#include <cmath>
+#include <oln/core/3d/image3d.hh>
+#include <oln/level/fill.hh>
+#include <oln/debug/print.hh>
+#include <ostream>
+#include <oln/core/gen/rle_image.hh>
+#include <oln/core/gen/rle_encode.hh>
+
+float my_sinus(const oln::point3d& p)
+{
+ return sin(p.sli() + p.row() + p.col());
+}
+
+
+int
+main()
+{
+ using namespace oln;
+
+ // Fill a 3D image with a cos.
+ image3d<float> ima3d(100, 100, 100);
+
+ level::fill(inplace(ima3d), my_sinus);
+
+
+ // Transform it into a 3 states image
+ // value < 0 => -1
+ // value > 0 => 1
+ // value next to 0 => 0
+ image3d<short> ima3s(100, 100, 100);
+ image3d<float>::piter p(ima3d.points());
+ for_all(p)
+ {
+ if (ima3d(p) < 0.05 && ima3d(p) > -0.05)
+ ima3s(p) = 0;
+ else
+ {
+ if (ima3d(p) < 0)
+ ima3s(p) = -1;
+ else
+ ima3s(p) = 1;
+ }
+ }
+
+// oln::debug::print(ima3s);
+// std::cout << std::endl;
+
+ // Encode ima3s into a rle_image
+ rle_image<point3d, short> ima3rle;
+
+
+ ima3rle = rle_encode(ima3s);
+ rle_image<point3d, short>::piter p1(ima3rle.points());
+// std::cout << "start test" << std::endl;
+// for_all(p1)
+// {
+// // std::cout << "point: " << p1.to_point() << std::endl;
+// // std::cout << "3s : " << ima3s(p1) << std::endl;
+// // std::cout << "rle: " << ima3rle(p1) << std::endl;
+// assert(ima3s(p1) == ima3rle(p1));
+// }
+
+}
Index: olena/tests/core/rle_image.cc
--- olena/tests/core/rle_image.cc (revision 953)
+++ olena/tests/core/rle_image.cc (working copy)
@@ -44,6 +44,12 @@
rle2 = rle_encode(ima2d);
+ oln::rle_image<oln::point2d, int>::piter p1(rle2.points());
+ for_all(p1)
+ {
+ assert(ima2d(p1) == rle2(p1));
+ }
+
// oln::debug::print(rle2);
// std::cout << std::endl;
Index: olena/tests/core/Makefile.am
--- olena/tests/core/Makefile.am (revision 953)
+++ olena/tests/core/Makefile.am (working copy)
@@ -35,7 +35,8 @@
sparse_image \
stack \
subset \
- window2d
+ window2d \
+ 3dtorle
# Images and auxiliary structures.
@@ -54,6 +55,7 @@
stack_SOURCES = stack.cc
subset_SOURCES = subset.cc
window2d_SOURCES = window2d.cc
+3dtorle_SOURCES = 3dtorle.cc
# Methods.
at_SOURCES = at.cc
Index: olena/oln/core/gen/rle_image.hh
--- olena/oln/core/gen/rle_image.hh (revision 953)
+++ olena/oln/core/gen/rle_image.hh (working copy)
@@ -85,7 +85,6 @@
void insert(const point& p, unsigned len, value val);
rvalue impl_read(const psite& p) const;
lvalue impl_read_write(const psite& p);
-
};
# ifndef OLN_INCLUDE_ONLY
Index: olena/oln/core/gen/rle_encode.hh
--- olena/oln/core/gen/rle_encode.hh (revision 953)
+++ olena/oln/core/gen/rle_encode.hh (working copy)
@@ -38,6 +38,22 @@
{
/*!
+ ** test if Point p1 and p2 are on the same line
+ */
+ template <typename P>
+ bool
+ on_the_same_line(P p1, P p2)
+ {
+ unsigned dim = mlc_value(typename P::grid::dim);
+ bool same_line = true;
+
+ for (int n = dim - 1; same_line && n > 0; --n)
+ same_line = p1[n] == p2[n];
+ return same_line;
+ }
+
+
+ /*!
** encode an image class to a rle_image
**
** @param input has to respect the Image concept
@@ -49,7 +65,7 @@
rle_encode(const Image<I>& input)
{
rle_image<typename I::point, typename I::value> output;
- typename I::piter p (input.points());
+ typename Image<I>::piter p (input.points());
unsigned len = 1;
/// range point start
typename I::point rstart;
@@ -65,7 +81,7 @@
p.next();
while (p.is_valid())
{
- if (rvalue == input(p))
+ if (rvalue == input(p) && on_the_same_line(rstart, p.to_point()))
++len;
else
{
Index: olena/oln/core/concept/iterator_on_values.hh
--- olena/oln/core/concept/iterator_on_values.hh (revision 953)
+++ olena/oln/core/concept/iterator_on_values.hh (working copy)
@@ -85,7 +85,7 @@
template <typename Exact>
std::ostream& operator<<(std::ostream& ostr, const Iterator_on_Values<Exact>& vit)
{
- return ostr << vit.to_point();
+ return ostr << vit.to_value();
}
# endif
Index: olena/oln/core/internal/encoded_image.hh
--- olena/oln/core/internal/encoded_image.hh (revision 953)
+++ olena/oln/core/internal/encoded_image.hh (working copy)
@@ -78,6 +78,8 @@
# ifndef OLN_INCLUDE_ONLY
+
+
template <typename Exact>
encoded_image_<Exact>::encoded_image_()
{
https://svn.lrde.epita.fr/svn/oln/trunk/olena
Index: ChangeLog
from Thierry Geraud <thierry.geraud(a)lrde.epita.fr>
Add tour3.cc and update.
* doc/tour/tour3.cc: New.
* oln/convert: New directory.
* oln/convert/to_window.hh: New.
* oln/core/internal/f_grid_to_window.hh: New.
* oln/core/internal/f_image_to_window.hh: New.
* doc/tour/tour2.cc: Add some text.
* doc/tour/tour1_extra.cc (include): Fix missing.
(at): Update.
* doc/tour/tour1.cc: Change a word.
* oln/debug/fill.hh (fill_): New.
(fill): Update.
* oln/debug/print.hh (format): Move into...
* oln/debug/format.hh: ...this new file.
* oln/core/1d/window1d.hh: Fix.
* oln/core/1d/image1d.hh,
* oln/core/2d/image2d_b.hh,
* oln/core/3d/image3d.hh (init_): New.
* oln/core/gen/torus_pset.hh (operator Ps): New.
(torus_pset): Fix ctor.
* oln/core/gen/niter_has.hh: Update.
* oln/core/gen/fun_ops.hh (oln_decl_p2v_cmp_): New overload.
* oln/core/concept/image.hh (dpoint): New in Image.
* oln/core/internal/box.hh: Add static check.
* oln/core/internal/op_image_extended_by_nbh.hh (operator I): New.
* oln/core/internal/point_base.hh (point_base_): New ctor overload;
decl only.
* oln/core/internal/op_pset_such_as_fp2b.hh
(pset_such_as_fp2b_fwd_piter_),
(pset_such_as_fp2b_bkd_piter_): New ctor overload.
* oln/core/internal/iterator_on_points_impl.hh
(iterator_on_points_impl_base_): New.
(vec): New.
* oln/core/internal/iterator_on_points_base.hh (point):
Disambiguate.
* oln/level/local.hh: Update.
* oln/level/clone.hh (clone_): New.
(clone): Update.
doc/tour/tour1.cc | 2
doc/tour/tour1_extra.cc | 6
doc/tour/tour2.cc | 47 +++
doc/tour/tour3.cc | 331 ++++++++++++++++++++++++++
oln/convert/to_window.hh | 76 +++++
oln/core/1d/image1d.hh | 10
oln/core/1d/window1d.hh | 2
oln/core/2d/image2d_b.hh | 25 -
oln/core/3d/image3d.hh | 10
oln/core/concept/image.hh | 1
oln/core/gen/fun_ops.hh | 10
oln/core/gen/niter_has.hh | 10
oln/core/gen/torus_pset.hh | 16 -
oln/core/internal/box.hh | 2
oln/core/internal/f_grid_to_window.hh | 118 +++++++++
oln/core/internal/f_image_to_window.hh | 37 ++
oln/core/internal/iterator_on_points_base.hh | 3
oln/core/internal/iterator_on_points_impl.hh | 38 ++
oln/core/internal/op_image_extended_by_nbh.hh | 7
oln/core/internal/op_pset_such_as_fp2b.hh | 17 +
oln/core/internal/point_base.hh | 3
oln/debug/fill.hh | 25 +
oln/debug/format.hh | 76 +++++
oln/debug/print.hh | 18 -
oln/level/clone.hh | 6
oln/level/local.hh | 6
26 files changed, 840 insertions(+), 62 deletions(-)
Index: doc/tour/tour2.cc
--- doc/tour/tour2.cc (revision 952)
+++ doc/tour/tour2.cc (working copy)
@@ -29,12 +29,10 @@
#include <oln/core/2d/image2d.hh>
#include <oln/core/2d/window2d.hh>
-#include <oln/level/fill.hh>
#include <oln/debug/println.hh>
-
// Note to the reader: If you do not have read the tour1.cc file, you
// should have a quick look at it before proceeding with this present
// file. Some important features and practices are described in the
@@ -318,9 +316,52 @@
} // End of 2nd version.
+ std::cout << std::endl;
+
+
+ // Above, p and q behave just like points; for instance, the
+ // following expressions are valid:
+
+ // int r = p.row();
+ // to get the current row value,
+
+ // bool b = img(p);
+ // to get the pixel value at the current point,
+
+ // or point2d pp = p + dp;
+ // where dp is a delta-point to get a point nearby p.
+
+ // Yet, p and q are "more than points" since they allow to
+ // browse/iterate over a set of points, respectivelly, the domain of
+ // 'img' and the window centered at p.
+
+
+ // The domain of 'img' is obtained with "img.points()" and is
+ // provided to the 'p' object so that it knows how to iterate.
+
+ // For a "basic" image, its set of points is an n-dimensional box.
+ // In the 2D space, the box type is called 'box2d'. We also have
+ // 'box1d' and 'box3d' for other dimensions.
+
+ box2d pts = img.points();
+ std::cout << "img points are " << pts << std::endl;
+ // Prints:
+ // img points are { (0, 0) .. (3, 4) }
+
+ // The type of iterators over a point set is obtained with the
+ // expression: "name_of_the_point_set_type::piter", where 'piter'
+ // means "point iterator" for short.
+
+ // The same construction is available for iterators on window
+ // points, whose types are obtained in a similar way with
+ // "name_of_the_window_type::qiter". Here the 'q' in 'qiter'
+ // emphases the fact that a window is not really a set of points but
+ // "a set of dpoints and a center point".
+
- // This last version is:
+ // The second version of our example contrasts with the more
+ // "classical" ones; it is:
// - shorter,
// so it is less error-prone for the developer;
Index: doc/tour/tour3.cc
--- doc/tour/tour3.cc (revision 0)
+++ doc/tour/tour3.cc (revision 0)
@@ -0,0 +1,331 @@
+// Copyright (C) 2001, 2007 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+// File: tour2.cc.
+
+#include <oln/core/2d/image2d.hh>
+#include <oln/core/2d/neighb2d.hh>
+
+#include <oln/core/gen/such_as.hh>
+#include <oln/core/gen/torus_image.hh>
+#include <oln/core/gen/pw_value.hh>
+#include <oln/core/gen/fun_ops.hh>
+
+#include <oln/level/fill.hh>
+#include <oln/debug/fill.hh>
+#include <oln/debug/println.hh>
+
+
+// Note to the reader: you should have read the files tour1.cc and
+// tour2.cc before starting with this present file.
+
+
+
+// We have encapsulated an algorithm into a procedure which is forward
+// declared below so that it can be used in the section 'main'.
+template <typename I> void algo(const I& img);
+
+
+// Some functions that will be useful in the following:
+bool chessboard(oln::point2d p)
+{
+ return (p.row() + p.col()) % 2;
+}
+
+
+
+int main()
+{
+ using namespace oln;
+
+ // First our domain is 2d box:
+ box2d b(point2d(0, 0), point2d(2, 2));
+ // ^^^^ ^^^^
+ // from to
+
+ // We define a binary image with values on that box.
+ image2d<bool> img(b);
+
+ // With an array of Booleans (1 means true, 0 means false)...
+ bool vals[] = { 1, 0, 0,
+ 0, 1, 0,
+ 0, 1, 1 };
+ // ...the debug::fill routine allows for manually initializing
+ // image data:
+ debug::fill(inplace(img), vals);
+ std::cout << "img = " << std::endl;
+ debug::println(img);
+ // img + // | - -
+ // - | -
+ // - | |
+
+ image2d<int> ima(b); // An image of integers with the same
+ box2d::piter p(ima.points()); // domain as img...
+ int i = 0;
+ for_all(p)
+ ima(p) = i++; // ...and manually filled with values.
+
+ std::cout << "ima = " << std::endl;
+ debug::println(ima);
+ // ima =
+ // 0 1 2
+ // 3 4 5
+ // 6 7 8
+
+ /* HERE
+
+ // The algorithm defined at the end of this file is very close to
+ // the one of the tour former file. The major difference is that it
+ // does not rely on a window but on a neighborhood.
+
+ // In image processing, we usually say that "an image has a given
+ // neighborhood" or that "we associate/embed a neighborhood to/into
+ // an image". In Olena, that is really the case: the image can
+ // "have" a neighborhood, meaning that a neighborhood can be added
+ // to an image in order to obtain an "image with a neighborhood".
+
+ // Joining an image with a neighborhood is performed with the
+ // operator '+':
+ algo(ima + c4); // c4 is the 2D neighborhood corresponding to
+ // 4-connectivity; such as many classical
+ // neighborhoods it is provided by Olena.
+ // The result is given below.
+
+ // ---input:
+ // 0 1 2
+ // 1 2 3
+ // 2 3 4
+ // ---output:
+ // 0: 1 1
+ // 1: 0 2 2
+ // 2: 1 3
+ // 1: 0 2 2
+ // 2: 1 1 3 3
+ // 3: 2 2 4
+ // 2: 1 3
+ // 3: 2 2 4
+ // 4: 3 3
+
+ // That was expectable...
+
+
+ // And now for a little test: what is the result of this code?
+ {
+ image2d<int> test(ima.points());
+ level::fill(inplace(test), ima);
+ (test + c4).at(1, 1) = 9;
+ debug::println(test);
+ }
+ // and can you tell why?
+ // The answers are given in the file tour3-test.txt
+
+
+ // Now let us start experimenting the genericity of Olena!
+
+
+ // First, imagine that you want to restrict the domain of ima to a
+ // subset of points, a region or whatever. For instance, the
+ // chessboard function takes a point as argument and returns a
+ // Boolean so it is like a predicate. We can want to consider only
+ // the points of ima "such as" this predicate is verified. The
+ // "such as" mathematical symbol is '|' so let's rock:
+
+ algo((ima | chessboard) + c8);
+ // gives:
+
+ // ---input:
+ // 1
+ // 3 5
+ // 7
+ // ---output:
+ // 1: 3 5
+ // 3: 1 7
+ // 5: 1 7
+ // 7: 3 5
+
+ // where the blanks in printing the input image denote that the
+ // corresponding points do NOT belong to the image domain.
+
+ // Another similar example is based on the binary image created at
+ // the beginning of this tour:
+ algo((ima | img) + c8);
+ // which gives:
+
+ // ---input:
+ // 0
+ // 4
+ // 7 8
+ // ---output:
+ // 0: 4
+ // 4: 0 7 8
+ // 7: 4 8
+ // 8: 4 7
+
+
+
+ // Second, imagine that you want your initial image to get the
+ // geodesy of a torus, that is, a 2D image wrapped on a torus.
+ // Points located at the image boundary have neighbors; for
+ // instance, the point denoted by the 'x' cross below has for
+ // 4-connectivity neighbors: t, l, r, and b (respectively for top,
+ // left, right, and bottom):
+
+ // b o o o
+ // o o o o
+ // t o o o
+ // x r o l
+
+ // Let us try:
+ algo(torus(ima) + c8);
+ // gives:
+
+ // ---input:
+ // 0 1 2
+ // 3 4 5
+ // 6 7 8
+ // ---output:
+ // 0: 8 6 7 2 1 5 3 4
+ // 1: 6 7 8 0 2 3 4 5
+ // 2: 7 8 6 1 0 4 5 3
+ // 3: 2 0 1 5 4 8 6 7
+ // 4: 0 1 2 3 5 6 7 8
+ // 5: 1 2 0 4 3 7 8 6
+ // 6: 5 3 4 8 7 2 0 1
+ // 7: 3 4 5 6 8 0 1 2
+ // 8: 4 5 3 7 6 1 2 0
+
+
+
+ // We can have both the torus geodesy and a sub-domain:
+
+ algo(torus(ima | chessboard) + c8);
+ algo(torus(ima | img) + c8);
+
+ // which respectively give:
+
+ // ---input:
+ // 1
+ // 3 5
+ // 7
+ // ---output:
+ // 1: 7 3 5
+ // 3: 1 5 7
+ // 5: 1 3 7
+ // 7: 3 5 1
+
+ // and:
+
+ // ---input:
+ // 0
+ // 4
+ // 7 8
+ // ---output:
+ // 0: 8 7 4
+ // 4: 0 7 8
+ // 7: 4 8 0
+ // 8: 4 7 0
+
+
+ */
+
+ // Last, the way a predicate is defined can also rely on some image
+ // values. For that the user can on the fly provide an expression
+ // built with the "pw_value" facility, where "pw_" means
+ // "point-wise" for short:
+
+ algo((ima | (pw_value(ima) < 4)) + c4);
+
+ // In this example, "pw_value(ima)" is the function that represents
+ // the point-wise value of the 'ima' image, that is, the function
+ // "p -> ima(p)". This naturally leads to:
+
+ // ---input:
+ // 0 1 2
+ // 3
+ //
+ // ---output:
+ // 0: 1 3
+ // 1: 0 2
+ // 2: 1
+ // 3: 0
+
+
+
+ // From those examples, you should realize that:
+
+
+ // +-----------------------------------------------------------+
+ // | |
+ // | The level of "genericity" provided by Olena is rather |
+ // | high; it means: |
+ // | |
+ // | - taking the image dimension you work on; |
+ // | |
+ // | - having the type of pixel values you need; |
+ // | |
+ // | - choosing the neighborhood you want; |
+ // | |
+ // | - changing the geodesy if you need it; |
+ // | |
+ // | - being able to restrict the image domain; |
+ // | |
+ // | - and many other features that are addressed further |
+ // | in the tour... |
+ // | |
+ // +-----------------------------------------------------------+
+
+}
+
+
+
+
+
+// The algorithm 'algo':
+
+template <typename I>
+void algo(const I& img)
+{
+ std::cout << "---input:" << std::endl;
+ oln::debug::print(img);
+ std::cout << "---output:" << std::endl;
+
+ oln_piter(I) p(img.points()); // p iterates on img points
+ oln_niter(I) n(img, p); // n iterates in img on neighbors of p
+
+ for_all(p)
+ {
+ std::cout << oln::debug::format(img(p))
+ << ':';
+ for_all(n)
+ std::cout << ' '
+ << oln::debug::format(img(n));
+ std::cout << std::endl;
+ }
+
+ std::cout << std::endl;
+}
Index: doc/tour/tour1_extra.cc
--- doc/tour/tour1_extra.cc (revision 952)
+++ doc/tour/tour1_extra.cc (working copy)
@@ -29,6 +29,8 @@
#include <oln/core/1d/image1d.hh>
#include <oln/arith/plus.hh>
+#include <oln/debug/println.hh>
+
int main()
@@ -91,7 +93,7 @@
{
image1d<int> orig(5); // An original image.
for (int i = 0; i < 5; ++i)
- orig(i) = i;
+ orig.at(i) = i;
debug::println(orig);
// 0 1 2 3 4
@@ -160,7 +162,7 @@
{
image1d<int> ima(5);
for (int i = 0; i < 5; ++i)
- ima(i) = i;
+ ima.at(i) = i;
debug::println(ima);
// 0 1 2 3 4
Index: doc/tour/tour1.cc
--- doc/tour/tour1.cc (revision 952)
+++ doc/tour/tour1.cc (working copy)
@@ -311,7 +311,7 @@
// Indeed, the loops above depict the "classical" way to iterate
- // over the contents of a 1D image. The next tour file explains
+ // over the contents of a 1D image. The next tour file introduces
// the solution provided by Olena to write better loops...
Index: oln/convert/to_window.hh
--- oln/convert/to_window.hh (revision 0)
+++ oln/convert/to_window.hh (revision 0)
@@ -0,0 +1,76 @@
+// Copyright (C) 2007 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#ifndef OLN_CONVERT_TO_WINDOW_HH
+# define OLN_CONVERT_TO_WINDOW_HH
+
+# include <oln/core/concept/image.hh>
+# include <oln/core/internal/f_image_to_window.hh>
+
+
+namespace oln
+{
+
+ namespace convert
+ {
+
+ // Fwd decl.
+
+ template <typename I>
+ oln_f_image_to_window(I)
+ to_window(const Binary_Image<I>& input);
+
+
+# ifndef OLN_INCLUDE_ONLY
+
+ // Generic version.
+
+ template <typename I>
+ oln_f_image_to_window(I)
+ to_window(const Binary_Image<I>& input)
+ {
+ oln_f_image_to_window(I) tmp;
+ oln_dpoint(I) dp;
+ oln_piter(I) p(input.points());
+ for_all(p)
+ if (input(p) = true)
+ {
+ dp.vec() = p.vec();
+ // FIXME: Better s.a. dp = p.to_dpoint();
+ tmp.take(dp);
+ }
+ return tmp;
+ }
+
+# endif // ! OLN_INCLUDE_ONLY
+
+ } // end of namespace oln::convert
+
+} // end of namespace oln
+
+
+#endif // ! OLN_CONVERT_TO_WINDOW_HH
Index: oln/debug/fill.hh
--- oln/debug/fill.hh (revision 952)
+++ oln/debug/fill.hh (working copy)
@@ -39,26 +39,37 @@
{
template <typename I, typename V>
- void fill(Mutable_Image<I>& in_out, const V values[]);
-
- template <typename I, typename V>
void fill(inplace_<I> in_out, const V values[]);
# ifndef OLN_INCLUDE_ONLY
- template <typename I>
- void fill(Mutable_Image<I>& in_out, const oln_value(I)& value)
+ namespace impl
+ {
+
+ template <typename I, typename V>
+ void fill_(Mutable_Image<I>& in_out, const V values[])
{
+ unsigned i = 0;
oln_piter(I) p(in_out.points());
for_all(p)
- in_out(p) = value;
+ in_out(p) = values[i++];
}
+ } // end of namespace oln::impl
+
template <typename I, typename V>
void fill(inplace_<I> in_out, const V values[])
{
- fill(in_out.unwrap(), values);
+ impl::fill_(in_out.unwrap(), values);
+ }
+
+ // Guard.
+
+ template <typename I, typename V>
+ void fill(const Image<I>&, const V[])
+ {
+ mlc::abort_<I>::check(); // FIXME: Add err msg.
}
# endif // ! OLN_INCLUDE_ONLY
Index: oln/debug/format.hh
--- oln/debug/format.hh (revision 0)
+++ oln/debug/format.hh (revision 0)
@@ -0,0 +1,76 @@
+// Copyright (C) 2006, 2007 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#ifndef OLN_DEBUG_FORMAT_HH
+# define OLN_DEBUG_FORMAT_HH
+
+
+namespace oln
+{
+
+ namespace debug
+ {
+
+ // Fwd decls.
+
+ template <typename T>
+ const T&
+ format(const T& value);
+
+ unsigned
+ format(const unsigned char& value);
+
+ char
+ format(bool value);
+
+
+# ifndef OLN_INCLUDE_ONLY
+
+ template <typename T>
+ const T& format(const T& value)
+ {
+ return value;
+ }
+
+ unsigned format(const unsigned char& value)
+ {
+ return value;
+ }
+
+ char format(bool value)
+ {
+ return value ? '|' : '-';
+ }
+
+# endif // ! OLN_INCLUDE_ONLY
+
+ } // end of namespace oln::debug
+
+} // end of namespace oln
+
+
+#endif // ! OLN_DEBUG_FORMAT_HH
Index: oln/debug/print.hh
--- oln/debug/print.hh (revision 952)
+++ oln/debug/print.hh (working copy)
@@ -30,6 +30,7 @@
# include <iostream>
# include <oln/core/concept/image.hh>
+# include <oln/debug/format.hh>
# ifdef OLN_ENV_2D
# include <oln/core/2d/point2d.hh>
@@ -53,23 +54,6 @@
namespace impl
{
- template <typename T>
- const T& format(const T& value)
- {
- return value;
- }
-
- unsigned format(const unsigned char& value)
- {
- return value;
- }
-
- char format(bool value)
- {
- return value ? '|' : '-';
- }
-
-
/// Generic version.
template <typename I>
Index: oln/core/1d/image1d.hh
--- oln/core/1d/image1d.hh (revision 952)
+++ oln/core/1d/image1d.hh (working copy)
@@ -108,6 +108,9 @@
template <typename T, typename D>
bool prepare(image1d<T>& target, with_t, const D& dat);
+ template <typename T>
+ bool init_(box1d* this_, const image1d<T>& data);
+
# ifndef OLN_INCLUDE_ONLY
@@ -242,6 +245,13 @@
return box_ok;
}
+ template <typename T>
+ bool init_(box1d* this_, const image1d<T>& data)
+ {
+ *this_ = data.bbox();
+ return true;
+ }
+
# endif // ! OLN_INCLUDE_ONLY
Index: oln/core/1d/window1d.hh
--- oln/core/1d/window1d.hh (revision 952)
+++ oln/core/1d/window1d.hh (working copy)
@@ -36,7 +36,7 @@
{
// FIXME: window1d should be an actual type, not an alias...
- typedef window_<dpoint1d> window1d;
+ typedef gen_window<dpoint1d> window1d;
} // end of namespace oln
Index: oln/core/2d/image2d_b.hh
--- oln/core/2d/image2d_b.hh (revision 952)
+++ oln/core/2d/image2d_b.hh (working copy)
@@ -114,12 +114,12 @@
std::size_t pad(const dpoint2d& dp) const;
};
-// template <typename T, typename D>
-// bool init_(image2d_b<T>* this_, const D& dat);
-
template <typename T, typename D>
bool prepare(image2d_b<T>& target, with_t, const D& dat);
+ template <typename T>
+ bool init_(box2d* this_, const image2d_b<T>& data);
+
# ifndef OLN_INCLUDE_ONLY
@@ -239,18 +239,6 @@
return this->data_->first.i_pad() * dp.row() + dp.col();
}
-// template <typename T, typename D>
-// bool init_(image2d_b<T>* this_, const D& dat)
-// {
-// precondition(not this_->has_data());
-// box2d b;
-// bool box_ok = init(b, with, dat);
-// postcondition(box_ok);
-// unsigned border = 2; // FIXME: Use init!
-// this_->data__() = new typename image2d_b<T>::data(b.pmin(), b.pmax(), border);
-// return box_ok;
-// }
-
template <typename T, typename D>
bool prepare(image2d_b<T>& target, with_t, const D& dat)
{
@@ -267,6 +255,13 @@
return box_ok;
}
+ template <typename T>
+ bool init_(box2d* this_, const image2d_b<T>& data)
+ {
+ *this_ = data.bbox();
+ return true;
+ }
+
# endif // ! OLN_INCLUDE_ONLY
} // end of namespace oln
Index: oln/core/3d/image3d.hh
--- oln/core/3d/image3d.hh (revision 952)
+++ oln/core/3d/image3d.hh (working copy)
@@ -109,6 +109,9 @@
template <typename T, typename D>
bool prepare(image3d<T>& target, with_t, const D& dat);
+ template <typename T>
+ bool init_(box3d* this_, const image3d<T>& data);
+
# ifndef OLN_INCLUDE_ONLY
@@ -240,6 +243,13 @@
return box_ok;
}
+ template <typename T>
+ bool init_(box3d* this_, const image3d<T>& data)
+ {
+ *this_ = data.bbox();
+ return true;
+ }
+
# endif // ! OLN_INCLUDE_ONLY
} // end of namespace oln
Index: oln/core/gen/torus_pset.hh
--- oln/core/gen/torus_pset.hh (revision 952)
+++ oln/core/gen/torus_pset.hh (working copy)
@@ -76,6 +76,8 @@
torus_pset(const Ps& pset);
void init_pset(const Ps& pset);
+ operator Ps() const;
+
point relocate(const point& p) const;
bool impl_has(const point& p) const;
@@ -105,9 +107,9 @@
: super(pset)
{
mlc::assert_< mlc_is_a(Ps, Point_Set) >::check();
- this->pmin_ = pset.pmin();
+ this->pmin_ = pset.bbox().pmin();
dpoint unit; unit.set_all(1);
- this->size_ = pset.pmax() - pset.pmin() + unit;
+ this->size_ = pset.bbox().pmax() - pset.bbox().pmin() + unit;
}
template <typename Ps>
@@ -115,9 +117,15 @@
current::init_pset(const Ps& pset)
{
this->ps_ = pset;
- this->pmin_ = pset.pmin();
+ this->pmin_ = pset.bbox().pmin();
dpoint unit; unit.set_all(1);
- this->size_ = pset.pmax() - pset.pmin() + unit;
+ this->size_ = pset.bbox().pmax() - pset.bbox().pmin() + unit;
+ }
+
+ template <typename Ps>
+ current::operator Ps() const
+ {
+ return this->ps_;
}
template <typename Ps>
Index: oln/core/gen/niter_has.hh
--- oln/core/gen/niter_has.hh (revision 952)
+++ oln/core/gen/niter_has.hh (working copy)
@@ -69,8 +69,8 @@
{
public:
- template <typename Pl, typename I>
- niter_has_(const Generalized_Point<Pl>& p, const Image_with_Nbh<I>& ima);
+ template <typename I, typename Pl>
+ niter_has_(const Image_with_Nbh<I>& ima, const Generalized_Point<Pl>& p);
void impl_start();
void impl_next();
@@ -87,10 +87,10 @@
# ifndef OLN_INCLUDE_ONLY
template <typename It, typename Ps>
- template <typename Pl, typename I>
- current::niter_has_(const Generalized_Point<Pl>& p, const Image_with_Nbh<I>& ima)
+ template <typename I, typename Pl>
+ current::niter_has_(const Image_with_Nbh<I>& ima, const Generalized_Point<Pl>& p)
:
- super( It(p, ima) ),
+ super( It(ima, p) ),
pset_( ima.points() )
{
}
Index: oln/core/gen/fun_ops.hh
--- oln/core/gen/fun_ops.hh (revision 952)
+++ oln/core/gen/fun_ops.hh (working copy)
@@ -76,6 +76,16 @@
return tmp; \
} \
\
+ template <typename L> \
+ p2v_##Name##_<L, lit_p2v_<oln_argument(L), oln_result(L)> > \
+ operator Sym (const Function_p2v<L>& left, const oln_result(L)& right) \
+ { \
+ mlc::assert_< mlc_is_a(oln_argument(L), Point) >::check(); \
+ lit_p2v_<oln_argument(L), oln_result(L)> right_(right); \
+ p2v_##Name##_<L, lit_p2v_<oln_argument(L), oln_result(L)> > tmp(left, right_); \
+ return tmp; \
+ } \
+ \
struct e_n_d___w_i_t_h___s_e_m_i_c_o_l_u_m_n
Index: oln/core/concept/image.hh
--- oln/core/concept/image.hh (revision 952)
+++ oln/core/concept/image.hh (working copy)
@@ -127,6 +127,7 @@
stc_typename(box);
stc_typename(pset);
+ stc_typename(dpoint);
// stc_typename(output); // FIXME: Uncomment!
stc_typename(plain);
Index: oln/core/internal/box.hh
--- oln/core/internal/box.hh (revision 952)
+++ oln/core/internal/box.hh (working copy)
@@ -306,6 +306,7 @@
box_fwd_piter_<B>::box_fwd_piter_(const Point_Set<Ps>& ps)
: b_(ps.bbox())
{
+ mlc::assert_< mlc_is_a(B, Point_Set) >::check(); // FIXME: Add err msg.
nop_ = b_.pmax();
++nop_[0];
p_ = nop_;
@@ -371,6 +372,7 @@
box_bkd_piter_<B>::box_bkd_piter_(const Point_Set<Ps>& ps)
: b_(ps.bbox())
{
+ mlc::assert_< mlc_is_a(B, Point_Set) >::check(); // FIXME: Add err msg.
nop_ = b_.pmin();
--nop_[0];
p_ = nop_;
Index: oln/core/internal/op_image_extended_by_nbh.hh
--- oln/core/internal/op_image_extended_by_nbh.hh (revision 952)
+++ oln/core/internal/op_image_extended_by_nbh.hh (working copy)
@@ -108,6 +108,8 @@
const nbh& impl_nbhood() const;
nbh& impl_nbhood();
+ operator I() const;
+
protected:
special_op_();
special_op_(I& ima, N& n);
@@ -150,6 +152,11 @@
namespace internal
{
+ template <typename I, typename N>
+ current::operator I() const
+ {
+ return this->image();
+ }
template <typename I, typename N>
current::special_op_()
Index: oln/core/internal/point_base.hh
--- oln/core/internal/point_base.hh (revision 952)
+++ oln/core/internal/point_base.hh (working copy)
@@ -97,8 +97,11 @@
vec_t& vec();
void set_all(const coord& c);
+ // FIXME: Add 'static const Exact& zero();'
+
protected:
point_base_();
+ point_base_(coord val);
vec_t v_;
};
Index: oln/core/internal/f_grid_to_window.hh
--- oln/core/internal/f_grid_to_window.hh (revision 0)
+++ oln/core/internal/f_grid_to_window.hh (revision 0)
@@ -0,0 +1,118 @@
+// Copyright (C) 2007 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#ifndef OLN_CORE_INTERNAL_F_GRID_TO_WINDOW_HH
+# define OLN_CORE_INTERNAL_F_GRID_TO_WINDOW_HH
+
+# include <oln/core/concept/grid.hh>
+# include <oln/core/gen/window.hh>
+
+
+#define oln_f_grid_to_window(G) typename oln::internal::f_grid_to_window_< G >::ret
+
+
+namespace oln
+{
+
+ /// \{
+ /// Forward declarations.
+
+ // Grid types.
+
+ struct grid1d;
+ struct grid2d;
+ struct grid2d_hex;
+ struct grid2d_tri;
+ struct grid3d;
+ // ...
+
+ // Dpoint types.
+ struct dpoint1d;
+ struct dpoint2d;
+ struct dpoint3d;
+ // ...
+
+ // Window types.
+
+ typedef gen_window<dpoint1d> window1d;
+ typedef gen_window<dpoint2d> window2d;
+ typedef gen_window<dpoint3d> window3d;
+ // ...
+
+ /// \}
+
+
+
+ namespace internal
+ {
+
+ // Fwd decl.
+
+ template <typename G> struct f_grid_to_;
+
+
+ /// \{
+ /// Definitions.
+
+ template <typename G>
+ struct grid_to_window__;
+
+ template <>
+ struct grid_to_window__< grid1d >
+ {
+ typedef window1d ret;
+ };
+
+ template <>
+ struct grid_to_window__< grid2d >
+ {
+ typedef window2d ret;
+ };
+
+ // FIXME: 2D hex/tri...
+
+ template <>
+ struct grid_to_window__< grid3d >
+ {
+ typedef window3d ret;
+ };
+
+ /// \}
+
+
+ template <typename G>
+ struct f_grid_to_window_ : private mlc::assert_< mlc_is_a(G, Grid) >,
+ public grid_to_window__< G >
+ {
+ };
+
+ } // end of namespace oln::internal
+
+} // end of namespace oln
+
+
+#endif // ! OLN_CORE_INTERNAL_F_GRID_TO_WINDOW_HH
Index: oln/core/internal/op_pset_such_as_fp2b.hh
--- oln/core/internal/op_pset_such_as_fp2b.hh (revision 952)
+++ oln/core/internal/op_pset_such_as_fp2b.hh (working copy)
@@ -209,7 +209,7 @@
{
public:
- pset_such_as_fp2b_fwd_piter_();
+ pset_such_as_fp2b_fwd_piter_(const op_<S, such_as, F>& pset);
pset_such_as_fp2b_fwd_piter_(const Point_Set< op_<S, such_as, F> >& pset);
void impl_start();
@@ -224,6 +224,13 @@
# ifndef OLN_INCLUDE_ONLY
template <typename S, typename F>
+ current::pset_such_as_fp2b_fwd_piter_(const op_<S, such_as, F>& pset)
+ : super(pset.adapted_()),
+ f_(pset.fun_())
+ {
+ }
+
+ template <typename S, typename F>
current::pset_such_as_fp2b_fwd_piter_(const Point_Set< op_<S, such_as, F> >& pset)
: super(exact(pset).adapted_()),
f_(exact(pset).fun_())
@@ -285,6 +292,7 @@
{
public:
+ pset_such_as_fp2b_bkd_piter_(const op_<S, such_as, F>& pset);
pset_such_as_fp2b_bkd_piter_(const Point_Set< op_<S, such_as, F> >& pset);
void impl_start();
@@ -299,6 +307,13 @@
# ifndef OLN_INCLUDE_ONLY
template <typename S, typename F>
+ current::pset_such_as_fp2b_bkd_piter_(const op_<S, such_as, F>& pset)
+ : super(pset.adapted_()),
+ f_(pset.fun_())
+ {
+ }
+
+ template <typename S, typename F>
current::pset_such_as_fp2b_bkd_piter_(const Point_Set< op_<S, such_as, F> >& pset)
: super(exact(pset).adapted_()),
f_(exact(pset).fun_())
Index: oln/core/internal/iterator_on_points_impl.hh
--- oln/core/internal/iterator_on_points_impl.hh (revision 952)
+++ oln/core/internal/iterator_on_points_impl.hh (working copy)
@@ -37,6 +37,22 @@
namespace internal
{
+ // base impl
+
+ template <typename Exact>
+ struct iterator_on_points_impl_base_
+ {
+ private:
+ stc_typename(point);
+ typedef typename point::vec_t vec_t;
+ public:
+ const vec_t& vec() const;
+ vec_t& vec();
+ };
+
+
+ // no-d impl is empty
+
template <unsigned n, typename Exact>
struct iterator_on_points_impl_
{
@@ -45,6 +61,8 @@
// 1d impl
template <typename Exact>
struct iterator_on_points_impl_< 1, Exact >
+ :
+ public iterator_on_points_impl_base_<Exact>
{
private:
stc_typename(coord);
@@ -55,6 +73,8 @@
// 2d impl
template <typename Exact>
struct iterator_on_points_impl_< 2, Exact >
+ :
+ public iterator_on_points_impl_base_<Exact>
{
private:
stc_typename(coord);
@@ -66,6 +86,8 @@
// 3d impl
template <typename Exact>
struct iterator_on_points_impl_< 3, Exact >
+ :
+ public iterator_on_points_impl_base_<Exact>
{
private:
stc_typename(coord);
@@ -77,6 +99,22 @@
# ifndef OLN_INCLUDE_ONLY
+ // base impl
+
+ template <typename Exact>
+ const typename iterator_on_points_impl_base_<Exact>::vec_t&
+ iterator_on_points_impl_base_<Exact>::vec() const
+ {
+ return static_cast<const Exact&>(*this).to_point().vec();
+ }
+
+ template <typename Exact>
+ typename iterator_on_points_impl_base_<Exact>::vec_t&
+ iterator_on_points_impl_base_<Exact>::vec()
+ {
+ return static_cast<const Exact&>(*this).to_point().vec();
+ }
+
// 1d impl
template <typename Exact>
Index: oln/core/internal/iterator_on_points_base.hh
--- oln/core/internal/iterator_on_points_base.hh (revision 952)
+++ oln/core/internal/iterator_on_points_base.hh (working copy)
@@ -69,6 +69,9 @@
: public Iterator_on_Points<Exact>,
public internal::iterator_on_points_impl_<mlc_value(stc_deferred(dim)), Exact>
{
+ public:
+ // Disambiguate.
+ stc_using_from(Iterator_on_Points, point);
protected:
iterator_on_points_base_();
};
Index: oln/core/internal/f_image_to_window.hh
--- oln/core/internal/f_image_to_window.hh (revision 0)
+++ oln/core/internal/f_image_to_window.hh (revision 0)
@@ -0,0 +1,37 @@
+// Copyright (C) 2007 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#ifndef OLN_CORE_INTERNAL_F_IMAGE_TO_WINDOW_HH
+# define OLN_CORE_INTERNAL_F_IMAGE_TO_WINDOW_HH
+
+# include <oln/core/internal/f_grid_to_window.hh>
+
+
+#define oln_f_image_to_window(I) oln_f_grid_to_window(oln_grid(I))
+
+
+#endif // ! OLN_CORE_INTERNAL_F_IMAGE_TO_WINDOW_HH
Index: oln/level/local.hh
--- oln/level/local.hh (revision 952)
+++ oln/level/local.hh (working copy)
@@ -68,7 +68,7 @@
const oln_point(I)& p)
{
f.init_with(input(p));
- oln_niter(I) n(p, input);
+ oln_niter(I) n(input, p);
for_all(n)
f(input(n));
return f.value();
@@ -85,7 +85,7 @@
f.init_with(input(p));
if (f.value() = true)
return true;
- oln_niter(I) n(p, input);
+ oln_niter(I) n(input, p);
for_all(n)
{
f(input(n)); // FIXME: Change to f.take(input(n))?
@@ -104,7 +104,7 @@
const oln_point(I)& p)
{
f.init_with(input(p));
- oln_niter(I) n(p, input);
+ oln_niter(I) n(input, p);
for_all(n)
{
f(input(n)); // FIXME: Change to f.take(input(n))?
Index: oln/level/clone.hh
--- oln/level/clone.hh (revision 952)
+++ oln/level/clone.hh (working copy)
@@ -50,11 +50,11 @@
// Generic version.
template <typename I>
- oln_plain(I) clone(const Image<I>& input)
+ oln_plain(I) clone_(const Image<I>& input)
{
oln_plain(I) output;
prepare(output, with, input);
- level::fill(output, input);
+ level::fill(inplace(output), input);
return output;
}
@@ -65,7 +65,7 @@
template <typename I>
oln_plain(I) clone(const Image<I>& input)
{
- return impl::clone(input);
+ return impl::clone_(input);
}
# endif // ! OLN_INCLUDE_ONLY
https://svn.lrde.epita.fr/svn/oln/trunk/olena
Index: ChangeLog
from Thierry Geraud <thierry.geraud(a)lrde.epita.fr>
Make 'inplace' mandatory and start a tour.
* doc: New directory.
* doc/tour: New sub-directory.
* doc/tour/tour1_extra.cc: New.
* doc/tour/tour1.cc: New.
* tests/core/image1d.cc: Remove unused decl and update.
* tests/core/image2d.cc: Use namespace.
* tests/core/image3d.cc: Update.
* tests/algorithms/basic_morpho.cc: Remove hack.
Update includes.
* oln/debug/print.hh (print_1D): New.
* tests/core/stack.cc,
* tests/algorithms/fill.cc,
* oln/debug/iota.hh,
* oln/draw/bresenham.hh,
* oln/level/fill.hh,
* oln/level/clone.hh,
* oln/level/apply_inplace.hh: Update.
* oln/core/1d/image1d.hh (prepare): New.
* oln/core/1d/image1d_b.hh (prepare): New.
* oln/core/internal/symmetrical_window.hh: New.
* oln/core/internal/window.hh (impl_take): New.
(take): Call impl_take.
* oln/core/2d/vline2d.hh,
* oln/core/2d/hline2d.hh,
* oln/core/2d/rectangle2d.hh: Update.
* oln/core/2d/neighb2d.hh: Add FIXMEs.
* oln/core/gen/inplace.hh (inplace): New overload.
* oln/core/concept/image.hh (is_empty): New in Image.
(min_ind, max_ind, ninds): New in Image_1D.
* oln/core/concept/function.hh: Remove obsolete commented code.
* oln/core/concept/image_identity.hh: Cosmetic change.
* oln/core/internal/image_selectors.hh (Image_dimension): Handle
1D and 3D cases.
* oln/core/internal/image_base.hh (impl_is_empty): New.
* oln/core/internal/op_image_extended_by_nbh.hh (init_): New
overload.
(init_): Unconst nbh in the Neighborhood version.
* oln/core/internal/special_op.hh: Cosmetic change.
* oln/morpho/cc_tarjan.hh: Fix.
doc/tour/tour1.cc | 322 ++++++++++++++++++++++++++
doc/tour/tour1_extra.cc | 212 +++++++++++++++++
oln/core/1d/image1d.hh | 26 ++
oln/core/1d/image1d_b.hh | 17 +
oln/core/2d/hline2d.hh | 14 -
oln/core/2d/neighb2d.hh | 2
oln/core/2d/rectangle2d.hh | 15 -
oln/core/2d/vline2d.hh | 14 -
oln/core/concept/function.hh | 48 ---
oln/core/concept/image.hh | 43 +++
oln/core/gen/inplace.hh | 14 +
oln/core/internal/image_base.hh | 9
oln/core/internal/image_selectors.hh | 24 +
oln/core/internal/op_image_extended_by_nbh.hh | 17 +
oln/core/internal/special_op.hh | 4
oln/core/internal/symmetrical_window.hh | 111 ++++++++
oln/core/internal/window.hh | 17 +
oln/debug/iota.hh | 19 +
oln/debug/print.hh | 39 +++
oln/draw/bresenham.hh | 27 +-
oln/level/apply_inplace.hh | 23 -
oln/level/clone.hh | 4
oln/level/fill.hh | 68 +----
oln/morpho/cc_tarjan.hh | 8
tests/algorithms/basic_morpho.cc | 14 -
tests/algorithms/fill.cc | 2
tests/core/image1d.cc | 5
tests/core/image2d.cc | 20 -
tests/core/image3d.cc | 24 -
tests/core/stack.cc | 3
30 files changed, 977 insertions(+), 188 deletions(-)
Index: tests/core/stack.cc
--- tests/core/stack.cc (revision 948)
+++ tests/core/stack.cc (working copy)
@@ -45,7 +45,8 @@
typedef image2d<int> I;
I ima_0(3, 3), ima_1(3, 3);
- level::fill(stack(ima_0, ima_1).inplace(), coords);
+ image_stack<2,I> ima = stack(ima_0, ima_1);
+ level::fill(inplace(ima), coords);
{
I::piter p(ima_0.points());
for_all(p)
Index: tests/core/image1d.cc
--- tests/core/image1d.cc (revision 948)
+++ tests/core/image1d.cc (working copy)
@@ -1,4 +1,4 @@
-// Copyright (C) 2006 EPITA Research and Development Laboratory
+// Copyright (C) 2006, 2007 EPITA Research and Development Laboratory
//
// This file is part of the Olena Library. This library is free
// software; you can redistribute it and/or modify it under the terms
@@ -38,7 +38,6 @@
// Fill a 1D image using its iterator.
image1d<char> ima1(3);
- image1d<char>::box box1 = ima1.points();
image1d<char>::piter p1 (ima1.points());
for_all(p1)
ima1(p1) = 1;
@@ -50,7 +49,7 @@
// Fill a 1D image using the routine level::fill.
image1d<long> ima3(ima1.points());
- level::fill(ima3, 3);
+ level::fill(inplace(ima3), 3);
// Add the three images.
Index: tests/core/image2d.cc
--- tests/core/image2d.cc (revision 948)
+++ tests/core/image2d.cc (working copy)
@@ -28,34 +28,34 @@
/// Test oln::image2d.
#include <cassert>
-// FIXME: We should not include oln/basics2d.hh, but
-// oln/core/2d/image2d.hh (and oln/core/2d/neigh2d.hh ?).
#include <oln/core/2d/image2d.hh>
#include <oln/level/fill.hh>
int
main()
{
+ using namespace oln;
+
// Fill a 2D image using its iterator.
- oln::image2d<char> ima1(3, 3);
- oln::image2d<char>::piter p1(ima1.points());
+ image2d<char> ima1(3, 3);
+ image2d<char>::piter p1(ima1.points());
for_all(p1)
ima1(p1) = 1;
// Fill a 2D image using a classic loop.
- oln::image2d<int> ima2(ima1.points());
+ image2d<int> ima2(ima1.points());
for (unsigned i = 0; i < 3; ++i)
for (unsigned j = 0; j < 3; ++j)
ima2.at(i, j) = 2;
- // Fill a 2D image using the routine oln::level::fill.
- oln::image2d<long> ima3(ima1.points());
- oln::level::fill(ima3, 3);
+ // Fill a 2D image using the routine level::fill.
+ image2d<long> ima3(ima1.points());
+ level::fill(inplace(ima3), 3);
// Add the three images.
- oln::image2d<long> sum(ima1.points());
- oln::image2d<long>::piter p(sum.points());
+ image2d<long> sum(ima1.points());
+ image2d<long>::piter p(sum.points());
for_all(p)
sum(p) = ima1(p) + ima2(p) + ima3(p);
// And check the sum.
Index: tests/core/image3d.cc
--- tests/core/image3d.cc (revision 948)
+++ tests/core/image3d.cc (working copy)
@@ -28,35 +28,35 @@
/// Test oln::image3d.
#include <cassert>
-// FIXME: We should not include oln/basics3d.hh, but
-// oln/core/3d/image3d.hh (and oln/core/3d/neigh3d.hh ?).
-#include <oln/basics3d.hh>
+#include <oln/core/3d/image3d.hh>
#include <oln/level/fill.hh>
int
main()
{
+ using namespace oln;
+
// Fill a 3D image using its iterator.
- oln::image3d<char> ima1(3, 3, 3);
- oln_vtype_(oln::image3d<char>, piter) p1(ima1.topo());
+ image3d<char> ima1(3, 3, 3);
+ image3d<char>::piter p1(ima1.points());
for_all(p1)
ima1(p1) = 1;
// Fill a 3D image using a classic loop.
- oln::image3d<int> ima2(ima1.topo());
+ image3d<int> ima2(ima1.points());
for (unsigned i = 0; i < 3; ++i)
for (unsigned j = 0; j < 3; ++j)
for (unsigned k = 0; k < 3; ++k)
- ima2(oln::point3d(i, j, k)) = 2;
+ ima2.at(i, j, k) = 2;
- // Fill a 3D image using the routine oln::level::fill.
- oln::image3d<long> ima3(ima1.topo());
- oln::level::fill(ima3, 3);
+ // Fill a 3D image using the routine level::fill.
+ image3d<long> ima3(ima1.points());
+ level::fill(inplace(ima3), 3);
// Add the three images.
- oln::image3d<long> sum(ima1.topo());
- oln_vtype_(oln::image3d<long>, piter) p(sum.topo());
+ image3d<long> sum(ima1.points());
+ image3d<long>::piter p(sum.points());
for_all(p)
sum(p) = ima1(p) + ima2(p) + ima3(p);
// And check the sum.
Index: tests/algorithms/basic_morpho.cc
--- tests/algorithms/basic_morpho.cc (revision 948)
+++ tests/algorithms/basic_morpho.cc (working copy)
@@ -1,8 +1,12 @@
#include <oln/core/2d/image2d.hh>
-#include <oln/core/2d/window2d.hh>
#include <oln/core/2d/neighb2d.hh>
+#include <oln/core/2d/window2d.hh>
+#include <oln/core/2d/rectangle2d.hh>
+#include <oln/core/2d/hline2d.hh>
+#include <oln/core/2d/vline2d.hh>
+
#include <oln/morpho/elementary_dilation.hh>
#include <oln/morpho/elementary_erosion.hh>
@@ -40,13 +44,13 @@
for_all(p1)
ima(p1) = i++ % 2;
- my_test( (morpho::elementary_erosion(ima + c4)).image(), 0);
+ my_test( morpho::elementary_erosion(ima + c4), 0);
- my_test( (morpho::elementary_dilation(ima + c4)).image(), 1 );
+ my_test( morpho::elementary_dilation(ima + c4), 1 );
- my_test( (morpho::elementary_opening(ima + c4)).image(), 0);
+ my_test( morpho::elementary_opening(ima + c4), 0);
- my_test( (morpho::elementary_closing(ima + c4)).image(), 1);
+ my_test( morpho::elementary_closing(ima + c4), 1);
my_test( morpho::erosion(ima, win3x3), 0);
Index: tests/algorithms/fill.cc
--- tests/algorithms/fill.cc (revision 948)
+++ tests/algorithms/fill.cc (working copy)
@@ -38,7 +38,7 @@
using namespace oln;
typedef image2d<int> image_t;
image_t ima(3, 3);
- level::fill(ima, 51);
+ level::fill(inplace(ima), 51);
image_t::piter p(ima.points());
for_all(p)
assert(ima(p) = 51);
Index: doc/tour/tour1_extra.cc
--- doc/tour/tour1_extra.cc (revision 0)
+++ doc/tour/tour1_extra.cc (revision 0)
@@ -0,0 +1,212 @@
+// Copyright (C) 2007 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+// File: tour1_extra.cc.
+
+#include <oln/core/1d/image1d.hh>
+#include <oln/arith/plus.hh>
+
+
+int main()
+{
+ using namespace oln;
+
+
+ // Let us take a few examples to illustrate how images and data are
+ // managed. In these examples, we will use the notion of "block of
+ // instructions" from the C/C+ languages: "{" ... "}".
+
+
+
+
+ // Example 1:
+
+ { // A new block starts here.
+
+ image1d<float> local_ima(1000);
+ // A non-empty image is created; a memory buffer automatically is
+ // allocated to store image data. Some code using 'local_ima' can
+ // be inserted here...
+
+ } // The block ends and 'local_ima' is not more accessible.
+
+ // At the end of the block, since the user cannot use 'local_ima'
+ // anymore, the memory is automatically deallocated.
+
+
+
+
+ // Example 2:
+
+ image1d<float> ima; // An empty image---a variable.
+
+ { // A new block.
+
+ image1d<float> local_ima(1000); // A non-empty image.
+ // Some work is performed with 'local_ima' here.
+ // ...
+ ima = local_ima; // Last, we state that ima IS local_ima.
+
+ } // End of the block: 'local_ima' is no more accessible.
+
+ assert(not ima.is_empty()); // We test that 'ima' is no more empty.
+
+ // Since we state that "ima IS local_ima" and since 'ima' is still
+ // accessible by the user, the contents of 'local_ima' is preserved.
+
+ // Conversely to the example 1, the memory allocated for 'local_ima'
+ // is thus NOT deallocated: the data of 'local_ima' is "transfered"
+ // to 'ima'. There is NO data "copy" involved during this transfer
+ // so it is fast and it saves memory.
+
+
+
+
+ // Example 3:
+
+ {
+ image1d<int> orig(5); // An original image.
+ for (int i = 0; i < 5; ++i)
+ orig(i) = i;
+ debug::println(orig);
+ // 0 1 2 3 4
+
+ image1d<int> ima = orig; // 'ima' is 'orig'.
+ ima = ima + ima; // Point-wise sum of ima and itself.
+ debug::println(ima);
+ // 0 2 4 6 8
+
+ debug::println(orig);
+ // 0 1 2 3 4
+ }
+
+ // To explain this result, let us detail the point-wise sum line.
+ // The assignment "ima = ima + ima" is a two-step process: first
+ // "ima + ima" is computed, then the assignment is performed. This
+ // line can be rewritten as:
+
+ // image1d<int> anon = ima + ima; // line (a)
+ // ima = anon; // line (b)
+
+ // where 'anon' is the "anonymous" result of the sum. We can see
+ // that 'ima' is used in line (a) to compute a new image, namely
+ // 'anon'. At that precise line, 'ima' still designates 'orig'. At
+ // line (b) the definition of 'ima' changes: 'ima' was designating
+ // 'orig', now it designates 'anon', that is, the sum result.
+ // Eventually the data of 'orig' have never changed since it has
+ // been initialized.
+
+ // In this example, two images with effective data have been
+ // created: the sum result, which is accessible through 'ima', and
+ // 'orig'.
+
+ // The same explanation in pictures. When the sum "ima + ima" is
+ // computed, the images and their data look like:
+ //
+ // +-----------+
+ // orig --> | 0 1 2 3 4 |
+ // +-----------+
+ // ^
+ // ima ______|
+ //
+ // +-----------+
+ // anon --> | 0 2 4 6 8 |
+ // +-----------+
+ //
+ // Then the assignment modifies this scheme into:
+ //
+ // +-----------+
+ // orig --> | 0 1 2 3 4 |
+ // +-----------+
+ // ima ______
+ // |
+ // v
+ // +-----------+
+ // anon --> | 0 2 4 6 8 |
+ // +-----------+
+ //
+ // and the temporary 'anon' disapears.
+
+
+
+
+
+ // Example 4:
+
+ {
+ image1d<int> ima(5);
+ for (int i = 0; i < 5; ++i)
+ ima(i) = i;
+ debug::println(ima);
+ // 0 1 2 3 4
+
+ ima = ima + ima;
+ debug::println(ima);
+ // 0 2 4 6 8
+ }
+
+ // Let us re-write the assignment line:
+
+ // image1d<int> anon = ima + ima; // line (a)
+ // ima = anon; // line (b)
+
+ // A new image, 'anon', is created to store the sum result; this
+ // image is just like a temporary object since it is anonymous. In
+ // line (a) the definition of 'ima' changes: it was the original
+ // image with its data being "0 1 2 3 4" and it now designates the
+ // sum result. The original data becomes inaccessible by the user
+ // so it is automatically deallocated.
+
+ // The same explanation In pictures. After the sum is computed, we
+ // have:
+ // +-----------+
+ // ima ---> | 0 1 2 3 4 |
+ // +-----------+
+ //
+ // +-----------+
+ // anon --> | 0 2 4 6 8 |
+ // +-----------+
+ //
+ // and the assignment of 'ima' leads to:
+ //
+ // +-----------+
+ // ima | 0 1 2 3 4 |
+ // | +-----------+
+ // |_________
+ // |
+ // v
+ // +-----------+
+ // anon --> | 0 2 4 6 8 |
+ // +-----------+
+ //
+ // so the original data, which is unreachable, are deallocated and
+ // the temporary 'anon' disappears; we end up with:
+ //
+ // +-----------+
+ // ima ---> | 0 2 4 6 8 |
+ // +-----------+
+}
Index: doc/tour/tour1.cc
--- doc/tour/tour1.cc (revision 0)
+++ doc/tour/tour1.cc (revision 0)
@@ -0,0 +1,322 @@
+w// Copyright (C) 2001, 2007 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+// File: tour1.cc.
+
+#include <oln/core/1d/image1d.hh>
+
+#include <oln/arith/plus.hh> // arith
+
+#include <oln/level/fill.hh> // level
+#include <oln/level/paste.hh>
+
+#include <oln/debug/println.hh> // debug
+
+
+int main()
+{
+ // Olena is organized in a namespace hierarchy. Everything is
+ // declared by Olena within the 'oln::' namespace, and possibly a
+ // sub-namespace such as 'oln::arith::' (arithmetic operations on
+ // images), 'oln::morpho::' (morphological operations), etc. For
+ // the sake of simplicity, we will neglect the 'oln::' prefix in
+ // this file.
+
+ using namespace oln;
+
+ // There are three kinds of image dimensions supported for the
+ // moment: 1D, 2D, and 3D. The respective basic image types are
+ // respectively image1d, image2d, and image3d. All are template'd,
+ // parametrized by the kind of value associated to each point.
+ //
+ // We will start to use the 1D images, because there are less values
+ // to assign (!) and because they are easy to display. Although we
+ // will be in 1D, we will talk about "points" and "pixels", just
+ // like in the classical 2D world.
+
+ // Here are the two most basic ways to build an image:
+
+ image1d<int> img1a; // which builds an empty image;
+ image1d<int> img1b(20); // which builds an image with 20 pixels.
+
+ // The type of values enclosed in those images is 'int' for
+ // integers.
+
+ // The empty image has no data and its definition domain is still
+ // unset. We do not know yet the number of pixels it contains.
+ // However, it is really useful to have such an "empty image"
+ // because it is a placeholder for the result of some processing, or
+ // another image.
+
+ // Trying to access the pixel value from an empty image leads to an
+ // error at run-time.
+
+ // Assigning an image to another one is NOT a costly operation.
+ // Actually img1a behaves like some mathematical variable. Put
+ // differently it is just a name to designate an image. After the
+ // following instruction
+
+ img1a = img1b;
+
+ // Both variables img1a and img1b can be used equivalently to access
+ // the same data. Just like in maths we can state that "img1a IS
+ // img2b" and we only have ONE actual image in memory. The image
+ // definition---its domain and its pixel values--is shared by img1a
+ // AND img1b.
+
+
+ // Since an image is a function that maps values to points, to read
+ // or modify a pixel value, we just the same notation than the one
+ // of functions:
+
+ img1a(0) = 7; // Assign value 7 to the 1st pixel of img1a.
+ img1a(10) = 51; // Assign value 51 to the 11th pixel of img1a.
+
+ std::cout << "img1b(10) = " << img1b(10)
+ << std::endl; // Print 51 since img1b is img1a.
+
+ // As you can see, Olena provides a unique easy syntax to access an
+ // image value, whatever we want to read this value or to modify it:
+ // "ima(p)", where p is a variable that represents a point of the 1D
+ // domain. In "val = ima(p)" we read the pixel value, whereas in
+ // "ima(p) = new_val" we write in an image. For 1D images, a 1D
+ // point behaves just like an index so the user can write "ima(i)"
+ // with i being an integer.
+
+
+ // A single image variable can be used to designate one image and
+ // then another one.
+
+ image1d<int> img2a(20); // An image (not empty).
+ image1d<int> img2b(20); // Another one (not empty).
+ image1d<int> img; // A variable.
+
+ img = img2a; // img is img2a
+ img(5) = 19; // so img2a(5) is set to 19.
+
+ img = img2b; // img is NOW img2b
+ img(5) = 69; // so img2b(5) is set to 69.
+
+ std::cout << (100 * img2a(5) + img2b(5)) // Gives 1969.
+ << std::endl;
+
+
+
+ // In the Olena library, all image types behave like image1d:
+ //
+ // +-----------------------------------------------------------+
+ // | |
+ // | - an "empty" image actually is a mathematical variable |
+ // | |
+ // | => just think in a mathemetical way when dealing |
+ // | with images; |
+ // | |
+ // | |
+ // | - no dynamic memory allocation/deallocation is required |
+ // | |
+ // | the user never has to use "new / delete" (the C++ |
+ // | equivalent for the C "malloc / free") so she does |
+ // | not have to manipulate pointers or to directly |
+ // | access memory |
+ // | |
+ // | => Olena prevents the user from making mistakes; |
+ // | |
+ // | |
+ // | - image data/values can be shared between several |
+ // | variables and the memory used for image data is |
+ // | handled by the library |
+ // | |
+ // | => memory management is automatic. |
+ // | |
+ // | |
+ // +-----------------------------------------------------------+
+
+
+
+
+ image1d<char> img3a(0, 19); // These 1D image data go from the
+ // index 0 to the index 19; it thus has
+ // 20 points.
+
+ // Memory has been allocated so data can be stored but pixel values
+ // have not been initialized yet. So we fill img3a, that is, all
+ // pixels of img3a, with the value 'a':
+ level::fill(inplace(img3a), 'a');
+
+ // The "fill" algorithm is located in the sub-namespace "level"
+ // since this algorithm deals with the "level" of pixel values.
+
+ // Note that the term "level" refers to the fact that an
+ // image can be considered as a landscape where the
+ // elevation at a particular location/point is given by the
+ // corresponding pixel value.
+
+ // The full name of this routine is "oln::level::fill". To access
+ // to a particular algorithm, the proper file shall be included.
+ // The file names of algorithms strictly map their C++ name; so
+ // oln::level::fill is defined in the file "oln/level/fill.hh".
+
+ // Most algorithms in Olena are constructed following the classical
+ // scheme: "output algo(input)", where the input image is only read.
+ // However some few algorithms take an input image in order to
+ // modify it. To enforce this particular feature, the user shall
+ // explicitly state that the image is provided so that its data is
+ // modified "inplace".
+
+ // The algorithm call shall be "level::fill(inplace(ima), val)".
+ // When forgetting the "inplace(..)" statement it does not compile.
+
+
+ // We then define below a second image to play with. As you can see
+ // this image has data for the indices 5 to 14 (so it has 10
+ // points). The definition domain of a 1D image can start from
+ // any index, even a negative one.
+ image1d<char> img3b(5, 14);
+
+ // We initialize the image values.
+ level::fill(inplace(img3b), 'b');
+
+ // Last we now paste the contents of img3b in img3a...
+ level::paste(img3b, inplace(img3a));
+
+ // ...and print the result.
+ debug::println(img3a);
+
+ // Before pasting, the couple of images looked like:
+ //
+ // index = 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1
+ // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9
+ //
+ // img3a = a a a a a a a a a a a a a a a a a a a a
+ // img3b = b b b b b b b b b b
+ //
+ // so after pasting we get:
+ // img3a = a a a a a b b b b b b b b b b a a a a a
+ //
+ // Just remember that a point is an absolute location on the
+ // discrete domain. For the 1D case, an index is thus NOT an
+ // offset. When we write "imgb(5)", we designate the first pixel of
+ // imgb since this image starts at index 5.
+
+
+ // With this simple example we can see that images defined on
+ // different domains (or set of points) can interoperate. The set
+ // of points an image is defined on can be accessed and printed.
+ // The following code:
+
+ std::cout << "img3a.points() = " << img3a.points() << std::endl
+ << "img3b.points() = " << img3b.points() << std::endl;
+
+ // gives:
+ // img3a.points() = { (0) .. (19) }
+ // img3b.points() = { (5) .. (14) }
+
+ // The notion of point sets plays an inportant role in Olena. Many
+ // tests are performed at run-time to ensure that the program is
+ // correct.
+
+ // For instance, the algorithm level::paste tests that the set of
+ // points of img3b (whose values are to be pasted) is a subset of
+ // the destination image. We can reproduce this same test:
+
+ std::cout << (img3b.points() <= img3a.points() ?
+ "true" :
+ "false") << std::endl; // which gives 'true'.
+
+ // Accessing the value of an image at a given point also performs a
+ // test to make sure that this point belongs to the image domain
+ // (and consequently that data access in memory is valid). For
+ // instance, calling "img3a(9)" actually runs a code equivalent to
+ // this test:
+
+ point1d p = 9;
+ std::cout << (img3a.points().has(p) ?
+ "true" :
+ "false") << std::endl; // which gives 'true'.
+
+ // The type of 1D image points is "point1d". The 1D image type
+ // features the method "operator()(point1d p)"; when we write
+ // "img3a(9)" it is just a shortcut for "img3a( point1d(9) )".
+
+ // When having a point we can access its index following:
+ std::cout << p.ind() << std::endl; // which gives 9.
+
+ // To know if a point belongs to an image domain or not, we can run
+ // this shorter test:
+ std::cout << (img3a.has(p) ?
+ "true" :
+ "false") << std::endl; // which gives 'true'.
+
+
+ // Since the notion of point is independent from the image it
+ // applies on, we can form expressions where p is used on several
+ // images:
+
+ img3a(p) = 'M', img3b(p) = 'W'; // At index 9, both values change.
+ debug::println(img3a);
+ debug::println(img3b);
+ // we obtain:
+ // a a a a a b b b b M b b b b b a a a a a
+ // b b b b W b b b b b
+
+
+ // To modify all the values of an image we can iterate over its
+ // domain with an index i:
+
+ for (int i = 5; i <= 14; ++i)
+ img3b(i) = 'a' + i - 5;
+ debug::println(img3b);
+ // a b c d e f g h i j
+
+ // There is a safer way to iterate that avoids to provide a wrong
+ // value for the minimum or maximum index value:
+ for (int i = img3b.min_ind(); i <= img3b.max_ind(); ++i)
+ img3b(i) = 'b' + i - img3b.min_ind();
+ debug::println(img3b);
+ // b c d e f g h i j k
+
+
+ // The Olena library was built with the following rationale:
+ //
+ // +-----------------------------------------------------------+
+ // | |
+ // | If you do not want to be "generic", if you are used to |
+ // | the classical way of browsing pixel values, you can! |
+ // | |
+ // +-----------------------------------------------------------+
+
+
+ // Indeed, the loops above depict the "classical" way to iterate
+ // over the contents of a 1D image. The next tour file explains
+ // the solution provided by Olena to write better loops...
+
+
+ // Jump to tour1_extra.cc if you want some more information about
+ // image data management.
+
+ // Jump to tour2.cc to continue the tour.
+}
Index: oln/debug/print.hh
--- oln/debug/print.hh (revision 948)
+++ oln/debug/print.hh (working copy)
@@ -83,6 +83,44 @@
+# ifdef OLN_ENV_1D
+
+ /// Default version.
+
+ template <typename I>
+ void print_1D(const Image<I>&, const I& input, std::ostream& ostr)
+ {
+ print_Gen(input, ostr);
+ }
+
+ /// Version for classical 1D images.
+
+ template <typename I>
+ void print_1D(const Point_Wise_Accessible_Image<I>&, const I& input,
+ std::ostream& ostr)
+ {
+ const oln_coord(I)
+ imin = input.min_ind(),
+ imax = input.max_ind();
+ for (oln_coord(I) i = imin; i <= imax; ++i)
+ {
+ if (input.has(i))
+ ostr << format(input(i));
+ else
+ ostr << '-';
+ ostr << ' ';
+ }
+ }
+
+ template <typename I>
+ void print(const Image_1D<I>& input, std::ostream& ostr)
+ {
+ impl::print_1D(exact(input), exact(input), ostr);
+ }
+
+# endif // OLN_ENV_1D
+
+
# ifdef OLN_ENV_2D
/// Default version.
@@ -128,7 +166,6 @@
# endif // OLN_ENV_2D
-
} // end of namespace oln::debug::impl
Index: oln/debug/iota.hh
--- oln/debug/iota.hh (revision 948)
+++ oln/debug/iota.hh (working copy)
@@ -39,16 +39,16 @@
{
template <typename I>
- void iota(Mutable_Image<I>& in_out);
-
- template <typename I>
void iota(inplace_<I> in_out);
# ifndef OLN_INCLUDE_ONLY
+ namespace impl
+ {
+
template <typename I>
- void iota(Mutable_Image<I>& in_out)
+ void iota_(Mutable_Image<I>& in_out)
{
oln_value(I) v = 0;
oln_fwd_piter(I) p(in_out.points());
@@ -56,10 +56,19 @@
in_out(p) = v++;
}
+ } // end of namespace oln::debug::impl
+
template <typename I>
void iota(inplace_<I> in_out)
{
- iota(in_out.unwrap());
+ impl::iota_(in_out.unwrap());
+ }
+
+ // guard
+ template <typename I>
+ void iota(const Image<I>&)
+ {
+ mlc::abort_<I>::check(); // FIXME: Add err msg.
}
# endif // ! OLN_INCLUDE_ONLY
Index: oln/core/1d/image1d.hh
--- oln/core/1d/image1d.hh (revision 948)
+++ oln/core/1d/image1d.hh (working copy)
@@ -85,6 +85,7 @@
image1d();
image1d(const box1d& b);
+ image1d(const point1d& pmin, const point1d& pmax);
image1d(unsigned n);
bool impl_owns_(const point1d& p) const;
@@ -102,6 +103,9 @@
const box1d& impl_points() const;
};
+ template <typename T, typename D>
+ bool prepare(image1d<T>& target, with_t, const D& dat);
+
# ifndef OLN_INCLUDE_ONLY
@@ -119,6 +123,15 @@
}
template <typename T>
+ image1d<T>::image1d(const point1d& pmin, const point1d& pmax)
+ {
+ precondition(pmax >= pmin);
+ box1d b(pmin, pmax);
+ this->data_ = new data(new array_t(pmin.ind(), pmax.ind()),
+ b);
+ }
+
+ template <typename T>
image1d<T>::image1d(unsigned n)
{
precondition(n != 0);
@@ -185,6 +198,19 @@
return this->data_->second;
}
+ template <typename T, typename D>
+ bool prepare(image1d<T>& target, with_t, const D& dat)
+ {
+ precondition(not target.has_data());
+ box1d b;
+ bool box_ok = init(b, with, dat);
+ postcondition(box_ok);
+ array1d_<T,int>* ptr = new array1d_<T,int>(b.pmin().ind(),
+ b.pmax().ind());
+ target.data__() = new typename image1d<T>::data(ptr, b);
+ return box_ok;
+ }
+
# endif // ! OLN_INCLUDE_ONLY
Index: oln/core/1d/image1d_b.hh
--- oln/core/1d/image1d_b.hh (revision 948)
+++ oln/core/1d/image1d_b.hh (working copy)
@@ -107,6 +107,9 @@
unsigned impl_border() const;
};
+ template <typename T, typename D>
+ bool prepare(image1d_b<T>& target, with_t, const D& dat);
+
# ifndef OLN_INCLUDE_ONLY
@@ -193,6 +196,20 @@
return this->data_->second;
}
+ template <typename T, typename D>
+ bool prepare(image1d_b<T>& target, with_t, const D& dat)
+ {
+ precondition(not target.has_data());
+ box1d b;
+ bool box_ok = init(b, with, dat);
+ postcondition(box_ok);
+ unsigned border = 2; // FIXME: Use init!
+ array1d_<T,int>* ptr = new array1d_<T,int>(b.pmin().ind() - border,
+ b.pmax().ind() + border);
+ target.data__() = new typename image1d_b<T>::data(ptr, border, b);
+ return box_ok;
+ }
+
# endif // ! OLN_INCLUDE_ONLY
Index: oln/core/2d/neighb2d.hh
--- oln/core/2d/neighb2d.hh (revision 948)
+++ oln/core/2d/neighb2d.hh (working copy)
@@ -52,6 +52,7 @@
namespace internal
{
+ // FIXME: constify.
neighb2d mk_c4();
neighb2d mk_c8();
neighb2d mk_c2_row();
@@ -101,6 +102,7 @@
} // end of namespace oln::internal
+ // FIXME: constify.
extern neighb2d c4;
extern neighb2d c8;
extern neighb2d c2_row;
Index: oln/core/2d/vline2d.hh
--- oln/core/2d/vline2d.hh (revision 948)
+++ oln/core/2d/vline2d.hh (working copy)
@@ -28,7 +28,7 @@
#ifndef OLN_CORE_2D_VLINE2D_HH
# define OLN_CORE_2D_VLINE2D_HH
-# include <oln/core/internal/window.hh>
+# include <oln/core/internal/symmetrical_window.hh>
# include <oln/core/2d/dpoint2d.hh>
@@ -39,11 +39,13 @@
class vline2d;
+# define super internal::symmetrical_window_<vline2d>
+
// Super type.
template <>
struct super_trait_< vline2d >
{
- typedef internal::window_<vline2d> ret;
+ typedef super ret;
};
@@ -57,7 +59,7 @@
/// 2D vertical line window.
- class vline2d : public internal::window_< vline2d >
+ class vline2d : public super
{
public:
@@ -66,7 +68,7 @@
private:
void init_(int drow_min, int drow_max);
- void take(); // safety; w/o impl, it provides from calling super::take(dp).
+ void impl_take(); // safety; w/o impl, it provides from calling take(dp).
}; // end of class oln::vline2d
@@ -90,11 +92,13 @@
vline2d::init_(int drow_min, int drow_max)
{
for (int drow = drow_min; drow <= drow_max; ++drow)
- this->internal::window_<vline2d>::take(dpoint2d(drow, 0));
+ this->super::impl_take(dpoint2d(drow, 0));
}
# endif // ! OLN_INCLUDE_ONLY
+#undef super
+
} // end of namespace oln
Index: oln/core/2d/hline2d.hh
--- oln/core/2d/hline2d.hh (revision 948)
+++ oln/core/2d/hline2d.hh (working copy)
@@ -28,7 +28,7 @@
#ifndef OLN_CORE_2D_HLINE2D_HH
# define OLN_CORE_2D_HLINE2D_HH
-# include <oln/core/internal/window.hh>
+# include <oln/core/internal/symmetrical_window.hh>
# include <oln/core/2d/dpoint2d.hh>
@@ -39,11 +39,13 @@
class hline2d;
+# define super internal::symmetrical_window_<hline2d>
+
// Super type.
template <>
struct super_trait_< hline2d >
{
- typedef internal::window_<hline2d> ret;
+ typedef super ret;
};
@@ -57,7 +59,7 @@
/// 2D horizontal line window.
- class hline2d : public internal::window_< hline2d >
+ class hline2d : public super
{
public:
@@ -65,7 +67,7 @@
private:
void init_(int dcol_min, int dcol_max);
- void take(); // safety; w/o impl, it provides from calling super::take(dp).
+ void impl_take(); // safety; w/o impl, it prevents from calling take(dp).
}; // end of class oln::hline2d
@@ -83,11 +85,13 @@
hline2d::init_(int dcol_min, int dcol_max)
{
for (int dcol = dcol_min; dcol <= dcol_max; ++dcol)
- this->internal::window_<hline2d>::take(dpoint2d(0, dcol));
+ this->super::impl_take(dpoint2d(0, dcol));
}
# endif // ! OLN_INCLUDE_ONLY
+# undef super
+
} // end of namespace oln
Index: oln/core/2d/rectangle2d.hh
--- oln/core/2d/rectangle2d.hh (revision 948)
+++ oln/core/2d/rectangle2d.hh (working copy)
@@ -28,7 +28,7 @@
#ifndef OLN_CORE_2D_RECTANGLE2D_HH
# define OLN_CORE_2D_RECTANGLE2D_HH
-# include <oln/core/internal/window.hh>
+# include <oln/core/internal/symmetrical_window.hh>
# include <oln/core/2d/dpoint2d.hh>
@@ -39,11 +39,13 @@
class rectangle2d;
+# define super internal::symmetrical_window_<rectangle2d>
+
// Super type.
template <>
struct super_trait_< rectangle2d >
{
- typedef internal::window_<rectangle2d> ret;
+ typedef super ret;
};
@@ -57,7 +59,7 @@
/// 2D rectangular window.
- class rectangle2d : public internal::window_< rectangle2d >
+ class rectangle2d : public super
{
public:
@@ -70,10 +72,11 @@
private:
void init_(int drow_min, int dcol_min,
int drow_max, int dcol_max);
- void take(); // safety; w/o impl, it provides from calling super::take(dp).
unsigned half_height_, half_width_;
+ void impl_take(); // safety; w/o impl, it prevents from calling take(dp).
+
}; // end of class oln::rectangle2d
@@ -105,11 +108,13 @@
{
for (int drow = drow_min; drow <= drow_max; ++drow)
for (int dcol = dcol_min; dcol <= dcol_max; ++dcol)
- this->internal::window_<rectangle2d>::take(dpoint2d(drow, dcol));
+ this->super::impl_take(dpoint2d(drow, dcol));
}
# endif // ! OLN_INCLUDE_ONLY
+# undef super
+
} // end of namespace oln
Index: oln/core/gen/inplace.hh
--- oln/core/gen/inplace.hh (revision 948)
+++ oln/core/gen/inplace.hh (working copy)
@@ -57,6 +57,11 @@
inplace(Mutable_Image<I>& ima);
+ template <typename I>
+ inplace_<I>
+ inplace(inplace_<I> ima);
+
+
# ifndef OLN_INCLUDE_ONLY
@@ -80,6 +85,8 @@
return this->unwrap();
}
+ // inplace
+
template <typename I>
inplace_<I>
inplace(Mutable_Image<I>& ima)
@@ -88,6 +95,13 @@
return tmp;
}
+ template <typename I>
+ inplace_<I>
+ inplace(inplace_<I> ima)
+ {
+ return ima;
+ }
+
# endif // ! OLN_INCLUDE_ONLY
} // end of namespace oln
Index: oln/core/concept/image.hh
--- oln/core/concept/image.hh (revision 948)
+++ oln/core/concept/image.hh (working copy)
@@ -131,7 +131,9 @@
// stc_typename(output); // FIXME: Uncomment!
stc_typename(plain);
+ bool is_empty() const; // Not subject to delegation.
bool owns_(const psite& p) const;
+
rvalue operator()(const psite& p) const;
rvalue read_(const psite& p) const;
@@ -209,11 +211,16 @@
stc_using_from(Mutable_Image, lvalue);
stc_typename(index);
+ // FIXME: Confusing! We already have indices for 1D images...
+ // FIXME: Use "offset" instead!
rvalue operator[](index i) const;
lvalue operator[](index i);
std::size_t npoints() const;
- // FIXME: ...
+
+ // FIXME: Add:
+ // point point_at_offset(o) const
+ // std::size_t offset_from_point(point p) const
protected:
Fast_Image();
@@ -275,6 +282,11 @@
{
stc_typename(coord);
+ // final
+ coord min_ind() const;
+ coord max_ind() const;
+ unsigned ninds() const;
+
protected:
Image_1D();
};
@@ -443,8 +455,16 @@
template <typename Exact>
bool
+ Image<Exact>::is_empty() const
+ {
+ return exact(this)->impl_is_empty();
+ }
+
+ template <typename Exact>
+ bool
Image<Exact>::owns_(const typename Image<Exact>::psite& p) const
{
+ precondition(not this->is_empty());
return exact(this)->impl_owns_(p);
}
@@ -626,6 +646,27 @@
{
}
+ template <typename Exact>
+ typename Image_1D<Exact>::coord
+ Image_1D<Exact>::min_ind() const
+ {
+ return this->bbox().pmin().ind();
+ }
+
+ template <typename Exact>
+ typename Image_1D<Exact>::coord
+ Image_1D<Exact>::max_ind() const
+ {
+ return this->bbox().pmax().ind();
+ }
+
+ template <typename Exact>
+ unsigned
+ Image_1D<Exact>::ninds() const
+ {
+ return this->bbox().pmax().ind() - this->bbox().pmin().ind() + 1;
+ }
+
// ----------------------------------- Image_2D<Exact>
template <typename Exact>
Index: oln/core/concept/function.hh
--- oln/core/concept/function.hh (revision 948)
+++ oln/core/concept/function.hh (working copy)
@@ -37,18 +37,6 @@
{
- /*
-
- // Fwd decl.
- namespace morpher {
- template <typename I, typename F> class two_way;
- template <typename I, typename F> class two_way_rw;
- }
- namespace value { template <typename I, typename F> class two_way; }
-
- */
-
-
template <typename Exact>
struct Function : public Any<Exact>
{
@@ -90,42 +78,17 @@
};
- /*
-
// Value1 -> Value2 *and* Value2 -> Value1.
template <typename Exact>
struct Function_v2w2v : public Function<Exact>
{
- public:
-
- template <typename I>
- oln::morpher::two_way<I, Exact>
- operator()(oln::abstract::mutable_image<I>& input) const;
-
+ typedef Function_v2w2v<void> category;
protected:
Function_v2w2v();
};
- // (Image, Point) -> Value2 *and* (Image, Point, Value2) -> Value1.
-
- template <typename Exact>
- struct Function_rw : public Function<Exact>
- {
- public:
-
- template <typename I>
- oln::morpher::two_way_rw<I, Exact>
- operator()(oln::abstract::mutable_image<I>& input) const;
-
- protected:
- Function_rw();
- };
-
- */
-
-
// Point -> Point.
template <typename Exact>
@@ -159,21 +122,12 @@
{
}
- /*
-
template <typename Exact>
Function_v2w2v<Exact>::Function_v2w2v()
{
}
template <typename Exact>
- Function_rw<Exact>::Function_rw()
- {
- }
-
- */
-
- template <typename Exact>
Function_p2p<Exact>::Function_p2p()
{
}
Index: oln/core/concept/image_identity.hh
Index: oln/core/internal/image_selectors.hh
--- oln/core/internal/image_selectors.hh (revision 948)
+++ oln/core/internal/image_selectors.hh (working copy)
@@ -28,9 +28,15 @@
#ifndef OLN_CORE_INTERNAL_IMAGE_SELECTORS_HH
# define OLN_CORE_INTERNAL_IMAGE_SELECTORS_HH
+# include <oln/core/concept/grid.hh>
# include <oln/core/concept/image.hh>
+
+// FIXME: Bad! Move Grid_*D into concept/grid.hh...
+# include <oln/core/1d/grid1d.hh>
# include <oln/core/2d/grid2d.hh>
-# include <oln/value/tags.hh>
+# include <oln/core/3d/grid3d.hh>
+
+# include <oln/value/tags.hh> // FIXME: Bad!
namespace oln
@@ -69,11 +75,27 @@
template <typename Exact>
struct case_< Image_dimension, Exact, 1 >
:
+ where_< stc_is_a(grid, Grid_1D) >
+ {
+ typedef Image_1D<Exact> ret;
+ };
+
+ template <typename Exact>
+ struct case_< Image_dimension, Exact, 2 >
+ :
where_< stc_is_a(grid, Grid_2D) >
{
typedef Image_2D<Exact> ret;
};
+ template <typename Exact>
+ struct case_< Image_dimension, Exact, 3 >
+ :
+ where_< stc_is_a(grid, Grid_3D) >
+ {
+ typedef Image_3D<Exact> ret;
+ };
+
// FIXME: ...
Index: oln/core/internal/window.hh
--- oln/core/internal/window.hh (revision 948)
+++ oln/core/internal/window.hh (working copy)
@@ -72,12 +72,16 @@
public:
stc_using(point);
- typedef typename point::dpoint dpoint;
+ typedef oln_dpoint(point) dpoint;
- window_();
Exact& take(const dpoint& dp);
+ Exact& impl_take(const dpoint& dp);
+
Exact impl_op_unary_minus_() const;
+ protected:
+ window_();
+
}; // end of class oln::internal::window_<Exact>
@@ -92,7 +96,14 @@
Exact&
window_<Exact>::take(const typename window_<Exact>::dpoint& dp)
{
- this->take_( dp);
+ return exact(this)->impl_take(dp);
+ }
+
+ template <typename Exact>
+ Exact&
+ window_<Exact>::impl_take(const typename window_<Exact>::dpoint& dp)
+ {
+ this->take_(dp); // from dpoints_impl_.
return exact(*this);
}
Index: oln/core/internal/image_base.hh
--- oln/core/internal/image_base.hh (revision 948)
+++ oln/core/internal/image_base.hh (working copy)
@@ -238,6 +238,7 @@
stc_typename(data);
+ bool impl_is_empty() const;
bool has_data() const;
// pseudo-private:
@@ -360,9 +361,15 @@
/// image_base_<Exact>
template <typename Exact>
+ bool image_base_<Exact>::impl_is_empty() const
+ {
+ return this->data_ = 0; // FIXME: This is not sufficient...
+ }
+
+ template <typename Exact>
bool image_base_<Exact>::has_data() const
{
- return this->data_ != 0;
+ return this->data_ != 0; // FIXME: redundant with is_empty? (no)
}
template <typename Exact>
Index: oln/core/internal/op_image_extended_by_nbh.hh
--- oln/core/internal/op_image_extended_by_nbh.hh (revision 948)
+++ oln/core/internal/op_image_extended_by_nbh.hh (working copy)
@@ -28,6 +28,7 @@
#ifndef OLN_CORE_INTERNAL_OP_IMAGE_EXTENDED_BY_NBH_HH
# define OLN_CORE_INTERNAL_OP_IMAGE_EXTENDED_BY_NBH_HH
+# include <mlc/unconst.hh>
# include <oln/core/concept/neighborhood.hh>
# include <oln/core/internal/image_base.hh>
# include <oln/core/gen/op.hh>
@@ -123,10 +124,14 @@
template <typename N, typename I>
bool init_(Neighborhood<N>* this_,
+ const internal::single_image_morpher_<I>& dat);
+
+ template <typename N, typename I>
+ bool init_(Neighborhood<N>* this_,
const internal::current& dat);
template <typename I, typename N>
- bool init_(Image<I>* this_,
+ bool init_(Image<I>* this_, // FIXME: Pb with I being "const J"...
const internal::current& dat);
@@ -186,6 +191,14 @@
template <typename N, typename I>
bool init_(Neighborhood<N>* this_,
+ const internal::single_image_morpher_<I>& data)
+ {
+ exact(*this_) = data.nbhood();
+ return true;
+ }
+
+ template <typename N, typename I>
+ bool init_(Neighborhood<N>* this_,
const internal::current& data)
{
exact(*this_) = data.nbhood();
@@ -220,7 +233,7 @@
precondition(not target.has_data());
target.data__() = new typename op_<I, extended_by, N>::data;
bool ima_ok = prepare(target.data__()->first, with, dat);
- bool nbh_ok = init(target.data__()->second, with, dat);
+ bool nbh_ok = init(mlc::unconst_cast(target.data__()->second), with, dat);
postcondition(ima_ok);
postcondition(nbh_ok);
return ima_ok and nbh_ok;
Index: oln/core/internal/special_op.hh
--- oln/core/internal/special_op.hh (revision 948)
+++ oln/core/internal/special_op.hh (working copy)
@@ -41,14 +41,14 @@
template <typename L, typename OpName, typename R> class op_;
- /// Virtual types.
+ // Virtual types.
template <typename Lcat, typename L, typename OpName, typename Rcat, typename R>
struct vtypes< internal::special_op_<Lcat, L, OpName, Rcat, R> >
/* undefined; to be specialized... */
;
- /// Super type.
+ // Super type.
template <typename Lcat, typename L, typename OpName, typename Rcat, typename R>
struct super_trait_< internal::special_op_<Lcat, L, OpName, Rcat, R> >
/* undefined; to be specialized... */
Index: oln/core/internal/symmetrical_window.hh
--- oln/core/internal/symmetrical_window.hh (revision 0)
+++ oln/core/internal/symmetrical_window.hh (revision 0)
@@ -0,0 +1,111 @@
+// Copyright (C) 2007 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#ifndef OLN_CORE_INTERNAL_SYMMETRICAL_WINDOW_HH
+# define OLN_CORE_INTERNAL_SYMMETRICAL_WINDOW_HH
+
+# include <oln/core/internal/window.hh>
+
+
+namespace oln
+{
+
+
+ // Fwd decl.
+ namespace internal { template <typename Exact> class symmetrical_window_; }
+
+#define current symmetrical_window_<Exact>
+#define super internal::window_<Exact>
+
+ // Super type.
+ template <typename Exact>
+ struct super_trait_< internal::current >
+ {
+ typedef super ret;
+ };
+
+
+ // Virtual types.
+ template <typename Exact>
+ struct vtypes< internal::current >
+ {
+ };
+
+ namespace internal
+ {
+
+ /// Base implementation class for symmetrical window classes.
+
+ template <typename Exact>
+ class symmetrical_window_ : public super
+ {
+ public:
+ stc_using(dpoint);
+
+ const Exact& impl_op_unary_minus_() const;
+ Exact& impl_take(const dpoint& dp);
+
+ protected:
+ symmetrical_window_();
+
+ }; // end of class oln::internal::symmetrical_window_<Exact>
+
+
+# ifndef OLN_INCLUDE_ONLY
+
+ template <typename Exact>
+ current::symmetrical_window_()
+ {
+ }
+
+ template <typename Exact>
+ const Exact&
+ current::impl_op_unary_minus_() const
+ {
+ return exact(*this);
+ }
+
+ template <typename Exact>
+ Exact&
+ current::impl_take(const typename current::dpoint& dp)
+ {
+ this->super::impl_take(dp);
+ this->super::impl_take(-dp);
+ return exact(*this);
+ }
+
+ } // end of namespace oln::internal
+
+# endif // ! OLN_INCLUDE_ONLY
+
+# undef super
+# undef current
+
+} // end of namespace oln
+
+
+#endif // ! OLN_CORE_INTERNAL_SYMMETRICAL_WINDOW_HH
Index: oln/draw/bresenham.hh
--- oln/draw/bresenham.hh (revision 948)
+++ oln/draw/bresenham.hh (working copy)
@@ -46,11 +46,6 @@
// Fwd decl.
template <typename I>
- void bresenham(Mutable_Image<I>& in_out,
- const oln_point(I)& begin, const oln_point(I)& end,
- const oln_value(I)& value);
-
- template <typename I>
void bresenham(inplace_<I> in_out,
const oln_point(I)& begin, const oln_point(I)& end,
const oln_value(I)& value);
@@ -66,28 +61,32 @@
const oln_point(I)& begin, const oln_point(I)& end,
const oln_value(I)& value)
{
- level::paste(literal(value) / line2d(begin, end), in_out);
+ level::paste(literal(value) / line2d(begin, end),
+ inplace(in_out));
}
} // end of namespace oln::draw::impl
- // Facades.
+ // Facade.
template <typename I>
- void bresenham(Mutable_Image<I>& in_out,
+ void bresenham(inplace_<I> in_out,
const oln_point(I)& begin, const oln_point(I)& end,
const oln_value(I)& value)
{
- impl::bresenham_(exact(in_out), begin, end, value);
+ impl::bresenham_(in_out.unwrap(), begin, end, value);
}
- template <typename I>
- void bresenham(inplace_<I> in_out,
- const oln_point(I)& begin, const oln_point(I)& end,
- const oln_value(I)& value)
+
+ // Guard.
+
+ template <typename I, typename P, typename V>
+ void bresenham(const Image<I>&,
+ const P&, const P&,
+ const V&)
{
- bresenham(in_out.unwrap(), begin, end, value);
+ mlc::abort_<I>::check(); // FIXME: Add err msg.
}
# endif // ! OLN_INCLUDE_ONLY
Index: oln/morpho/cc_tarjan.hh
--- oln/morpho/cc_tarjan.hh (revision 948)
+++ oln/morpho/cc_tarjan.hh (working copy)
@@ -29,6 +29,8 @@
# define OLN_MORPHO_CC_TARJAN_HH
# include <oln/core/concept/image.hh>
+# include <oln/core/internal/f_ch_value.hh>
+# include <oln/level/fill.hh>
namespace oln
{
@@ -116,10 +118,10 @@
oln_plain_value(I, oln_point(I)) parent;
prepare(parent, with, input);
- oln_plain(I) is_processed;
+ // init.
+ oln_plain_value(I, bool) is_processed;
prepare(is_processed, with, input);
- oln_piter(I) p1(is_processed.points());
- is_processed(p1) = false; // FIXME : built with ?.
+ level::fill(inplace(is_processed), false);
first_pass(input, parent, is_processed);
second_pass(input, parent, output);
Index: oln/level/fill.hh
--- oln/level/fill.hh (revision 948)
+++ oln/level/fill.hh (working copy)
@@ -53,36 +53,22 @@
// Fwd decls.
template <typename I>
- void fill(Mutable_Image<I>& target, /* with */ const oln_value(I)& value);
+ void fill(inplace_<I> target, /* with */ const oln_value(I)& value);
template <typename I, typename J>
- void fill(Mutable_Image<I>& target, /* with */ const Image<J>& data);
+ void fill(inplace_<I> target, /* with */ const Image<J>& data);
template <typename I, typename F>
- void fill(Mutable_Image<I>& target, /* with */ const Function_p2v<F>& fun);
+ void fill(inplace_<I> target, /* with */ const Function_p2v<F>& fun);
template <typename I, typename V, typename P>
- void fill(Mutable_Image<I>& target, /* with */ V (*fun)(P));
+ void fill(inplace_<I> target, /* with */ V (*f)(P));
// FIXME: Inactivated.
// template <typename I>
// void fill(Value_Wise_Mutable_Image<I>& target, const oln_value(I)& value);
- // versions for temporary images
-
- template <typename I>
- void fill(inplace_<I> target, /* with */ const oln_value(I)& value);
-
- template <typename I, typename J>
- void fill(inplace_<I> target, /* with */ const Image<J>& data);
-
- template <typename I, typename F>
- void fill(inplace_<I> target, /* with */ const Function_p2v<F>& fun);
-
- template <typename I, typename V, typename P>
- void fill(inplace_<I> target, /* with */ V (*fun)(P));
-
# ifndef OLN_INCLUDE_ONLY
@@ -130,56 +116,44 @@
/// Facades.
template <typename I>
- void fill(Mutable_Image<I>& target, const oln_value(I)& value)
+ void fill(inplace_<I> target, const oln_value(I)& value)
{
- impl::fill_from_value_(exact(target), value);
+ impl::fill_from_value_(target.unwrap(), value);
}
template <typename I, typename J>
- void fill(Mutable_Image<I>& target, const Image<J>& data)
+ void fill(inplace_<I> target, const Image<J>& data)
{
assert_same_grid_<I, J>::check();
- precondition(target.points() <= data.points());
- impl::fill_from_image_(exact(target), exact(data));
+ precondition(target.unwrap().points() <= data.points());
+ impl::fill_from_image_(target.unwrap(), exact(data));
}
template <typename I, typename F>
- void fill(Mutable_Image<I>& target, const Function_p2v<F>& fun)
+ void fill(inplace_<I> target, const Function_p2v<F>& fun)
{
- impl::fill_from_function_(exact(target), exact(fun));
+ typedef mlc_basic(oln_argument(F)) P;
+ mlc::assert_< mlc_is_a(P, Point) >::check(); // FIXME: Add err msg.
+ // FIXME: Check also the value type.
+ impl::fill_from_function_(target.unwrap(), exact(fun));
}
template <typename I, typename V, typename P>
- void fill(Mutable_Image<I>& target, V (*f)(P))
+ void fill(inplace_<I> target, V (*f)(P))
{
mlc::assert_< mlc_is_a(P, Point) >::check(); // FIXME: Add err msg.
- impl::fill_from_function_(exact(target), functorize_p2v(f));
+ // FIXME: Check also the value type.
+ impl::fill_from_function_(target.unwrap(), functorize_p2v(f));
}
- // with inplace_<I>
-
- template <typename I>
- void fill(inplace_<I> target, const oln_value(I)& value)
- {
- fill(target.unwrap(), value);
- }
- template <typename I, typename J>
- void fill(inplace_<I> target, const Image<J>& data)
- {
- fill(target.unwrap(), data);
- }
- template <typename I, typename F>
- void fill(inplace_<I> target, const Function_p2v<F>& fun)
- {
- fill(target.unwrap(), fun);
- }
+ /// Guard.
- template <typename I, typename V, typename P>
- void fill(inplace_<I> target, V (*fun)(P))
+ template <typename I, typename T>
+ void fill(const Image<I>&, const T&)
{
- fill(target.unwrap(), fun);
+ mlc::abort_<I>::check(); // FIXME: Add err msg.
}
# endif // ! OLN_INCLUDE_ONLY
Index: oln/level/clone.hh
--- oln/level/clone.hh (revision 948)
+++ oln/level/clone.hh (working copy)
@@ -1,5 +1,5 @@
-// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006 EPITA Research and
-// Development Laboratory
+// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 EPITA
+// Research and Development Laboratory
//
// This file is part of the Olena Library. This library is free
// software; you can redistribute it and/or modify it under the terms
Index: oln/level/apply_inplace.hh
--- oln/level/apply_inplace.hh (revision 948)
+++ oln/level/apply_inplace.hh (working copy)
@@ -80,27 +80,26 @@
/// Facades.
template <typename F, typename I>
- void apply_inplace(const Function_v2v<F>& f, Mutable_Image<I>& in_out)
+ void apply_inplace(const Function_v2v<F>& f, inplace_<I> in_out)
{
- impl::apply_inplace_(exact(f), exact(in_out));
+ // FIXME: Add check.
+ impl::apply_inplace_(exact(f), in_out.unwrap());
}
template <typename R, typename A, typename I>
- void apply_inplace(R (*f)(A), Mutable_Image<I>& in_out)
+ void apply_inplace(R (*f)(A), inplace_<I> in_out)
{
- impl::apply_inplace_(functorize_v2v(f), exact(in_out));
+ // FIXME: Add check.
+ impl::apply_inplace_(functorize_v2v(f), in_out.unwrap());
}
- template <typename F, typename I>
- void apply_inplace(const Function_v2v<F>& f, inplace_<I> in_out)
- {
- apply_inplace(f, in_out.unwrap());
- }
- template <typename R, typename A, typename I>
- void apply_inplace(R (*f)(A), inplace_<I> in_out)
+ /// Guard.
+
+ template <typename T, typename I>
+ void apply_inplace(const T&, const Image<I>&)
{
- apply_inplace(f, in_out.unwrap());
+ mlc::abort_<I>::check(); // FIXME: Add err msg.
}
# endif // ! OLN_INCLUDE_ONLY
Index: ChangeLog
from Ugo Jardonnet <ugo.jardonnet(a)lrde.epita.fr>
Draft canvas : 3 versions (Two_pass).
* oln/canvas/queue_based.hh: New.
* oln/canvas/parallel.hh: New.
* oln/canvas/two_pass_until_stability.hh: New.
* oln/canvas/two_pass.hh: .
* oln/canvas/until_stability.hh: New.
parallel.hh | 42 ++++++++++++++++++++++++++
queue_based.hh | 54 ++++++++++++++++++++++++++++++++++
two_pass.hh | 62 ++++++++++++++++++++++++++++++++++++---
two_pass_until_stability.hh | 69 ++++++++++++++++++++++++++++++++++++++++++++
until_stability.hh | 58 ++++++++++++++++++++++++++++++++++++
5 files changed, 281 insertions(+), 4 deletions(-)
Index: oln/canvas/queue_based.hh
--- oln/canvas/queue_based.hh (revision 0)
+++ oln/canvas/queue_based.hh (revision 0)
@@ -0,0 +1,54 @@
+// Copyright (C) 2007 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have receiv a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#ifndef OLN_CANVAS_QUEUE_BASED_HH
+# define OLN_CANVAS_QUEUE_BASED_HH
+
+namespace canvas
+{
+
+ template <typename F, typename I>
+ void queue_based(F f, I input)
+ {
+ queue q;
+
+ f.init(input);
+
+ oln_piter(I) p1(input.points());
+ for_all(p1)
+ f.enqueue(p1, q, input);
+
+ while ( !q.empty() ) do
+ {
+ oln_piter(I) p = q.deq();
+ f.loop(p, input);
+ }
+
+ f.final(input);
+ }
+
+#endif // ! OLN_CANVAS_QUEUE_BASED_HH
Index: oln/canvas/parallel.hh
--- oln/canvas/parallel.hh (revision 0)
+++ oln/canvas/parallel.hh (revision 0)
@@ -0,0 +1,42 @@
+// Copyright (C) 2007 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have receiv a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#ifndef OLN_CANVAS_PARALLEL_HH
+# define OLN_CANVAS_PARALLEL_HH
+
+namespace canvas
+{
+
+ template <typename F, typename I>
+ void parallel(F f, I input)
+ {
+
+ }
+
+}
+
+#endif // ! OLN_CANVAS_PARALLEL_HH
Index: oln/canvas/two_pass_until_stability.hh
--- oln/canvas/two_pass_until_stability.hh (revision 0)
+++ oln/canvas/two_pass_until_stability.hh (revision 0)
@@ -0,0 +1,69 @@
+// Copyright (C) 2007 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have receiv a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#ifndef OLN_CANVAS_TWO_PASS_UNTIL_STABILITY_HH
+# define OLN_CANVAS_TWO_PASS_UNTIL_STABILITY_HH
+
+namespace canvas
+{
+
+ template <typename F, typename I>
+ void two_pass_until_stability(F f, I input)
+ {
+ bool stability;
+
+ f.init(input);
+
+ for (;;)
+ {
+
+ // first pass
+ oln_fwd_piter(I) p1(input.points());
+ for_all(p1)
+ f.first_pass_body(p1, input);
+
+ // second pass
+ oln_bkd_piter(I) p2(input.points());
+ for_all(p2)
+ f.second_pass_body(p2, input);
+
+ // stability check
+ stability = f.is_stable(input); // Oblige de posseder output.
+ if (stability)
+ return;
+
+ // prepare a new loop iteration
+ f.re_loop(input);
+ }
+
+ f.final(input);
+ }
+
+
+}
+
+#endif // ! OLN_CANVAS_TWO_PASS_UNTIL_STABILITY_HH
Index: oln/canvas/two_pass.hh
--- oln/canvas/two_pass.hh (revision 947)
+++ oln/canvas/two_pass.hh (working copy)
@@ -31,21 +31,75 @@
namespace canvas
{
- template <typename F, typename I>
- void two_pass(F f, I input)
+ namespace v1
{
+ template <template <class> class F,
+ typename I>
+ void two_pass(F<I> f)
+ {
+ mlc::assert_< mlc_is_a(I, Image) >::check();
+
f.init();
- oln_piter(I) p1(input.points());
+ // first pass
+ oln_fwd_piter(I) p1(f.input.points());
for_all(p1)
f.first_pass_body(p1);
- oln_bkd_piter(I) p2(input.points());
+ // second pass
+ oln_bkd_piter(I) p2(f.input.points());
for_all(p2)
f.second_pass_body(p2);
f.final();
}
+ }
+
+ namespace v2
+ {
+ template <typename F, typename I>
+ void two_pass(F f, I input)
+ {
+ mlc::assert_< mlc_is_a(I, Image) >::check();
+
+ f.init(input);
+
+ // first pass
+ oln_fwd_piter(I) p1(input.points());
+ for_all(p1)
+ f.first_pass_body(p1, input);
+
+ // second pass
+ oln_bkd_piter(I) p2(input.points());
+ for_all(p2)
+ f.second_pass_body(p2, input);
+
+ f.final(input);
+ }
+ }
+
+ namespace v3
+ {
+ template <typename F, typename I, typename A>
+ void two_pass(F f, I input, A aux)
+ {
+ mlc::assert_< mlc_is_a(I, Image) >::check();
+
+ f.init(input, aux);
+
+ // first pass
+ oln_fwd_piter(I) p1(input.points());
+ for_all(p1)
+ f.first_pass_body(p1, input, aux);
+
+ // second pass
+ oln_bkd_piter(I) p2(input.points());
+ for_all(p2)
+ f.second_pass_body(p2, input, aux);
+
+ f.final(input, aux);
+ }
+ }
}
Index: oln/canvas/until_stability.hh
--- oln/canvas/until_stability.hh (revision 0)
+++ oln/canvas/until_stability.hh (revision 0)
@@ -0,0 +1,58 @@
+// Copyright (C) 2007 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have receiv a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#ifndef OLN_CANVAS_UNTIL_STABILITY_HH
+# define OLN_CANVAS_UNTIL_STABILITY_HH
+
+namespace canvas
+{
+
+ template <typename F>
+ void until_stability(F f)
+ {
+ bool stability;
+
+ f.init();
+
+ for (;;)
+ {
+ f.loop_body();
+
+ // stability check
+ stability = f.is_stable();
+ if (stability)
+ return;
+
+ // prepare a new loop iteration
+ f.re_loop();
+ }
+
+ f.final();
+ }
+}
+
+#endif // ! OLN_CANVAS_UNTIL_STABILITY_HH
https://svn.lrde.epita.fr/svn/oln/trunk/olena
Index: ChangeLog
from Thierry Geraud <thierry.geraud(a)lrde.epita.fr>
Add the type of value-casted images.
* oln/core/gen/casted_image.hh: New.
* oln/core/gen/value_cast.hh (include): Add casted_image.hh.
* oln/morpher/stack_rw.hxx,
* oln/morpher/value_cast.hh,
* oln/morpher/identity.hh,
* oln/morpher/thru_fun.hh,
* oln/morpher/tags.hh,
* oln/morpher/value_cast.hxx,
* oln/morpher/count_rw.hh,
* oln/morpher/identity.hxx,
* oln/morpher/stack.hh,
* oln/morpher/count_rw.hxx,
* oln/morpher/stack_rw.hh,
* oln/morpher/stack.hxx,
* oln/morpher/internal/image_value_morpher.hh,
* oln/morpher/internal/image_extension.hh: Remove; obsolete.
casted_image.hh | 146 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
value_cast.hh | 3 +
2 files changed, 149 insertions(+)
Index: oln/core/gen/casted_image.hh
--- oln/core/gen/casted_image.hh (revision 0)
+++ oln/core/gen/casted_image.hh (revision 0)
@@ -0,0 +1,146 @@
+// Copyright (C) 2007 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#ifndef OLN_CORE_GEN_CASTED_IMAGE_HH
+# define OLN_CORE_GEN_CASTED_IMAGE_HH
+
+# include <oln/core/gen/through.hh>
+# include <oln/core/gen/pw_value.hh>
+# include <oln/core/internal/f_ch_value.hh>
+
+
+namespace oln
+{
+
+
+# define current casted_image<I, V>
+# define super internal::value_morpher_< current >
+
+
+ // Fwd decl.
+ template <typename I, typename V> class casted_image;
+
+
+ // Super type.
+ template <typename I, typename V>
+ struct super_trait_< current >
+ {
+ typedef super ret;
+ };
+
+
+ // Virtual types.
+ template <typename I, typename V>
+ struct vtypes< current >
+ {
+ typedef I delegatee;
+ typedef internal::singleton<const I> data;
+
+ typedef V value;
+ typedef V rvalue;
+
+ typedef oln_plain_value(I, V) plain;
+ typedef casted_image<pl::rec<I>, V> skeleton;
+ };
+
+
+ /// casted_image<I, V>
+
+ template <typename I, typename V>
+ class casted_image : public super
+ {
+ public:
+ stc_using(data);
+ stc_using(psite);
+
+ casted_image();
+ casted_image(const Image<I>& ima);
+
+ const I& impl_image() const;
+
+ V impl_read(const psite& p) const;
+ };
+
+
+ // value_cast
+
+ template <typename V, typename I>
+ casted_image<I, V> value_cast(const Image<I>& ima);
+
+
+# ifndef OLN_INCLUDE_ONLY
+
+ template <typename I, typename V>
+ current::casted_image()
+ {
+ }
+
+ template <typename I, typename V>
+ current::casted_image(const Image<I>& ima)
+ {
+ precondition(exact(ima).has_data());
+ this->data_ = new data(exact(ima));
+ }
+
+ template <typename I, typename V>
+ const I&
+ current::impl_image() const
+ {
+ assert(this->has_data());
+ return this->data_->value;
+ }
+
+ template <typename I, typename V>
+ V
+ current::impl_read(const typename current::psite& p) const
+ {
+ assert(this->has_data());
+ assert(this->image().has_data());
+ return this->data_->value(p);
+ }
+
+ // value_cast
+
+ template <typename V, typename I>
+ current value_cast(const Image<I>& ima)
+ {
+ current tmp(ima);
+ return tmp;
+ }
+
+# endif // ! OLN_INCLUDE_ONLY
+
+# undef super
+# undef current
+
+} // end of namespace oln
+
+
+# include <oln/core/gen/value_cast.hh>
+
+
+#endif // ! OLN_CORE_GEN_CASTED_IMAGE_HH
Index: oln/core/gen/value_cast.hh
--- oln/core/gen/value_cast.hh (revision 945)
+++ oln/core/gen/value_cast.hh (working copy)
@@ -88,4 +88,7 @@
} // end of namespace oln
+# include <oln/core/gen/casted_image.hh>
+
+
#endif // ! OLN_CORE_GEN_VALUE_CAST_HH