Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed custom color converter in dynamic_factory and added corresponding #726

Merged
merged 2 commits into from
Feb 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 6 additions & 14 deletions include/boost/gil/extension/dynamic_image/image_view_factory.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -314,20 +314,12 @@ auto nth_channel_view(any_image_view<Views...> const& src, int n)

namespace detail {

template <typename View, typename DstP, typename CC>
struct get_ccv_type : color_converted_view_type<View, DstP, CC> {};

template <typename Views, typename DstP, typename CC>
struct views_get_ccv_type
{
private:
// FIXME: Remove class name injection with detail:: qualification
// Required as workaround for MP11 issue that treats unqualified metafunction
// in the class definition of the same name as the specialization (Peter Dimov):
// invalid template argument for template parameter 'F', expected a class template
template <typename T>
using ccvt = detail::get_ccv_type<T, DstP, CC>;

template <typename T>
using ccvt = typename color_converted_view_type<T, DstP, CC>::type;
public:
using type = mp11::mp_transform<ccvt, Views>;
};
Expand All @@ -340,27 +332,27 @@ template <typename ...Views, typename DstP, typename CC>
struct color_converted_view_type<any_image_view<Views...>,DstP,CC>
{
//using type = any_image_view<typename detail::views_get_ccv_type<Views, DstP, CC>::type>;
using type = detail::views_get_ccv_type<any_image_view<Views...>, DstP, CC>;
using type = typename detail::views_get_ccv_type<any_image_view<Views...>, DstP, CC>::type;
};

/// \ingroup ImageViewTransformationsColorConvert
/// \brief overload of generic color_converted_view with user defined color-converter
/// \tparam Views Models Boost.MP11-compatible list of models of ImageViewConcept
template <typename DstP, typename ...Views, typename CC>
inline
auto color_converted_view(any_image_view<Views...> const& src, CC)
auto color_converted_view(any_image_view<Views...> const& src, CC cc)
-> typename color_converted_view_type<any_image_view<Views...>, DstP, CC>::type
{
using cc_view_t = typename color_converted_view_type<any_image_view<Views...>, DstP, CC>::type;
return variant2::visit(detail::color_converted_view_fn<DstP, cc_view_t>(), src);
return variant2::visit(detail::color_converted_view_fn<DstP, cc_view_t, CC>(cc), src);
}

/// \ingroup ImageViewTransformationsColorConvert
/// \brief Returns the type of a runtime-specified view, color-converted to a given pixel type with the default coor converter
template <typename ...Views, typename DstP>
struct color_converted_view_type<any_image_view<Views...>,DstP>
{
using type = detail::views_get_ccv_type<any_image_view<Views...>, DstP, default_color_converter>;
using type = typename detail::views_get_ccv_type<any_image_view<Views...>, DstP, default_color_converter>::type;
};

/// \ingroup ImageViewTransformationsColorConvert
Expand Down
67 changes: 67 additions & 0 deletions test/extension/dynamic_image/image_view_factory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,10 +83,77 @@ struct test_flipped_up_down_view
}
};

template<typename V1, typename V2>
bool equal_pixels_values(V1&& v1,
V2&& v2,
float threshold = 1e-6f)
{
// convert both images to rgba32f and compare with threshold
return boost::variant2::visit([=](auto const& v1, auto const& v2) -> bool {
auto it1 = v1.begin();
auto it2 = v2.begin();
while(it1 != v1.end() && it2 != v2.end()) {
using pixel_t = gil::rgba32f_pixel_t;
static constexpr std::size_t num_channels = gil::num_channels<pixel_t>::value;
pixel_t p1{};
gil::color_convert(*it1++, p1);
pixel_t p2{};
gil::color_convert(*it2++, p2);
for(size_t i = 0; i < num_channels; ++i) {
if(std::abs(p1[i] - p2[i]) > threshold){
return false;
}
}
}
return true;
},
std::forward<V1>(v1),
std::forward<V2>(v2));
}

struct test_color_converted_view
{
static void run()
{
using dynamic_image_t = gil::any_image<gil::gray8_image_t, gil::gray16_image_t>;
using src_image_t = gil::gray8_image_t;
using dst_image_t = gil::gray16_image_t;
using dst_pixel_t = typename dst_image_t::value_type;
static constexpr std::size_t num_channels = 1;
auto color_converter = [](auto const& src, auto& dst) { dst = 2 * src; };
std::array<int, 9> pixel_data =
{
0, 1, 2,
3, 4, 5,
6, 7, 8
};
std::array<int, 9> expected_pixel_data;
std::transform(std::begin(pixel_data),
std::end(pixel_data),
std::begin(expected_pixel_data),
[](auto v) { return 2 * v; });

dynamic_image_t source_image =
fixture::generate_image<src_image_t>(
3, 3, generator<num_channels>{pixel_data.data()});

dynamic_image_t expected_image =
fixture::generate_image<dst_image_t>(
3, 3, generator<num_channels>{expected_pixel_data.data()});

auto result_view = gil::color_converted_view<dst_pixel_t>(gil::const_view(source_image), color_converter);

BOOST_TEST(equal_pixels_values(result_view,
gil::const_view(expected_image),
1e-6f));
}
};

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

test_color_converted_view::run();

return ::boost::report_errors();
}