Commit c4f62af7 authored by Thierry Geraud's avatar Thierry Geraud
Browse files

Add memcpy_ and memset_ for fast images; some fixes.

	* tests/histo.cc: Augment.
	* tests/level_memcpy_.cc: New.
	* tests/level_memset_.cc: New.
	* mln/convert/to_vec_p.hh: Typos.
	* mln/core/concept/generalized_pixel.hh (doc): Fix.
	* mln/core/concept/fast_image.hh (ncells): New.
	Add FIXMEs.
	* mln/core/concept/doc/fast_image.hh: Update.
	* mln/level/fill.hh (fill_with_value): Use memset_.
	* mln/level/memset_.hh: New.
	* mln/level/memcpy_.hh: New.
	* mln/value/int_s.hh (props): Fix card_.
	(int_s): Fix preconditions.


git-svn-id: https://svn.lrde.epita.fr/svn/oln/trunk@1081 4aad255d-cdde-0310-9447-f3009e2ae8c0
parent 5ac31483
2007-09-06 Thierry Geraud <thierry.geraud@lrde.epita.fr>
Add memcpy_ and memset_ for fast images; some fixes.
* tests/histo.cc: Augment.
* tests/level_memcpy_.cc: New.
* tests/level_memset_.cc: New.
* mln/convert/to_vec_p.hh: Typos.
* mln/core/concept/generalized_pixel.hh (doc): Fix.
* mln/core/concept/fast_image.hh (ncells): New.
Add FIXMEs.
* mln/core/concept/doc/fast_image.hh: Update.
* mln/level/fill.hh (fill_with_value): Use memset_.
* mln/level/memset_.hh: New.
* mln/level/memcpy_.hh: New.
* mln/value/int_s.hh (props): Fix card_.
(int_s): Fix preconditions.
2007-09-06 Matthieu Garrigues <garrigues.matthieu@lrde.epita.fr>
add convertion from histo to image1d
......
......@@ -34,6 +34,7 @@
*/
# include <mln/core/vec_p.hh>
# include <mln/core/concept/window.hh>
namespace mln
......@@ -47,9 +48,9 @@ namespace mln
vec_p<mln_point(S)> to_vec_p(const Point_Set<S>& pset);
/// Convert a window \p win with a point \p p into a vec_p (point set vector).
/// Convert a window \p win centered at point \p p into a vec_p (point set vector).
template <typename W>
vec_p<mln_point(W)> to_vec_p(const Window<W>& win, const mln_point(W) p);
vec_p<mln_point(W)> to_vec_p(const Window<W>& win, const mln_point(W)& p);
# ifndef MLN_INCLUDE_ONLY
......@@ -67,17 +68,16 @@ namespace mln
}
template <typename W>
vec_p<mln_point(W)> to_vec_p(const Window<W>& win, const mln_point(W) p_center)
vec_p<mln_point(W)> to_vec_p(const Window<W>& win, const mln_point(W)& p)
{
vec_p<mln_point(W)> v;
mln_qiter(W) dp(win, p_center);
v.reserve(exact(win).ndpoints());
for_all(dp)
v.append(dp);
mln_qiter(W) q(win, p);
for_all(q)
v.append(q);
return v;
}
# endif // ! MLN_INCLUDE_ONLY
} // end of namespace mln::convert
......
......@@ -97,6 +97,13 @@ namespace mln
*/
lvalue operator[](unsigned o);
/*! \brief Give the number of pixels of the image including
* those of the virtual border.
*
* \pre The image has to be initialized.
*/
std::size_t ncells() const;
};
} // end of namespace mln::doc
......
......@@ -51,7 +51,7 @@ namespace mln
/*
unsigned border();
int offset(const dpoint& dp) const;
int offset(const dpoint& dp) const; // FIXME: std::ptr_diff_t?
point point_at_offset(unsigned o) const;
mln_qlf_value(E)* buffer();
......@@ -59,6 +59,8 @@ namespace mln
rvalue operator[](unsigned o) const;
lvalue operator[](unsigned o);
std::size_t ncells() const;
*/
......@@ -72,7 +74,8 @@ namespace mln
* \post p == point_at_offset(result)
*/
template <typename P>
unsigned offset(const Generalized_Point<P>& p) const;
unsigned
offset_at(const Generalized_Point<P>& p) const;
protected:
Fast_Image();
......@@ -83,11 +86,11 @@ namespace mln
template <typename E>
template <typename P>
unsigned
Fast_Image<E>::offset(const Generalized_Point<P>& p_) const
unsigned // FIXME: std::size_t?
Fast_Image<E>::offset_at(const Generalized_Point<P>& p_) const
{
// FIXME: check that P is mln_point(E)
const E& this_ = exact(this);
const E* this_ = exact(this);
const P& p = internal::force_exact<P>(p_);
mln_precondition(this_->has_data());
mln_precondition(this_->owns_(p));
......@@ -128,6 +131,9 @@ namespace mln
lvalue (E::*m7)(unsigned) = & E::operator[];
m7 = 0;
std::size_t (E::*m8)() const = & E::ncells;
m8 = 0;
// FIXME: how to check that qixter are defined when W is unknown!
}
......
......@@ -41,13 +41,9 @@
namespace mln
{
// FIXME: \class Generalized_Pixel Generalized_Pixel.hh "mln/core/concept/doc/Generalized_Pixel.hh"
/*! \brief Base class for implementation classes that are pixels or that
* have the behavior of pixels.
*
* "Generalized_Pixel" is "Generalized Pixel" for short.
*
* \warning This class does \em not derive from mln::Object; it is
* for use as a parallel hierarchy.
*
......
......@@ -39,6 +39,7 @@
# include <mln/core/concept/image.hh>
# include <mln/core/concept/function.hh>
# include <mln/level/memset_.hh>
namespace mln
......@@ -131,10 +132,8 @@ namespace mln
// fill_with_value
template <typename I>
void fill_with_value(Image<I>& ima_, const mln_value(I)& value,
bool force_call = false)
void fill_with_value(Image<I>& ima_, const mln_value(I)& value)
{
force_call = false; // just to avoid warning ("unused param")
I& ima = exact(ima_);
mln_piter(I) p(ima.domain());
for_all(p)
......@@ -145,17 +144,7 @@ namespace mln
void fill_with_value(Fast_Image<I>& ima_, const mln_value(I)& value)
{
I& ima = exact(ima_);
if (sizeof(mln_value(I)) == 1)
{
std::memset((void*)(ima.buffer()),
*(const int*)(& value), // violent cast
sizeof(mln_value(I)) * ima.ncells());
}
else
{
// FIXME: Use memcpy on a chunck when image size is large!
fill_with_value(ima, value, true);
}
level::memset_(ima, ima.point_at_offset(0), value, ima.ncells());
}
......
// 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 MLN_LEVEL_MEMCPY_HH
# define MLN_LEVEL_MEMCPY_HH
/*! \file mln/level/memcpy_.hh
*
* \brief Same as std::memcpy but for fast images.
*
* \todo Overload with images and points; Cf. memset_.
*/
# include <mln/core/concept/fast_image.hh>
# include <mln/core/pixel.hh>
namespace mln
{
namespace level
{
/*! Copy \p n pixels starting from pixel \p src to destination
* starting from pixel \p dest.
*
* \param[in,out] dest The destination pixel (to set values).
* \param[in] v The source pixel (to get values).
* \param[in] n The number of pixels to copy.
*
* \pre FIXME: !
*/
template <typename Pd, typename Ps>
void memcpy_(Generalized_Pixel<Pd>& dest, const Generalized_Pixel<Ps>& src,
std::size_t n);
# ifndef MLN_INCLUDE_ONLY
template <typename Pd, typename Ps>
void memcpy_(Generalized_Pixel<Pd>& dest_, const Generalized_Pixel<Ps>& src_,
std::size_t n)
{
typedef mln_image(Pd) Id;
// FIXME: metal::is_not_const<Id>::check();
typedef mln_image(Ps) Is;
Pd& dest = internal::force_exact<Pd>(dest_);
Ps& src = internal::force_exact<Ps>(src_);
mln_precondition(sizeof(mln_value(Id)) == sizeof(mln_value(Is)));
mln_precondition(dest.ima().has_data());
mln_precondition(src.ima().has_data());
// FIXME: Add precondition about n.
if (n == 0)
{
return; // no-op
}
if (n == 1)
{
dest.val() = src.val(); // one assignment
return;
}
if (sizeof(mln_value(Id)) == 1)
{
std::memcpy(( void*)(& dest.val()), // violent casts
(const void*)(& src.val()),
n);
}
else
{
mln_value(Id)* p_d = & dest.val();
const mln_value(Is)* p_s = & src.val();
for (std::size_t i = 0; i < n; ++i)
*p_d++ = *p_s++;
}
}
# endif // ! MLN_INCLUDE_ONLY
} // end of namespace mln::level
} // end of namespace mln
#endif // ! MLN_LEVEL_MEMCPY_HH
// 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 MLN_LEVEL_MEMSET_HH
# define MLN_LEVEL_MEMSET_HH
/*! \file mln/level/memset_.hh
*
* \brief Same as std::memset but for fast images.
*/
# include <mln/core/concept/fast_image.hh>
# include <mln/core/pixel.hh>
namespace mln
{
namespace level
{
/*! Set \p n pixels at value \p v starting from pixel \p p.
*
* \param[in,out] pix The first pixel to set.
* \param[in] v The value to set pixels with.
* \param[in] n The number of pixels to set.
*
* \pre FIXME: !
*/
template <typename P>
void memset_(Generalized_Pixel<P>& pix,
const mln_value(P)& v, std::size_t n);
/*! Set \p n points of image \p ima at value \p v starting from
* point \p p.
*
* \param[in,out] input The image.
* \param[in] p The first point to set.
* \param[in] v The value to set to points.
* \param[in] n The number of points to set.
*
* \pre \p input has to be initialized. FIXME: More.
*/
template <typename I>
void memset_(Fast_Image<I>& input, const mln_point(I)& p,
const mln_value(I)& v, std::size_t n);
# ifndef MLN_INCLUDE_ONLY
template <typename P>
void memset_(Generalized_Pixel<P>& pix_,
const mln_value(P)& v, std::size_t n)
{
typedef mln_image(P) I;
// FIXME: metal::is_not_const<I>::check();
P& pix = internal::force_exact<P>(pix_);
mln_precondition(pix.ima().has_data());
mln_precondition(& pix.val() >= & pix.ima()[0]);
mln_precondition(& pix.val() < & pix.ima()[0] + pix.ima().ncells());
mln_precondition(& pix.val() + n <= & pix.ima()[0] + pix.ima().ncells());
if (n == 0)
{
return; // no-op
}
if (n == 1)
{
pix.val() = v; // one assignment
return;
}
if (sizeof(mln_value(I)) == 1)
{
std::memset((void*)(& pix.val()),
*(const int*)(&v), // violent cast
n);
}
else
{
mln_value(I)* ptr = & pix.val();
for (std::size_t i = 0; i < n; ++i)
*ptr++ = v;
}
}
template <typename I>
void memset_(Fast_Image<I>& input_, const mln_point(I)& p,
const mln_value(I)& v, std::size_t n)
{
I& input = exact(input_);
mln_precondition(input.has_data());
mln_precondition(input.owns_(p));
mln_precondition(input.offset_at(p) + n <= input.ncells());
pixel<I> pix(input, p);
memset_(pix, v, n);
}
# endif // ! MLN_INCLUDE_ONLY
} // end of namespace mln::level
} // end of namespace mln
#endif // ! MLN_LEVEL_MEMSET_HH
......@@ -101,7 +101,7 @@ namespace mln
template <unsigned n>
struct props< int_s<n> >
{
static const std::size_t card_ = metal::pow<2, n>::value;
static const std::size_t card_ = metal::pow<2, n>::value - 1;
static const int_s<n> max() { return metal::pow<2, n-1>::value - 1; }
static const int_s<n> min() { return - max(); }
static const unsigned nbits = n;
......@@ -132,8 +132,10 @@ namespace mln
template <unsigned n>
int_s<n>::int_s(int i)
{
mln_precondition(i >= mln_min(enc));
mln_precondition(i <= mln_max(enc));
static const int max = metal::pow<2, n-1>::value - 1;
static const int min = - max;
mln_precondition(i >= min);
mln_precondition(i <= max);
this->v_ = enc(i);
}
......@@ -141,8 +143,10 @@ namespace mln
int_s<n>&
int_s<n>::operator=(int i)
{
mln_precondition(i >= mln_min(enc));
mln_precondition(i <= mln_max(enc));
static const int max = metal::pow<2, n-1>::value - 1;
static const int min = - max;
mln_precondition(i >= min);
mln_precondition(i <= max);
this->v_ = i;
return *this;
}
......
......@@ -34,8 +34,10 @@
#include <mln/core/image2d_b.hh>
#include <mln/value/int_u8.hh>
#include <mln/value/int_s.hh>
#include <mln/debug/iota.hh>
#include <mln/debug/println.hh>
#include <mln/accu/histo.hh>
#include <mln/histo/compute.hh>
......@@ -62,8 +64,28 @@ int main()
{
image2d_b<int_u8> ima(3, 3);
debug::iota(ima);
ima.at(0,0) = 2;
debug::println(ima);
histo::data< value::set<int_u8> > h = histo::compute(ima);
std::cout << h << std::endl;
int_u8 i = 2;
std::cout << h(i) << std::endl;
}
// {
// typedef value::int_s<5> int_s5;
// image2d_b<int_s5> ima(3, 3);
// debug::iota(ima);
// ima.at(0,0) = 2;
// debug::println(ima);
// histo::data< value::set<int_s5> > h = histo::compute(ima);
// std::cout << h(2) << std::endl;
// for (unsigned i = 0; i < h.vset().nvalues(); ++i)
// std::cout << h[i] << std::endl;
// }
}
// 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 tests/level_memcpy_.cc
*
* \brief Tests on mln::level::memcpy_.
*
* \todo Make this test not dummy!
*/
#include <mln/core/image2d_b.hh>
#include <mln/core/inplace.hh>
#include <mln/debug/iota.hh>
#include <mln/level/memcpy_.hh>
int main()
{
using namespace mln;
typedef image2d_b<int> I;
I ima(3, 3);
debug::iota(ima);
point2d
src = make::point2d(0, 2),
dest = make::point2d(1, 2);
level::memcpy_(inplace(make::pixel(ima, dest)),
make::pixel(ima, src),
2 + 2 * ima.border());
mln_assertion(ima(dest) == ima(src));
}
// 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 tests/level_memset_.cc
*
* \brief Tests on mln::level::memset_.
*/
#include <mln/core/image2d_b.hh>
#include <mln/geom/ncols.hh>
#include <mln/level/fill.hh>
#include <mln/level/memset_.hh>
int main()
{
using namespace mln;
image2d_b<int> ima(3, 3);
level::fill(ima, 0);
int X = 9;
level::memset_(ima, make::point2d(0,0),
X,
geom::ncols(ima) + 2 * ima.border() + 1);
// ^
// |
mln_assertion(ima.at(1,0) == X); // <----------------+
mln_assertion(ima.at(1,1) != X);
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this m