• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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