Skip to content

Commit

Permalink
deprecated apply_operation in favour of variant2::visit for any_image
Browse files Browse the repository at this point in the history
  • Loading branch information
marco-langer committed May 3, 2022
1 parent 36a45e3 commit 89a0dad
Show file tree
Hide file tree
Showing 11 changed files with 397 additions and 39 deletions.
48 changes: 26 additions & 22 deletions include/boost/gil/extension/dynamic_image/algorithm.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
//
// Copyright 2005-2007 Adobe Systems Incorporated
// Copyright 2022 Marco Langer <langer.m86 at gmail dot com>
//
// Distributed under the Boost Software License, Version 1.0
// See accompanying file LICENSE_1_0.txt or copy at
Expand All @@ -12,7 +13,10 @@

#include <boost/gil/algorithm.hpp>

#include <boost/variant2/variant.hpp>

#include <functional>
#include <utility>

////////////////////////////////////////////////////////////////////////////////////////
/// \file
Expand Down Expand Up @@ -43,31 +47,31 @@ struct equal_pixels_fn : binary_operation_obj<equal_pixels_fn, bool>
/// \tparam Types Model Boost.MP11-compatible list of models of ImageViewConcept
/// \tparam View Model MutableImageViewConcept
template <typename ...Types, typename View>
bool equal_pixels(any_image_view<Types...> const& src, View const& dst)
auto equal_pixels(any_image_view<Types...> const& src, View const& dst) -> bool
{
return apply_operation(
src,
std::bind(detail::equal_pixels_fn(), std::placeholders::_1, dst));
return variant2::visit(
std::bind(detail::equal_pixels_fn(), std::placeholders::_1, dst),
src);
}

/// \ingroup ImageViewSTLAlgorithmsEqualPixels
/// \tparam View Model ImageViewConcept
/// \tparam Types Model Boost.MP11-compatible list of models of MutableImageViewConcept
template <typename View, typename ...Types>
bool equal_pixels(View const& src, any_image_view<Types...> const& dst)
auto equal_pixels(View const& src, any_image_view<Types...> const& dst) -> bool
{
return apply_operation(
dst,
std::bind(detail::equal_pixels_fn(), src, std::placeholders::_1));
return variant2::visit(
std::bind(detail::equal_pixels_fn(), src, std::placeholders::_1),
dst);
}

/// \ingroup ImageViewSTLAlgorithmsEqualPixels
/// \tparam Types1 Model Boost.MP11-compatible list of models of ImageViewConcept
/// \tparam Types2 Model Boost.MP11-compatible list of models of MutableImageViewConcept
template <typename ...Types1, typename ...Types2>
bool equal_pixels(any_image_view<Types1...> const& src, any_image_view<Types2...> const& dst)
auto equal_pixels(any_image_view<Types1...> const& src, any_image_view<Types2...> const& dst) -> bool
{
return apply_operation(src, dst, detail::equal_pixels_fn());
return variant2::visit(detail::equal_pixels_fn(), src, dst);
}

namespace detail {
Expand All @@ -90,7 +94,7 @@ struct copy_pixels_fn : public binary_operation_obj<copy_pixels_fn>
template <typename ...Types, typename View>
void copy_pixels(any_image_view<Types...> const& src, View const& dst)
{
apply_operation(src, std::bind(detail::copy_pixels_fn(), std::placeholders::_1, dst));
variant2::visit(std::bind(detail::copy_pixels_fn(), std::placeholders::_1, dst), src);
}

/// \ingroup ImageViewSTLAlgorithmsCopyPixels
Expand All @@ -99,7 +103,7 @@ void copy_pixels(any_image_view<Types...> const& src, View const& dst)
template <typename ...Types, typename View>
void copy_pixels(View const& src, any_image_view<Types...> const& dst)
{
apply_operation(dst, std::bind(detail::copy_pixels_fn(), src, std::placeholders::_1));
variant2::visit(std::bind(detail::copy_pixels_fn(), src, std::placeholders::_1), dst);
}

/// \ingroup ImageViewSTLAlgorithmsCopyPixels
Expand All @@ -108,7 +112,7 @@ void copy_pixels(View const& src, any_image_view<Types...> const& dst)
template <typename ...Types1, typename ...Types2>
void copy_pixels(any_image_view<Types1...> const& src, any_image_view<Types2...> const& dst)
{
apply_operation(src, dst, detail::copy_pixels_fn());
variant2::visit(detail::copy_pixels_fn(), src, dst);
}

//forward declaration for default_color_converter (see full definition in color_convert.hpp)
Expand All @@ -122,7 +126,7 @@ template <typename ...Types, typename View, typename CC>
void copy_and_convert_pixels(any_image_view<Types...> const& src, View const& dst, CC cc)
{
using cc_fn = detail::copy_and_convert_pixels_fn<CC>;
apply_operation(src, std::bind(cc_fn{cc}, std::placeholders::_1, dst));
variant2::visit(std::bind(cc_fn{cc}, std::placeholders::_1, dst), src);
}

/// \ingroup ImageViewSTLAlgorithmsCopyAndConvertPixels
Expand All @@ -132,7 +136,7 @@ template <typename ...Types, typename View>
void copy_and_convert_pixels(any_image_view<Types...> const& src, View const& dst)
{
using cc_fn = detail::copy_and_convert_pixels_fn<default_color_converter>;
apply_operation(src, std::bind(cc_fn{}, std::placeholders::_1, dst));
variant2::visit(std::bind(cc_fn{}, std::placeholders::_1, dst), src);
}

/// \ingroup ImageViewSTLAlgorithmsCopyAndConvertPixels
Expand All @@ -143,7 +147,7 @@ template <typename View, typename ...Types, typename CC>
void copy_and_convert_pixels(View const& src, any_image_view<Types...> const& dst, CC cc)
{
using cc_fn = detail::copy_and_convert_pixels_fn<CC>;
apply_operation(dst, std::bind(cc_fn{cc}, src, std::placeholders::_1));
variant2::visit(std::bind(cc_fn{cc}, src, std::placeholders::_1), dst);
}

/// \ingroup ImageViewSTLAlgorithmsCopyAndConvertPixels
Expand All @@ -153,7 +157,7 @@ template <typename View, typename ...Types>
void copy_and_convert_pixels(View const& src, any_image_view<Types...> const& dst)
{
using cc_fn = detail::copy_and_convert_pixels_fn<default_color_converter>;
apply_operation(dst, std::bind(cc_fn{}, src, std::placeholders::_1));
variant2::visit(std::bind(cc_fn{}, src, std::placeholders::_1), dst);
}

/// \ingroup ImageViewSTLAlgorithmsCopyAndConvertPixels
Expand All @@ -165,7 +169,7 @@ void copy_and_convert_pixels(
any_image_view<Types1...> const& src,
any_image_view<Types2...> const& dst, CC cc)
{
apply_operation(src, dst, detail::copy_and_convert_pixels_fn<CC>(cc));
variant2::visit(detail::copy_and_convert_pixels_fn<CC>(cc), src, dst);
}

/// \ingroup ImageViewSTLAlgorithmsCopyAndConvertPixels
Expand All @@ -176,8 +180,8 @@ void copy_and_convert_pixels(
any_image_view<Types1...> const& src,
any_image_view<Types2...> const& dst)
{
apply_operation(src, dst,
detail::copy_and_convert_pixels_fn<default_color_converter>());
variant2::visit(
detail::copy_and_convert_pixels_fn<default_color_converter>(), src, dst);
}

namespace detail {
Expand Down Expand Up @@ -227,7 +231,7 @@ struct fill_pixels_fn
template <typename ...Types, typename Value>
void fill_pixels(any_image_view<Types...> const& view, Value const& val)
{
apply_operation(view, detail::fill_pixels_fn<Value>(val));
variant2::visit(detail::fill_pixels_fn<Value>(val), view);
}

namespace detail {
Expand All @@ -236,7 +240,7 @@ template <typename F>
struct for_each_pixel_fn
{
for_each_pixel_fn(F&& fun) : fun_(std::move(fun)) {}

template <typename View>
auto operator()(View const& view) -> F
{
Expand Down
11 changes: 5 additions & 6 deletions include/boost/gil/extension/dynamic_image/any_image.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
#define BOOST_GIL_EXTENSION_DYNAMIC_IMAGE_ANY_IMAGE_HPP

#include <boost/gil/extension/dynamic_image/any_image_view.hpp>
#include <boost/gil/extension/dynamic_image/apply_operation.hpp>

#include <boost/gil/image.hpp>
#include <boost/gil/detail/mp11.hpp>
Expand Down Expand Up @@ -121,7 +120,7 @@ class any_image : public variant2::variant<Images...>

void recreate(const point_t& dims, unsigned alignment=1)
{
apply_operation(*this, detail::recreate_image_fnobj(dims, alignment));
variant2::visit(detail::recreate_image_fnobj(dims, alignment), *this);
}

void recreate(x_coord_t width, y_coord_t height, unsigned alignment=1)
Expand All @@ -131,12 +130,12 @@ class any_image : public variant2::variant<Images...>

std::size_t num_channels() const
{
return apply_operation(*this, detail::any_type_get_num_channels());
return variant2::visit(detail::any_type_get_num_channels(), *this);
}

point_t dimensions() const
{
return apply_operation(*this, detail::any_type_get_dimensions());
return variant2::visit(detail::any_type_get_dimensions(), *this);
}

x_coord_t width() const { return dimensions().x; }
Expand All @@ -156,7 +155,7 @@ BOOST_FORCEINLINE
auto view(any_image<Images...>& img) -> typename any_image<Images...>::view_t
{
using view_t = typename any_image<Images...>::view_t;
return apply_operation(img, detail::any_image_get_view<view_t>());
return variant2::visit(detail::any_image_get_view<view_t>(), img);
}

/// \brief Returns the constant-pixel view of any image. The returned view is any view.
Expand All @@ -166,7 +165,7 @@ BOOST_FORCEINLINE
auto const_view(any_image<Images...> const& img) -> typename any_image<Images...>::const_view_t
{
using view_t = typename any_image<Images...>::const_view_t;
return apply_operation(img, detail::any_image_get_const_view<view_t>());
return variant2::visit(detail::any_image_get_const_view<view_t>(), img);
}
///@}

Expand Down
8 changes: 4 additions & 4 deletions include/boost/gil/extension/dynamic_image/any_image_view.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ struct any_type_get_size
/// Other requirements, such as access to the pixels, would be inefficient to provide. Thus \p any_image_view does not fully model ImageViewConcept.
/// However, many algorithms provide overloads taking runtime specified views and thus in many cases \p any_image_view can be used in places taking a view.
///
/// To perform an algorithm on any_image_view, put the algorithm in a function object and invoke it by calling \p apply_operation(runtime_view, algorithm_fn);
/// To perform an algorithm on any_image_view, put the algorithm in a function object and invoke it by calling \p variant2::visit(algorithm_fn, runtime_view);
////////////////////////////////////////////////////////////////////////////////////////

template <typename ...Views>
Expand Down Expand Up @@ -105,9 +105,9 @@ class any_image_view : public variant2::variant<Views...>
return *this;
}

std::size_t num_channels() const { return apply_operation(*this, detail::any_type_get_num_channels()); }
point_t dimensions() const { return apply_operation(*this, detail::any_type_get_dimensions()); }
size_type size() const { return apply_operation(*this, detail::any_type_get_size()); }
std::size_t num_channels() const { return variant2::visit(detail::any_type_get_num_channels(), *this); }
point_t dimensions() const { return variant2::visit(detail::any_type_get_dimensions(), *this); }
size_type size() const { return variant2::visit(detail::any_type_get_size(), *this); }
x_coord_t width() const { return dimensions().x; }
y_coord_t height() const { return dimensions().y; }
};
Expand Down
4 changes: 4 additions & 0 deletions test/extension/dynamic_image/algorithm/Jamfile
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,8 @@

import testing ;

run copy_and_convert_pixels.cpp ;
run copy_pixels.cpp ;
run equal_pixels.cpp ;
run fill_pixels.cpp ;
run for_each_pixel.cpp ;
89 changes: 89 additions & 0 deletions test/extension/dynamic_image/algorithm/copy_and_convert_pixels.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
//
// Copyright (c) 2022 Marco Langer <langer.m86 at gmail dot com>
//
// Distributed under the Boost Software License, Version 1.0
// See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt
//
#include <boost/gil/extension/dynamic_image/any_image.hpp>
#include <boost/gil/extension/dynamic_image/algorithm.hpp>

#include <boost/core/lightweight_test.hpp>

#include <utility>

#include "core/image/test_fixture.hpp"
#include "extension/dynamic_image/test_fixture.hpp"

namespace gil = boost::gil;
namespace fixture = boost::gil::test::fixture;

struct test_copy_and_convert_pixels
{
template <typename ImageLhs, typename ImageRhs>
void operator()(std::pair<ImageLhs, ImageRhs> const&)
{
using image_lhs_t = ImageLhs;
using image_rhs_t = ImageRhs;

gil::default_color_converter cc_default;

{
// dynamic_image -> image
fixture::dynamic_image dyn_image_lhs(fixture::create_image<image_lhs_t>(2, 2, 128));
image_lhs_t image_lhs1(2, 2);
image_lhs_t image_lhs2(2, 2);
image_rhs_t image_rhs1(2, 2);
image_rhs_t image_rhs2(2, 2);

BOOST_TEST_NO_THROW(gil::copy_and_convert_pixels(gil::const_view(dyn_image_lhs), gil::view(image_lhs1)));
BOOST_TEST_NO_THROW(gil::copy_and_convert_pixels(gil::const_view(dyn_image_lhs), gil::view(image_lhs2), cc_default));
BOOST_TEST_NO_THROW(gil::copy_and_convert_pixels(gil::const_view(dyn_image_lhs), gil::view(image_rhs1)));
BOOST_TEST_NO_THROW(gil::copy_and_convert_pixels(gil::const_view(dyn_image_lhs), gil::view(image_rhs2), cc_default));
}
{
// image -> dynamic_image
image_lhs_t image_lhs = fixture::create_image<image_lhs_t>(2, 2, 128);
fixture::dynamic_image dyn_image_lhs1(image_lhs_t(2, 2));
fixture::dynamic_image dyn_image_lhs2(image_lhs_t(2, 2));
fixture::dynamic_image dyn_image_rhs1(image_rhs_t(2, 2));
fixture::dynamic_image dyn_image_rhs2(image_rhs_t(2, 2));

BOOST_TEST_NO_THROW(gil::copy_and_convert_pixels(gil::const_view(image_lhs), gil::view(dyn_image_lhs1)));
BOOST_TEST_NO_THROW(gil::copy_and_convert_pixels(gil::const_view(image_lhs), gil::view(dyn_image_lhs2), cc_default));
BOOST_TEST_NO_THROW(gil::copy_and_convert_pixels(gil::const_view(image_lhs), gil::view(dyn_image_rhs1)));
BOOST_TEST_NO_THROW(gil::copy_and_convert_pixels(gil::const_view(image_lhs), gil::view(dyn_image_rhs2), cc_default));
}
{
// dynamic_image -> dynamic_image
fixture::dynamic_image dyn_image_lhs1(fixture::create_image<image_lhs_t>(2, 2, 128));
fixture::dynamic_image dyn_image_lhs2(image_lhs_t(2, 2));
fixture::dynamic_image dyn_image_lhs3(image_lhs_t(2, 2));
fixture::dynamic_image dyn_image_rhs1(image_rhs_t(2, 2));
fixture::dynamic_image dyn_image_rhs2(image_rhs_t(2, 2));

BOOST_TEST_NO_THROW(gil::copy_and_convert_pixels(gil::const_view(dyn_image_lhs1), gil::view(dyn_image_lhs2)));
BOOST_TEST_NO_THROW(gil::copy_and_convert_pixels(gil::const_view(dyn_image_lhs1), gil::view(dyn_image_lhs3), cc_default));
BOOST_TEST_NO_THROW(gil::copy_and_convert_pixels(gil::const_view(dyn_image_lhs1), gil::view(dyn_image_rhs1)));
BOOST_TEST_NO_THROW(gil::copy_and_convert_pixels(gil::const_view(dyn_image_lhs1), gil::view(dyn_image_rhs2), cc_default));
}
}

static void run()
{
boost::mp11::mp_for_each
<
boost::mp11::mp_pairwise_fold
<
fixture::image_types, std::pair
>
>(test_copy_and_convert_pixels{});
}
};

int main()
{
test_copy_and_convert_pixels::run();

return ::boost::report_errors();
}
Loading

0 comments on commit 89a0dad

Please sign in to comment.