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 11 #include <boost/gil/dynamic_step.hpp> 12 #include <boost/gil/image.hpp> 13 #include <boost/gil/image_view.hpp> 14 #include <boost/gil/point.hpp> 15 #include <boost/gil/detail/mp11.hpp> 16 17 #include <boost/variant2/variant.hpp> 18 19 namespace boost { namespace gil { 20 21 template <typename View> 22 struct dynamic_xy_step_transposed_type; 23 24 namespace detail { 25 26 template <typename View> 27 struct get_const_t { using type = typename View::const_t; }; 28 29 template <typename Views> 30 struct views_get_const_t : mp11::mp_transform<get_const_t, Views> {}; 31 32 // works for both image_view and image 33 struct any_type_get_num_channels 34 { 35 using result_type = int; 36 template <typename T> operator ()boost::gil::detail::any_type_get_num_channels37 result_type operator()(const T&) const { return num_channels<T>::value; } 38 }; 39 40 // works for both image_view and image 41 struct any_type_get_dimensions 42 { 43 using result_type = point<std::ptrdiff_t>; 44 template <typename T> operator ()boost::gil::detail::any_type_get_dimensions45 result_type operator()(const T& v) const { return v.dimensions(); } 46 }; 47 48 // works for image_view 49 struct any_type_get_size 50 { 51 using result_type = std::size_t; 52 template <typename T> operator ()boost::gil::detail::any_type_get_size53 result_type operator()(const T& v) const { return v.size(); } 54 }; 55 56 } // namespace detail 57 58 //////////////////////////////////////////////////////////////////////////////////////// 59 /// CLASS any_image_view 60 /// 61 /// \ingroup ImageViewModel 62 /// \brief Represents a run-time specified image view. Models HasDynamicXStepTypeConcept, HasDynamicYStepTypeConcept, Note that this class does NOT model ImageViewConcept 63 /// 64 /// Represents a view whose type (color space, layout, planar/interleaved organization, etc) can be specified at run time. 65 /// It is the runtime equivalent of \p image_view. 66 /// 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. 67 /// Other requirements, such as access to the pixels, would be inefficient to provide. Thus \p any_image_view does not fully model ImageViewConcept. 68 /// 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. 69 /// 70 /// 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); 71 //////////////////////////////////////////////////////////////////////////////////////// 72 73 template <typename ...Views> 74 class any_image_view : public variant2::variant<Views...> 75 { 76 using parent_t = variant2::variant<Views...>; 77 78 public: 79 using const_t = detail::views_get_const_t<any_image_view>; 80 using x_coord_t = std::ptrdiff_t; 81 using y_coord_t = std::ptrdiff_t; 82 using point_t = point<std::ptrdiff_t>; 83 using size_type = std::size_t; 84 85 any_image_view() = default; any_image_view(any_image_view const & view)86 any_image_view(any_image_view const& view) : parent_t((parent_t const&)view) {} 87 88 template <typename View> any_image_view(View const & view)89 explicit any_image_view(View const& view) : parent_t(view) {} 90 91 template <typename ...OtherViews> any_image_view(any_image_view<OtherViews...> const & view)92 any_image_view(any_image_view<OtherViews...> const& view) 93 : parent_t((variant2::variant<OtherViews...> const&)view) 94 {} 95 operator =(any_image_view const & view)96 any_image_view& operator=(any_image_view const& view) 97 { 98 parent_t::operator=((parent_t const&)view); 99 return *this; 100 } 101 102 template <typename View> operator =(View const & view)103 any_image_view& operator=(View const& view) 104 { 105 parent_t::operator=(view); 106 return *this; 107 } 108 109 template <typename ...OtherViews> operator =(any_image_view<OtherViews...> const & view)110 any_image_view& operator=(any_image_view<OtherViews...> const& view) 111 { 112 parent_t::operator=((variant2::variant<OtherViews...> const&)view); 113 return *this; 114 } 115 num_channels() const116 std::size_t num_channels() const { return apply_operation(*this, detail::any_type_get_num_channels()); } dimensions() const117 point_t dimensions() const { return apply_operation(*this, detail::any_type_get_dimensions()); } size() const118 size_type size() const { return apply_operation(*this, detail::any_type_get_size()); } width() const119 x_coord_t width() const { return dimensions().x; } height() const120 y_coord_t height() const { return dimensions().y; } 121 }; 122 123 ///////////////////////////// 124 // HasDynamicXStepTypeConcept 125 ///////////////////////////// 126 127 template <typename ...Views> 128 struct dynamic_x_step_type<any_image_view<Views...>> 129 { 130 private: 131 // FIXME: Remove class name injection with gil:: qualification 132 // Required as workaround for Boost.MP11 issue that treats unqualified metafunction 133 // in the class definition of the same name as the specialization (Peter Dimov): 134 // invalid template argument for template parameter 'F', expected a class template 135 template <typename T> 136 using dynamic_step_view = typename gil::dynamic_x_step_type<T>::type; 137 138 public: 139 using type = mp11::mp_transform<dynamic_step_view, any_image_view<Views...>>; 140 }; 141 142 ///////////////////////////// 143 // HasDynamicYStepTypeConcept 144 ///////////////////////////// 145 146 template <typename ...Views> 147 struct dynamic_y_step_type<any_image_view<Views...>> 148 { 149 private: 150 // FIXME: Remove class name injection with gil:: qualification 151 // Required as workaround for Boost.MP11 issue that treats unqualified metafunction 152 // in the class definition of the same name as the specialization (Peter Dimov): 153 // invalid template argument for template parameter 'F', expected a class template 154 template <typename T> 155 using dynamic_step_view = typename gil::dynamic_y_step_type<T>::type; 156 157 public: 158 using type = mp11::mp_transform<dynamic_step_view, any_image_view<Views...>>; 159 }; 160 161 template <typename ...Views> 162 struct dynamic_xy_step_type<any_image_view<Views...>> 163 { 164 private: 165 // FIXME: Remove class name injection with gil:: qualification 166 // Required as workaround for Boost.MP11 issue that treats unqualified metafunction 167 // in the class definition of the same name as the specialization (Peter Dimov): 168 // invalid template argument for template parameter 'F', expected a class template 169 template <typename T> 170 using dynamic_step_view = typename gil::dynamic_xy_step_type<T>::type; 171 172 public: 173 using type = mp11::mp_transform<dynamic_step_view, any_image_view<Views...>>; 174 }; 175 176 template <typename ...Views> 177 struct dynamic_xy_step_transposed_type<any_image_view<Views...>> 178 { 179 private: 180 // FIXME: Remove class name injection with gil:: qualification 181 // Required as workaround for Boost.MP11 issue that treats unqualified metafunction 182 // in the class definition of the same name as the specialization (Peter Dimov): 183 // invalid template argument for template parameter 'F', expected a class template 184 template <typename T> 185 using dynamic_step_view = typename gil::dynamic_xy_step_type<T>::type; 186 187 public: 188 using type = mp11::mp_transform<dynamic_step_view, any_image_view<Views...>>; 189 }; 190 191 }} // namespace boost::gil 192 193 #endif 194