any_image.hpp 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. //
  2. // Copyright 2005-2007 Adobe Systems Incorporated
  3. //
  4. // Distributed under the Boost Software License, Version 1.0
  5. // See accompanying file LICENSE_1_0.txt or copy at
  6. // http://www.boost.org/LICENSE_1_0.txt
  7. //
  8. #ifndef BOOST_GIL_EXTENSION_DYNAMIC_IMAGE_ANY_IMAGE_HPP
  9. #define BOOST_GIL_EXTENSION_DYNAMIC_IMAGE_ANY_IMAGE_HPP
  10. #include <boost/gil/extension/dynamic_image/any_image_view.hpp>
  11. #include <boost/gil/extension/dynamic_image/apply_operation.hpp>
  12. #include <boost/gil/image.hpp>
  13. #include <boost/gil/detail/mp11.hpp>
  14. #include <boost/config.hpp>
  15. #include <boost/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 make_variant_over<Images>::type
  71. {
  72. using parent_t = typename make_variant_over<Images>::type;
  73. public:
  74. using view_t = any_image_view<detail::images_get_views_t<Images>>;
  75. using const_view_t = any_image_view<detail::images_get_const_views_t<Images>>;
  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. any_image() = default;
  80. any_image(any_image const& img) : parent_t((parent_t const&)img) {}
  81. template <typename Image>
  82. explicit any_image(Image const& img) : parent_t(img) {}
  83. template <typename Image>
  84. explicit any_image(Image& img, bool do_swap) : parent_t(img, do_swap) {}
  85. template <typename OtherImages>
  86. any_image(any_image<OtherImages> const& img)
  87. : parent_t((typename make_variant_over<OtherImages>::type const&)img)
  88. {}
  89. any_image& operator=(any_image const& img)
  90. {
  91. parent_t::operator=((parent_t const&)img);
  92. return *this;
  93. }
  94. template <typename Image>
  95. any_image& operator=(Image const& img)
  96. {
  97. parent_t::operator=(img);
  98. return *this;
  99. }
  100. template <typename OtherImages>
  101. any_image& operator=(any_image<OtherImages> const& img)
  102. {
  103. parent_t::operator=((typename make_variant_over<OtherImages>::type const&)img);
  104. return *this;
  105. }
  106. void recreate(const point_t& dims, unsigned alignment=1)
  107. {
  108. apply_operation(*this, detail::recreate_image_fnobj(dims, alignment));
  109. }
  110. void recreate(x_coord_t width, y_coord_t height, unsigned alignment=1)
  111. {
  112. recreate({ width, height }, alignment);
  113. }
  114. std::size_t num_channels() const
  115. {
  116. return apply_operation(*this, detail::any_type_get_num_channels());
  117. }
  118. point_t dimensions() const
  119. {
  120. return apply_operation(*this, detail::any_type_get_dimensions());
  121. }
  122. x_coord_t width() const { return dimensions().x; }
  123. y_coord_t height() const { return dimensions().y; }
  124. };
  125. ///@{
  126. /// \name view, const_view
  127. /// \brief Get an image view from a run-time instantiated image
  128. /// \ingroup ImageModel
  129. /// \brief Returns the non-constant-pixel view of any image. The returned view is any view.
  130. /// \tparam Types Models ImageVectorConcept
  131. template <typename Types>
  132. BOOST_FORCEINLINE
  133. auto view(any_image<Types>& img) -> typename any_image<Types>::view_t
  134. {
  135. using view_t = typename any_image<Types>::view_t;
  136. return apply_operation(img, detail::any_image_get_view<view_t>());
  137. }
  138. /// \brief Returns the constant-pixel view of any image. The returned view is any view.
  139. /// \tparam Types Models ImageVectorConcept
  140. template <typename Types>
  141. BOOST_FORCEINLINE
  142. auto const_view(any_image<Types> const& img) -> typename any_image<Types>::const_view_t
  143. {
  144. using view_t = typename any_image<Types>::const_view_t;
  145. return apply_operation(img, detail::any_image_get_const_view<view_t>());
  146. }
  147. ///@}
  148. }} // namespace boost::gil
  149. #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
  150. #pragma warning(pop)
  151. #endif
  152. #endif