Commit 6d760b1c authored by Edwin Carlinet's avatar Edwin Carlinet
Browse files

Improve documentation.

parent d75e6fa4
...@@ -4,9 +4,20 @@ ...@@ -4,9 +4,20 @@
# include <mln/core/image/image.hpp> # include <mln/core/image/image.hpp>
# include <mln/core/algorithm/copy.hpp> # include <mln/core/algorithm/copy.hpp>
/// \file
/// \brief Header file for clone algorithm.
namespace mln namespace mln
{ {
/// \ingroup Algorithms
/// \brief Make and return a deep copy of an image.
///
/// If the image is not already concrete (e.g. a morpher with no
/// proper memory), the image is concretized.
///
/// \tparam I The input image type
/// \param ima The image to clone.
template <typename I> template <typename I>
mln_concrete(I) mln_concrete(I)
clone(const Image<I>& ima); clone(const Image<I>& ima);
......
...@@ -28,11 +28,10 @@ namespace mln { ...@@ -28,11 +28,10 @@ namespace mln {
/// This is equivalent to the following code. /// This is equivalent to the following code.
/// ///
/// \code /// \code
/// vin = std::begin(input.values()) /// mln_iter(vin, input.values())
/// vend = std::end(input.values()) /// mln_iter(vout, output.values())
/// vout = std::begin(output.values()) /// mln_forall(vin, vout)
/// while (vin != vend) /// *vout = *vin;
/// vout++ = vin++;
/// \endcode /// \endcode
/// ///
/// \param[in] input Input Image /// \param[in] input Input Image
......
...@@ -15,7 +15,7 @@ namespace mln { ...@@ -15,7 +15,7 @@ namespace mln {
/// This is equivalent to the following code: /// This is equivalent to the following code:
/// ///
/// \code /// \code
/// for (auto px: input.pixels()) /// mln_foreach (auto px, input.pixels())
/// output(px.point()) = px.val() /// output(px.point()) = px.val()
/// \endcode /// \endcode
/// ///
...@@ -49,10 +49,9 @@ namespace mln { ...@@ -49,10 +49,9 @@ namespace mln {
{ {
mln_pixter(px, ima); mln_pixter(px, ima);
mln_forall(px) mln_forall(px)
out(px->point()) = px->val(); out(px->point()) = px->val();
} }
} }
template <typename InputImage, typename OutputImage> template <typename InputImage, typename OutputImage>
......
...@@ -3,13 +3,34 @@ ...@@ -3,13 +3,34 @@
# include <mln/core/image/image.hpp> # include <mln/core/image/image.hpp>
namespace mln { /// \file
namespace mln {
/// \ingroup Algorithms
/// \brief Transform the value of an image through a function.
///
/// This is equivalent to the following code.
/// \code
/// mln_iter(vout, out.values())
/// mln_iter(vin, in.values())
/// mln_forall(vin, vout)
/// *vout = f(*vin)
///
/// \endcode
///
/// \tparam InputImage A model of :concept:ref:`forward_image`
/// \tparam OutputImage A model of Writable :concept:ref:`forward_image`
/// \tparam UnaryFunction A mondel of unary function.
/// \param input The input image.
/// \param f The unary function.
/// \param output The output image.
/// \see mln::imtransform
template <typename InputImage, typename OutputImage, class UnaryFunction> template <typename InputImage, typename OutputImage, class UnaryFunction>
OutputImage& OutputImage&
transform(const Image<InputImage>& input, UnaryFunction f, Image<OutputImage>& output); transform(const Image<InputImage>& input, UnaryFunction f, Image<OutputImage>& output);
/// \overload
template <typename InputImage, typename OutputImage, class UnaryFunction> template <typename InputImage, typename OutputImage, class UnaryFunction>
OutputImage&& OutputImage&&
transform(const Image<InputImage>& input, UnaryFunction f, Image<OutputImage>&& output); transform(const Image<InputImage>& input, UnaryFunction f, Image<OutputImage>&& output);
...@@ -18,6 +39,7 @@ namespace mln { ...@@ -18,6 +39,7 @@ namespace mln {
unary_image_expr<UnaryFunction, InputImage> unary_image_expr<UnaryFunction, InputImage>
lazy_transform(InputImage&& input, UnaryFunction f); lazy_transform(InputImage&& input, UnaryFunction f);
/// \overload
template <typename InputImage, class UnaryFunction> template <typename InputImage, class UnaryFunction>
mln_ch_value(InputImage, mln_ch_value(InputImage,
typename std::decay< typename std::decay<
...@@ -38,7 +60,7 @@ namespace mln { ...@@ -38,7 +60,7 @@ namespace mln {
{ {
mln_viter(vin, vout, input, output); mln_viter(vin, vout, input, output);
mln_forall(vin, vout) mln_forall(vin, vout)
*vout = f(*vin); *vout = f(*vin);
} }
} }
......
...@@ -2,12 +2,14 @@ ...@@ -2,12 +2,14 @@
# define MLN_CORE_ALGORITHMS_HPP # define MLN_CORE_ALGORITHMS_HPP
/// \file /// \file
/// \defgroup Algorithms /// \defgroup Algorithms General Image Algorithms.
/// \{ /// \{
# include <mln/core/algorithm/accumulate.hpp>
# include <mln/core/algorithm/copy.hpp> # include <mln/core/algorithm/copy.hpp>
# include <mln/core/algorithm/iota.hpp> # include <mln/core/algorithm/iota.hpp>
# include <mln/core/algorithm/fill.hpp> # include <mln/core/algorithm/fill.hpp>
# include <mln/core/algorithm/paste.hpp> # include <mln/core/algorithm/paste.hpp>
# include <mln/core/algorithm/transform.hpp>
/// \} /// \}
#endif //!MLN_CORE_ALGORITHMS_HPP #endif //!MLN_CORE_ALGORITHMS_HPP
#ifndef MLN_CORE_CH_VALUE_HPP #ifndef MLN_CORE_CH_VALUE_HPP
# define MLN_CORE_CH_VALUE_HPP # define MLN_CORE_CH_VALUE_HPP
/// \file
/// \brief Meta-Function to transform images.
# define mln_ch_value(I, V) typename image_ch_value<I, V>::type # define mln_ch_value(I, V) typename image_ch_value<I, V>::type
# define mln_concrete(I) typename image_concrete<I>::type # define mln_concrete(I) typename image_concrete<I>::type
......
...@@ -29,9 +29,9 @@ namespace mln ...@@ -29,9 +29,9 @@ namespace mln
template <typename T, unsigned dim, typename E> struct ndimage_base; template <typename T, unsigned dim, typename E> struct ndimage_base;
/******************************************/ /******************************************/
/**** Traits ****/ /**** Traits ****/
/******************************************/ /******************************************/
template <typename T, unsigned dim, typename E> template <typename T, unsigned dim, typename E>
...@@ -46,9 +46,9 @@ namespace mln ...@@ -46,9 +46,9 @@ namespace mln
typedef mln::extension::border_extension_tag extension; typedef mln::extension::border_extension_tag extension;
}; };
/******************************************/ /******************************************/
/**** Definition ****/ /**** Definition ****/
/******************************************/ /******************************************/
namespace internal namespace internal
{ {
...@@ -114,8 +114,12 @@ namespace mln ...@@ -114,8 +114,12 @@ namespace mln
template <typename T, unsigned dim, typename E> template <typename T, unsigned dim, typename E>
struct ndimage_base : struct ndimage_base
image_base<E, point<short, dim>, T, ndimage_pixel<T, dim, E>, ndimage_pixel<const T, dim, const E> > #ifndef MLN_DOXYGEN
: image_base<E, point<short, dim>, T,
ndimage_pixel<T, dim, E>,
ndimage_pixel<const T, dim, const E> >
#endif
{ {
private: private:
typedef ndimage_base<T, dim, E> this_type; typedef ndimage_base<T, dim, E> this_type;
...@@ -126,29 +130,65 @@ namespace mln ...@@ -126,29 +130,65 @@ namespace mln
template <unsigned d, typename T1, typename E1, typename T2, typename E2> template <unsigned d, typename T1, typename E1, typename T2, typename E2>
friend friend
bool are_indexes_compatible(const ndimage_base<T1, d, E1>& self, bool are_indexes_compatible(const ndimage_base<T1, d, E1>& self,
const ndimage_base<T2, d, E2>& other); const ndimage_base<T2, d, E2>& other);
public: public:
// As an Image /// \name Image point/value/pixel types
/// \{
typedef box<short, dim> domain_type; /// \copydoc image::site_type
typedef point<short,dim> site_type; typedef point<short,dim> site_type;
/// \copydoc image::point_type
typedef point<short,dim> point_type; typedef point<short,dim> point_type;
typedef ndimage_pixel<const T, dim, const E> const_pixel_type;
/// \copydoc image::pixel_type
typedef ndimage_pixel<T, dim, E> pixel_type; typedef ndimage_pixel<T, dim, E> pixel_type;
typedef T value_type;
enum { ndim = dim};
// As a ContainerImage /// \copydoc image::const_pixel_type
typedef T& reference; typedef ndimage_pixel<const T, dim, const E> const_pixel_type;
typedef const T& const_reference;
typedef T* pointer; /// \copydoc image::value_type
typedef const T* const_pointer; typedef T value_type;
typedef int difference_type;
typedef unsigned index_type; /// \copydoc image::reference
typedef unsigned size_type; typedef T& reference;
/// \copydoc image::const_reference
typedef const T& const_reference;
/// \copydoc image::difference_type
typedef int difference_type;
/// \copydoc image::size_type
typedef unsigned size_type;
typedef unsigned index_type;
typedef T* pointer;
typedef const T* const_pointer;
/// \}
/// \name Image Ranges Types
/// \{
/// \copydoc image::domain_type
typedef box<short, dim> domain_type;
/// \copydoc image::value_range
typedef ndimage_value_range<this_type, T> value_range;
/// \copydoc image::const_value_range
typedef ndimage_value_range<const this_type, const T> const_value_range;
/// \copydoc image::pixel_range
typedef ndimage_pixel_range<this_type, T> pixel_range;
/// \copydoc image::const_pixel_range
typedef ndimage_pixel_range<const this_type, const T> const_pixel_range;
/// \}
enum { ndim = dim};
// As an Image // As an Image
// Constructors // Constructors
...@@ -157,84 +197,133 @@ namespace mln ...@@ -157,84 +197,133 @@ namespace mln
explicit ndimage_base(const domain_type& domain, unsigned border = 3, T v = T()); explicit ndimage_base(const domain_type& domain, unsigned border = 3, T v = T());
// \} // \}
const domain_type& domain() const; /// \name Accession Operators
/// \{
/// \copydoc image::operator()(const site_type& p) const
reference operator() (const site_type& p); reference operator() (const site_type& p);
/// \copydoc image::operator()(const site_type& p) const
const_reference operator() (const site_type& p) const; const_reference operator() (const site_type& p) const;
/// \copydoc image::operator[](size_type i) const
reference operator[] (size_type i); reference operator[] (size_type i);
/// \copydoc image::operator[](size_type i) const
const_reference operator[] (size_type i) const; const_reference operator[] (size_type i) const;
/// \copydoc image::at(const site_type& p) const
reference at (const site_type& p); reference at (const site_type& p);
/// \copydoc image::at(const site_type& p) const
const_reference at (const site_type& p) const; const_reference at (const site_type& p) const;
/// \}
// FIXME move to base /// \name Pixel utilities
pixel_type pixel_at(const site_type& p) /// \{
{
pixel_type pix;
pix.point_ = p;
pix.ima_ = (E*)this;
pix.ptr_ = (char*) & (operator () (p));
return pix;
}
const_pixel_type pixel_at(const site_type& p) const /// \copydoc image::pixel_at(const point_type&) const
{ pixel_type pixel_at(const point_type& p);
const_pixel_type pix((const E*) this);
pix.point_ = p;
pix.ptr_ = (char*) & (operator () (p));
return pix;
}
/// \copydoc image::pixel_at(const point_type&) const
const_pixel_type pixel_at(const point_type& p) const;
pixel_type pixel(const site_type& p) /// \copydoc image::pixel(const point_type&) const
{ pixel_type pixel(const point_type& p);
mln_precondition(domain_.has(p));
return pixel_at(p);
}
const_pixel_type pixel(const site_type& p) const /// \copydoc image::pixel(const point_type&) const
{ const_pixel_type pixel(const point_type& p) const;
mln_precondition(domain_.has(p));
return pixel_at(p);
}
/// \}
// As a Resizable Image
void resize(const domain_type& domain, unsigned border = 3, T v = T());
// As an IterableImage typedef typename value_range::iterator value_iterator;
typedef ndimage_value_range<this_type, T> value_range; typedef typename value_range::reverse_iterator reverse_value_iterator;
typedef ndimage_value_range<const this_type, const T> const_value_range; typedef typename const_value_range::iterator const_value_iterator;
typedef typename value_range::iterator value_iterator;
typedef typename value_range::reverse_iterator reverse_value_iterator;
typedef typename const_value_range::iterator const_value_iterator;
typedef typename const_value_range::reverse_iterator const_reverse_value_iterator; typedef typename const_value_range::reverse_iterator const_reverse_value_iterator;
typedef typename pixel_range::iterator pixel_iterator;
typedef ndimage_pixel_range<this_type, T> pixel_range; typedef typename pixel_range::reverse_iterator reverse_pixel_iterator;
typedef ndimage_pixel_range<const this_type, const T> const_pixel_range; typedef typename const_pixel_range::iterator const_pixel_iterator;
typedef typename pixel_range::iterator pixel_iterator;
typedef typename pixel_range::reverse_iterator reverse_pixel_iterator;
typedef typename const_pixel_range::iterator const_pixel_iterator;
typedef typename const_pixel_range::reverse_iterator const_reverse_pixel_iterator; typedef typename const_pixel_range::reverse_iterator const_reverse_pixel_iterator;
/// \name Image Ranges
/// \{
/// \copydoc image::domain()
const domain_type& domain() const;
/// \copydoc image::values()
value_range values();
value_range values(); /// \copydoc image::values() const
const_value_range values() const; const_value_range values() const;
/// \copydoc image::pixels()
pixel_range pixels(); pixel_range pixels();
/// \copydoc image::pixels() const
const_pixel_range pixels() const; const_pixel_range pixels() const;
/// \}
/// \name Concrete-related Image Methods
/// \{
/// \brief Resize the image to fit \p domain.
///
/// Resize the image w.r.t to \p domain and \p border. The image is
/// initialized with value \p v.
/// \warning The old values are not kept.
/// \param domain The new domain of the image.
/// \param border The new border of the image.
/// \param v The initialization value of the image. If \p is given, values
/// are copy constructed from \p v, otherwise, they are default-initialized.
void resize(const domain_type& domain, unsigned border = 3, T v = T());
/// \brief Re-indexation of the image.
///
/// Reindex the image so that the index of the first point is \p
/// index_first.
/// \param index_first
/// \postcondition `this->index_of_point(domain().pmin) == index_first`
void reindex(size_type index_first)
{
std::ptrdiff_t diff = index_first - m_index_first;
m_ptr_origin -= diff;
m_index_first += diff;
m_index_last += diff;
}
/// \}
/// \name Index-related methods
/// \{
/// \copydoc image::index_of_point(const point_type&) const
size_type index_of_point(const point_type& p) const;
/// \copydoc image::point_at_index(size_type i) const
point_type point_at_index(size_type i) const;
/// \copydoc image::delta_index(const point_type&) const
difference_type delta_index(const point_type& p) const;
/// \}
// As a Raw Image // As a Raw Image
const size_t* strides() const; const std::size_t* strides() const;
int border() const { return border_; } int border() const { return border_; }
// Specialized algorithm // Specialized algorithm
template <typename T_, unsigned dim_, typename E_, typename Domain_> template <typename T_, unsigned dim_, typename E_, typename Domain_>
friend typename std::enable_if<std::is_convertible<Domain_, typename ndimage_base<T_, dim_, E_>::domain_type>::value, E_>::type friend typename std::enable_if<std::is_convertible<Domain_, typename ndimage_base<T_, dim_, E_>::domain_type>::value, E_>::type
make_subimage(ndimage_base<T_, dim_, E_>&, const Domain_& domain); make_subimage(ndimage_base<T_, dim_, E_>&, const Domain_& domain);
// template <typename T_, unsigned dim_, typename E_, typename Domain_> // template <typename T_, unsigned dim_, typename E_, typename Domain_>
// friend E_ make_subimage(ndimage_base<T_, dim_, E_>&, const Domain_& domain); // friend E_ make_subimage(ndimage_base<T_, dim_, E_>&, const Domain_& domain);
// template <typename T_, unsigned dim_, typename E_, typename Domain_> // template <typename T_, unsigned dim_, typename E_, typename Domain_>
...@@ -248,55 +337,15 @@ namespace mln ...@@ -248,55 +337,15 @@ namespace mln
// bool friend_index_compatible(ndimage_base self, const Image<O>& other) const; // bool friend_index_compatible(ndimage_base self, const Image<O>& other) const;
void reindex(std::size_t index_first)
{
std::ptrdiff_t diff = index_first - m_index_first;
m_ptr_origin -= diff;
m_index_first += diff;
m_index_last += diff;
}
size_type index_of_point(const point_type& p) const
{
std::size_t idx = m_index_first;
point_type q = p - domain_.pmin;
for (unsigned i = 0; i < dim; ++i)
idx += q[i] * m_index_strides[i];
return idx;
}
point_type point_at_index(size_type idx) const
{
int k = idx;
int kpmin = m_index_first;
point_type p = point_type ();
for (unsigned i = 0; i < dim; ++i) {
std::div_t off = std::div((int)kpmin, (int)m_index_strides[i]);
std::div_t res = std::div((int)k, (int)m_index_strides[i]);
p[i] = res.quot - off.quot + domain_.pmin[i];
k = res.rem;
kpmin = off.rem;
}
//p -= (domain_.pmin + border_);
mln_postcondition(vbox_.has(p));
return p;
}
difference_type delta_index(const point_type& p) const
{
difference_type idx = 0;
for (unsigned i = 0; i < dim; ++i)
idx += p[i] * m_index_strides[i];
return idx;
}
difference_type delta_offset(const point_type& p) const difference_type delta_offset(const point_type& p) const
{ {
difference_type idx = 0; difference_type idx = 0;
for (unsigned i = 0; i < dim; ++i) for (unsigned i = 0; i < dim; ++i)
idx += p[i] * strides_[i]; idx += p[i] * strides_[i];
return idx; return idx;
} }
...@@ -365,7 +414,7 @@ namespace mln ...@@ -365,7 +414,7 @@ namespace mln
ndimage_data<T, dim>::ndimage_data(size_t* shape_, unsigned border, T v) ndimage_data<T, dim>::ndimage_data(size_t* shape_, unsigned border, T v)
{ {
for (unsigned i = 0; i < dim; ++i) for (unsigned i = 0; i < dim; ++i)
shape[i] = shape_[i] + 2 * border; shape[i] = shape_[i] + 2 * border;
strides[dim-1] = sizeof(T); strides[dim-1] = sizeof(T);
...@@ -374,18 +423,18 @@ namespace mln ...@@ -374,18 +423,18 @@ namespace mln