any_image.hpp 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. //
  2. // Copyright 2005-2007 Adobe Systems Incorporated
  3. // Copyright 2020 Samuel Debionne
  4. //
  5. // Distributed under the Boost Software License, Version 1.0
  6. // See accompanying file LICENSE_1_0.txt or copy at
  7. // http://www.boost.org/LICENSE_1_0.txt
  8. //
  9. #ifndef BOOST_GIL_EXTENSION_DYNAMIC_IMAGE_ANY_IMAGE_HPP
  10. #define BOOST_GIL_EXTENSION_DYNAMIC_IMAGE_ANY_IMAGE_HPP
  11. #include <boost/gil/extension/dynamic_image/any_image_view.hpp>
  12. #include <boost/gil/image.hpp>
  13. #include <boost/gil/detail/mp11.hpp>
  14. #include <boost/config.hpp>
  15. #include <boost/variant2/variant.hpp>
  16. #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
  17. #pragma warning(push)
  18. #pragma warning(disable:4512) //assignment operator could not be generated
  19. #endif
  20. namespace boost { namespace gil {
  21. namespace detail {
  22. template <typename T>
  23. using get_view_t = typename T::view_t;
  24. template <typename Images>
  25. using images_get_views_t = mp11::mp_transform<get_view_t, Images>;
  26. template <typename T>
  27. using get_const_view_t = typename T::const_view_t;
  28. template <typename Images>
  29. using images_get_const_views_t = mp11::mp_transform<get_const_view_t, Images>;
  30. struct recreate_image_fnobj
  31. {
  32. using result_type = void;
  33. point<std::ptrdiff_t> const& _dimensions;
  34. unsigned _alignment;
  35. recreate_image_fnobj(point<std::ptrdiff_t> const& dims, unsigned alignment)
  36. : _dimensions(dims), _alignment(alignment)
  37. {}
  38. template <typename Image>
  39. result_type operator()(Image& img) const { img.recreate(_dimensions,_alignment); }
  40. };
  41. template <typename AnyView> // Models AnyViewConcept
  42. struct any_image_get_view
  43. {
  44. using result_type = AnyView;
  45. template <typename Image>
  46. result_type operator()(Image& img) const
  47. {
  48. return result_type(view(img));
  49. }
  50. };
  51. template <typename AnyConstView> // Models AnyConstViewConcept
  52. struct any_image_get_const_view
  53. {
  54. using result_type = AnyConstView;
  55. template <typename Image>
  56. result_type operator()(Image const& img) const { return result_type{const_view(img)}; }
  57. };
  58. } // namespce detail
  59. ////////////////////////////////////////////////////////////////////////////////////////
  60. /// \ingroup ImageModel
  61. /// \brief Represents a run-time specified image. Note it does NOT model ImageConcept
  62. ///
  63. /// Represents an image whose type (color space, layout, planar/interleaved organization, etc) can be specified at run time.
  64. /// It is the runtime equivalent of \p image.
  65. /// Some of the requirements of ImageConcept, such as the \p value_type alias cannot be fulfilled, since the language does not allow runtime type specification.
  66. /// Other requirements, such as access to the pixels, would be inefficient to provide. Thus \p any_image does not fully model ImageConcept.
  67. /// In particular, its \p view and \p const_view methods return \p any_image_view, which does not fully model ImageViewConcept. See \p any_image_view for more.
  68. ////////////////////////////////////////////////////////////////////////////////////////
  69. template <typename ...Images>
  70. class any_image : public variant2::variant<Images...>
  71. {
  72. using parent_t = variant2::variant<Images...>;
  73. public:
  74. using view_t = mp11::mp_rename<detail::images_get_views_t<any_image>, any_image_view>;
  75. using const_view_t = mp11::mp_rename<detail::images_get_const_views_t<any_image>, any_image_view>;
  76. using x_coord_t = std::ptrdiff_t;
  77. using y_coord_t = std::ptrdiff_t;
  78. using point_t = point<std::ptrdiff_t>;
  79. using parent_t::parent_t;
  80. any_image& operator=(any_image const& img)
  81. {
  82. parent_t::operator=((parent_t const&)img);
  83. return *this;
  84. }
  85. template <typename Image>
  86. any_image& operator=(Image const& img)
  87. {
  88. parent_t::operator=(img);
  89. return *this;
  90. }
  91. template <typename ...OtherImages>
  92. any_image& operator=(any_image<OtherImages...> const& img)
  93. {
  94. parent_t::operator=((typename variant2::variant<OtherImages...> const&)img);
  95. return *this;
  96. }
  97. void recreate(point_t const& dims, unsigned alignment=1)
  98. {
  99. variant2::visit(detail::recreate_image_fnobj(dims, alignment), *this);
  100. }
  101. void recreate(x_coord_t width, y_coord_t height, unsigned alignment=1)
  102. {
  103. recreate({ width, height }, alignment);
  104. }
  105. std::size_t num_channels() const
  106. {
  107. return variant2::visit(detail::any_type_get_num_channels(), *this);
  108. }
  109. point_t dimensions() const
  110. {
  111. return variant2::visit(detail::any_type_get_dimensions(), *this);
  112. }
  113. x_coord_t width() const { return dimensions().x; }
  114. y_coord_t height() const { return dimensions().y; }
  115. };
  116. ///@{
  117. /// \name view, const_view
  118. /// \brief Get an image view from a run-time instantiated image
  119. /// \ingroup ImageModel
  120. /// \brief Returns the non-constant-pixel view of any image. The returned view is any view.
  121. /// \tparam Images Models ImageVectorConcept
  122. template <typename ...Images>
  123. BOOST_FORCEINLINE
  124. auto view(any_image<Images...>& img) -> typename any_image<Images...>::view_t
  125. {
  126. using view_t = typename any_image<Images...>::view_t;
  127. return variant2::visit(detail::any_image_get_view<view_t>(), img);
  128. }
  129. /// \brief Returns the constant-pixel view of any image. The returned view is any view.
  130. /// \tparam Types Models ImageVectorConcept
  131. template <typename ...Images>
  132. BOOST_FORCEINLINE
  133. auto const_view(any_image<Images...> const& img) -> typename any_image<Images...>::const_view_t
  134. {
  135. using view_t = typename any_image<Images...>::const_view_t;
  136. return variant2::visit(detail::any_image_get_const_view<view_t>(), img);
  137. }
  138. ///@}
  139. }} // namespace boost::gil
  140. #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
  141. #pragma warning(pop)
  142. #endif
  143. #endif