any_image_view.hpp 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  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_VIEW_HPP
  9. #define BOOST_GIL_EXTENSION_DYNAMIC_IMAGE_ANY_IMAGE_VIEW_HPP
  10. #include <boost/gil/dynamic_step.hpp>
  11. #include <boost/gil/image.hpp>
  12. #include <boost/gil/image_view.hpp>
  13. #include <boost/gil/point.hpp>
  14. #include <boost/gil/detail/mp11.hpp>
  15. #include <boost/variant.hpp>
  16. namespace boost { namespace gil {
  17. template <typename View>
  18. struct dynamic_xy_step_transposed_type;
  19. namespace detail {
  20. template <typename View>
  21. struct get_const_t { using type = typename View::const_t; };
  22. template <typename Views>
  23. struct views_get_const_t : mp11::mp_transform<get_const_t, Views> {};
  24. // works for both image_view and image
  25. struct any_type_get_num_channels
  26. {
  27. using result_type = int;
  28. template <typename T>
  29. result_type operator()(const T&) const { return num_channels<T>::value; }
  30. };
  31. // works for both image_view and image
  32. struct any_type_get_dimensions
  33. {
  34. using result_type = point<std::ptrdiff_t>;
  35. template <typename T>
  36. result_type operator()(const T& v) const { return v.dimensions(); }
  37. };
  38. } // namespace detail
  39. ////////////////////////////////////////////////////////////////////////////////////////
  40. /// CLASS any_image_view
  41. ///
  42. /// \ingroup ImageViewModel
  43. /// \brief Represents a run-time specified image view. Models HasDynamicXStepTypeConcept, HasDynamicYStepTypeConcept, Note that this class does NOT model ImageViewConcept
  44. ///
  45. /// Represents a view whose type (color space, layout, planar/interleaved organization, etc) can be specified at run time.
  46. /// It is the runtime equivalent of \p image_view.
  47. /// Some of the requirements of ImageViewConcept, such as the \p value_type alias cannot be fulfilled, since the language does not allow runtime type specification.
  48. /// Other requirements, such as access to the pixels, would be inefficient to provide. Thus \p any_image_view does not fully model ImageViewConcept.
  49. /// 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.
  50. ///
  51. /// 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);
  52. ////////////////////////////////////////////////////////////////////////////////////////
  53. template <typename Views>
  54. class any_image_view : public make_variant_over<Views>::type
  55. {
  56. using parent_t = typename make_variant_over<Views>::type;
  57. public:
  58. using const_t = any_image_view<detail::views_get_const_t<Views>>;
  59. using x_coord_t = std::ptrdiff_t;
  60. using y_coord_t = std::ptrdiff_t;
  61. using point_t = point<std::ptrdiff_t>;
  62. any_image_view() = default;
  63. any_image_view(any_image_view const& view) : parent_t((parent_t const&)view) {}
  64. template <typename View>
  65. explicit any_image_view(View const& view) : parent_t(view) {}
  66. template <typename OtherViews>
  67. any_image_view(any_image_view<OtherViews> const& view)
  68. : parent_t((typename make_variant_over<OtherViews>::type const&)view)
  69. {}
  70. any_image_view& operator=(any_image_view const& view)
  71. {
  72. parent_t::operator=((parent_t const&)view);
  73. return *this;
  74. }
  75. template <typename View>
  76. any_image_view& operator=(View const& view)
  77. {
  78. parent_t::operator=(view);
  79. return *this;
  80. }
  81. template <typename OtherViews>
  82. any_image_view& operator=(any_image_view<OtherViews> const& view)
  83. {
  84. parent_t::operator=((typename make_variant_over<OtherViews>::type const&)view);
  85. return *this;
  86. }
  87. std::size_t num_channels() const { return apply_operation(*this, detail::any_type_get_num_channels()); }
  88. point_t dimensions() const { return apply_operation(*this, detail::any_type_get_dimensions()); }
  89. x_coord_t width() const { return dimensions().x; }
  90. y_coord_t height() const { return dimensions().y; }
  91. };
  92. /////////////////////////////
  93. // HasDynamicXStepTypeConcept
  94. /////////////////////////////
  95. template <typename Views>
  96. struct dynamic_x_step_type<any_image_view<Views>>
  97. {
  98. private:
  99. // FIXME: Remove class name injection with gil:: qualification
  100. // Required as workaround for Boost.MP11 issue that treats unqualified metafunction
  101. // in the class definition of the same name as the specialization (Peter Dimov):
  102. // invalid template argument for template parameter 'F', expected a class template
  103. template <typename T>
  104. using dynamic_step_view = typename gil::dynamic_x_step_type<T>::type;
  105. public:
  106. using type = any_image_view<mp11::mp_transform<dynamic_step_view, Views>>;
  107. };
  108. /////////////////////////////
  109. // HasDynamicYStepTypeConcept
  110. /////////////////////////////
  111. template <typename Views>
  112. struct dynamic_y_step_type<any_image_view<Views>>
  113. {
  114. private:
  115. // FIXME: Remove class name injection with gil:: qualification
  116. // Required as workaround for Boost.MP11 issue that treats unqualified metafunction
  117. // in the class definition of the same name as the specialization (Peter Dimov):
  118. // invalid template argument for template parameter 'F', expected a class template
  119. template <typename T>
  120. using dynamic_step_view = typename gil::dynamic_y_step_type<T>::type;
  121. public:
  122. using type = any_image_view<mp11::mp_transform<dynamic_step_view, Views>>;
  123. };
  124. template <typename Views>
  125. struct dynamic_xy_step_type<any_image_view<Views>>
  126. {
  127. private:
  128. // FIXME: Remove class name injection with gil:: qualification
  129. // Required as workaround for Boost.MP11 issue that treats unqualified metafunction
  130. // in the class definition of the same name as the specialization (Peter Dimov):
  131. // invalid template argument for template parameter 'F', expected a class template
  132. template <typename T>
  133. using dynamic_step_view = typename gil::dynamic_xy_step_type<T>::type;
  134. public:
  135. using type = any_image_view<mp11::mp_transform<dynamic_step_view, Views>>;
  136. };
  137. template <typename Views>
  138. struct dynamic_xy_step_transposed_type<any_image_view<Views>>
  139. {
  140. private:
  141. // FIXME: Remove class name injection with gil:: qualification
  142. // Required as workaround for Boost.MP11 issue that treats unqualified metafunction
  143. // in the class definition of the same name as the specialization (Peter Dimov):
  144. // invalid template argument for template parameter 'F', expected a class template
  145. template <typename T>
  146. using dynamic_step_view = typename gil::dynamic_xy_step_type<T>::type;
  147. public:
  148. using type = any_image_view<mp11::mp_transform<dynamic_step_view, Views>>;
  149. };
  150. }} // namespace boost::gil
  151. #endif