Commit de4b1cd3 authored by Edwin Carlinet's avatar Edwin Carlinet
Browse files

Work on clip view.

parent 9f305d2b
Pipeline #12869 failed with stages
in 1 minute and 21 seconds
#pragma once
#include <mln/core/concept/new/archetype/domain.hpp>
#include <mln/core/concept/new/archetype/pixel.hpp>
#include <mln/core/concept/new/check.hpp>
#include <mln/core/concept/new/images.hpp>
#include <mln/core/domain/private/domain_traits.hpp>
#include <mln/core/image/private/image_traits.hpp>
#include <mln/core/image/private/pixel_traits.hpp>
#include <range/v3/range_traits.hpp>
#include <type_traits>
......@@ -24,7 +24,7 @@ namespace mln::archetypes
using new_pixel_type = Pixel;
using value_type = pixel_value_t<Pixel>;
using reference = pixel_reference_t<Pixel>;
using point_type = domain_point_t<Domain>;
using point_type = ::ranges::range_value_t<Domain>;
using domain_type = Domain;
using category_type = forward_image_tag;
using concrete_type = ConcreteImage;
......
#pragma once
#include <mln/core/concept/new/cmcstl2.hpp>
#include <mln/core/concept/new/points.hpp>
#include <mln/core/concept/new/values.hpp>
#include <mln/core/domain/private/domain_traits.hpp>
#include <type_traits>
namespace mln::concepts
......@@ -20,9 +16,8 @@ namespace mln::concepts
template <typename Dom>
concept Domain =
stl::ForwardRange<Dom> &&
stl::Same<domain_value_t<Dom>, domain_point_t<Dom>> &&
Point<domain_point_t<Dom>> &&
requires(const Dom cdom, domain_point_t<Dom> p) {
requires(const Dom cdom, stl::range_value_t<Dom> p) {
{ cdom.has(p) } -> bool;
{ cdom.empty() } -> bool;
// { cdom.size() } -> stl::UnsignedIntegral&&;
......
#pragma once
namespace mln
{
template <class D>
using domain_value_t = typename D::value_type;
template <class D>
using domain_reference_t = typename D::reference;
template <class D>
using domain_point_t = typename D::value_type;
} // namespace mln
......@@ -417,6 +417,11 @@ namespace mln
/// \precondition -amin(shape() / 2) <= delta <= border
void inflate_domain(int delta);
/// \brief clip an image to a domain
E clip(const domain_type& domain) const;
private:
static E from_buffer_copy_(void* buffer, const domain_type& domain, const size_t* strides);
......@@ -1011,6 +1016,21 @@ namespace mln
return extension_type(m_ptr, &m_strides[0], m_domain.shape(), m_border);
}
template <typename T, unsigned dim, typename E>
E ndimage_base<T, dim, E>::clip(const domain_type& domain) const
{
E other(exact(*this));
other.m_domain = domain;
other.m_border = this->m_border; // FIXME
other.m_ptr = (char*)&(this->at(domain.pmin));
other.m_last = (char*)&(this->at(domain.pmax - 1));
other.m_ptr_origin = this->m_ptr_origin;
other.m_index_first = this->index_of_point(domain.pmin);
other.m_index_last = this->index_of_point(domain.pmax - 1);
return other;
}
template <unsigned d, typename T1, typename E1, typename T2, typename E2>
inline bool are_indexes_compatible(const ndimage_base<T1, d, E1>& self, const ndimage_base<T2, d, E2>& other)
{
......@@ -1018,6 +1038,7 @@ namespace mln
(self.m_index_strides == other.m_index_strides);
}
/******************************************/
/**** Extension implementation ****/
/******************************************/
......
......@@ -33,33 +33,25 @@ namespace mln
template <typename T_, unsigned dim_, typename E_, typename Domain_>
std::enable_if_t<std::is_convertible<Domain_, typename ndimage_base<T_, dim_, E_>::domain_type>::value, E_>
make_subimage(ndimage_base<T_, dim_, E_>& image, const Domain_& domain)
make_subimage(ndimage_base<T_, dim_, E_>& image, const Domain_& domain)
{
E_ other(exact(image));
other.m_domain = domain;
other.m_border = image.m_border; // FIXME
other.m_ptr = (char*)&image(domain.pmin);
other.m_last = (char*)&image(domain.pmax - 1);
other.m_ptr_origin = image.m_ptr_origin;
other.m_index_first = image.index_of_point(domain.pmin);
other.m_index_last = image.index_of_point(domain.pmax - 1);
return other;
return image.clip(domain);
}
template <typename T, unsigned dim, typename E, typename Domain>
std::enable_if_t<std::is_convertible<Domain, typename ndimage_base<T, dim, E>::domain_type>::value, const E>
make_subimage(const ndimage_base<T, dim, E>& image, const Domain& domain)
make_subimage(const ndimage_base<T, dim, E>& image, const Domain& domain)
{
return make_subimage(const_cast<ndimage_base<T, dim, E>&>(image), domain);
return image.clip(domain);
}
template <typename T, unsigned dim, typename E, typename Domain>
std::enable_if_t<std::is_convertible<Domain, typename ndimage_base<T, dim, E>::domain_type>::value, E>
make_subimage(ndimage_base<T, dim, E>&& image, const Domain& domain)
make_subimage(ndimage_base<T, dim, E>&& image, const Domain& domain)
{
return make_subimage(image, domain);
return image.clip(domain);
}
} // end of namespace mln
......
#pragma once
#include <mln/core/domain/private/domain_traits.hpp>
#include <mln/core/image/image.hpp>
#include <mln/core/image/view/adaptor.hpp>
#include <mln/core/rangev3/view/transform.hpp>
......@@ -25,7 +24,7 @@ namespace mln
using typename clip_view::image_adaptor::value_type;
using domain_type = D;
static_assert(std::is_convertible_v<domain_value_t<D>, point_type>,
static_assert(std::is_convertible_v<::ranges::range_value_t<D>, point_type>,
"Domain value type must be convertible to image point type.");
/// \}
......@@ -36,6 +35,7 @@ namespace mln
using indexable = image_indexable_t<I>;
using view = std::true_type;
using extension_category = mln::extension::none_extension_tag; // FIXME: should be improved
using category_type = forward_image_tag; // FIXME: to preservative
using concrete_type = clip_view<image_concrete_t<I>, D>;
template <class V>
......@@ -147,8 +147,6 @@ namespace mln
template <typename dummy = I>
std::enable_if_t<(indexable::value && accessible::value), image_index_t<dummy>> delta_index(point_type p) const
{
mln_precondition(m_domain.has(p));
mln_precondition(this->base().domain().has(p));
return this->base().delta_index(p);
}
/// \}
......@@ -165,13 +163,23 @@ namespace mln
namespace view
{
// Clip customization point
// if ima.clip(domain) exists and is well-formed, it is used
// otherwise the generic morpher is used
// Try first, if Substition succeeds, it is a best match
template <class I, class D>
clip_view<I, D> clip(I ima, D domain)
auto clip(I&& ima, D&& domain) -> decltype(ima.clip(domain))
{
static_assert(mln::is_a<I, experimental::Image>());
return ima.clip(std::forward<D>(domain));
}
// FIXME: make ima a view first ?
return {std::move(ima), std::move(domain)};
// Used if the previous substition has failed
template <class I, class D>
clip_view<I, D> clip(const experimental::Image<I>& ima, D domain)
{
return {static_cast<const I&>(ima), std::forward<D>(domain)};
}
} // namespace view
......
#include <mln/core/algorithm/fill.hpp>
#include <mln/core/algorithm/all_of.hpp>
#include <mln/core/image/image2d.hpp>
#include <mln/core/image/private/image_operators.hpp>
#include <mln/core/image/view/clip.hpp>
#include <mln/core/concept/new/archetype/image.hpp>
#include <helpers.hpp>
#include <gtest/gtest.h>
......@@ -41,7 +42,7 @@ TEST(View, clip)
ASSERT_EQ(42, clipped(p));
}
ASSERT_TRUE(mln::experimental::all(ima == ref));
ASSERT_TRUE(mln::experimental::all_of(ima == ref));
}
......@@ -71,5 +72,41 @@ TEST(View, clip_twice)
ASSERT_EQ(42, B(p));
}
ASSERT_TRUE(mln::experimental::all(ima == ref));
ASSERT_TRUE(mln::experimental::all_of(ima == ref));
}
TEST(View, clip_other_a_box2d)
{
using namespace mln::experimental::ops;
mln::image2d<int> ima = {{0, 1, 2, 3, 4}, //
{5, 6, 4, 8, 9}, //
{10, 11, 12, 13, 14}};
mln::image2d<int> ref = {{0, 42, 42, 3, 4}, //
{5, 42, 42, 8, 9}, //
{10, 11, 12, 13, 14}};
mln::box2d domain = {{0,1}, {2,3}};
// Clip returns an 'image2d'
mln::image2d<int> clipped = mln::view::clip(ima, domain);
fill(clipped, 42);
for (auto p : clipped.domain())
{
ASSERT_EQ(42, ima(p));
ASSERT_EQ(42, clipped(p));
}
ASSERT_TRUE(mln::experimental::all_of(ima == ref));
}
#ifdef PYLENE_CONCEPT_TS_ENABLED
static_assert(mln::concept::AccessibleImage<mln::clip_view<mln::archetypes::AccessibleImage, mln::archetypes::Domain>>);
static_assert(mln::concept::OutputImage<mln::clip_view<mln::archetypes::OutputAccessibleImage, mln::archetypes::Domain>>);
static_assert(mln::concept::IndexableAndAccessibleImage<mln::clip_view<mln::archetypes::IndexableAndAccessibleImage, mln::archetypes::Domain>>);
#endif // PYLENE_CONCEPT_TS_ENABLED
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment