Skip to content

Commit

Permalink
fix: Fixed custom color converter in dynamic_factory and added corres…
Browse files Browse the repository at this point in the history
…ponding (#726)
  • Loading branch information
nicolacandussi authored Feb 21, 2023
1 parent d6e67f3 commit 8f4cdcb
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 14 deletions.
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();
}

0 comments on commit 8f4cdcb

Please sign in to comment.