Imported Upstream version 1.72.0
[platform/upstream/boost.git] / boost / gil / extension / dynamic_image / any_image_view.hpp
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/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>
37     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>
45     result_type operator()(const T& v) const { return v.dimensions(); }
46 };
47
48 } // namespace detail
49
50 ////////////////////////////////////////////////////////////////////////////////////////
51 /// CLASS any_image_view
52 ///
53 /// \ingroup ImageViewModel
54 /// \brief Represents a run-time specified image view. Models HasDynamicXStepTypeConcept, HasDynamicYStepTypeConcept, Note that this class does NOT model ImageViewConcept
55 ///
56 /// Represents a view whose type (color space, layout, planar/interleaved organization, etc) can be specified at run time.
57 /// It is the runtime equivalent of \p image_view.
58 /// 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.
59 /// Other requirements, such as access to the pixels, would be inefficient to provide. Thus \p any_image_view does not fully model ImageViewConcept.
60 /// 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.
61 ///
62 /// 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);
63 ////////////////////////////////////////////////////////////////////////////////////////
64
65 template <typename Views>
66 class any_image_view : public make_variant_over<Views>::type
67 {
68     using parent_t = typename make_variant_over<Views>::type;
69 public:
70     using const_t = any_image_view<detail::views_get_const_t<Views>>;
71     using x_coord_t = std::ptrdiff_t;
72     using y_coord_t = std::ptrdiff_t;
73     using point_t = point<std::ptrdiff_t>;
74
75     any_image_view() = default;
76     any_image_view(any_image_view const& view) : parent_t((parent_t const&)view) {}
77
78     template <typename View>
79     explicit any_image_view(View const& view) : parent_t(view) {}
80
81     template <typename OtherViews>
82     any_image_view(any_image_view<OtherViews> const& view)
83         : parent_t((typename make_variant_over<OtherViews>::type const&)view)
84     {}
85
86     any_image_view& operator=(any_image_view const& view)
87     {
88         parent_t::operator=((parent_t const&)view);
89         return *this;
90     }
91
92     template <typename View>
93     any_image_view& operator=(View const& view)
94     {
95         parent_t::operator=(view);
96         return *this;
97     }
98
99     template <typename OtherViews>
100     any_image_view& operator=(any_image_view<OtherViews> const& view)
101     {
102         parent_t::operator=((typename make_variant_over<OtherViews>::type const&)view);
103         return *this;
104     }
105
106     std::size_t num_channels()  const { return apply_operation(*this, detail::any_type_get_num_channels()); }
107     point_t     dimensions()    const { return apply_operation(*this, detail::any_type_get_dimensions()); }
108     x_coord_t   width()         const { return dimensions().x; }
109     y_coord_t   height()        const { return dimensions().y; }
110 };
111
112 /////////////////////////////
113 //  HasDynamicXStepTypeConcept
114 /////////////////////////////
115
116 template <typename Views>
117 struct dynamic_x_step_type<any_image_view<Views>>
118 {
119 private:
120     // FIXME: Remove class name injection with gil:: qualification
121     // Required as workaround for Boost.MP11 issue that treats unqualified metafunction
122     // in the class definition of the same name as the specialization (Peter Dimov):
123     //    invalid template argument for template parameter 'F', expected a class template
124     template <typename T>
125     using dynamic_step_view = typename gil::dynamic_x_step_type<T>::type;
126
127 public:
128     using type = any_image_view<mp11::mp_transform<dynamic_step_view, Views>>;
129 };
130
131 /////////////////////////////
132 //  HasDynamicYStepTypeConcept
133 /////////////////////////////
134
135 template <typename Views>
136 struct dynamic_y_step_type<any_image_view<Views>>
137 {
138 private:
139     // FIXME: Remove class name injection with gil:: qualification
140     // Required as workaround for Boost.MP11 issue that treats unqualified metafunction
141     // in the class definition of the same name as the specialization (Peter Dimov):
142     //    invalid template argument for template parameter 'F', expected a class template
143     template <typename T>
144     using dynamic_step_view = typename gil::dynamic_y_step_type<T>::type;
145
146 public:
147     using type = any_image_view<mp11::mp_transform<dynamic_step_view, Views>>;
148 };
149
150 template <typename Views>
151 struct dynamic_xy_step_type<any_image_view<Views>>
152 {
153 private:
154     // FIXME: Remove class name injection with gil:: qualification
155     // Required as workaround for Boost.MP11 issue that treats unqualified metafunction
156     // in the class definition of the same name as the specialization (Peter Dimov):
157     //    invalid template argument for template parameter 'F', expected a class template
158     template <typename T>
159     using dynamic_step_view = typename gil::dynamic_xy_step_type<T>::type;
160
161 public:
162     using type = any_image_view<mp11::mp_transform<dynamic_step_view, Views>>;
163 };
164
165 template <typename Views>
166 struct dynamic_xy_step_transposed_type<any_image_view<Views>>
167 {
168 private:
169     // FIXME: Remove class name injection with gil:: qualification
170     // Required as workaround for Boost.MP11 issue that treats unqualified metafunction
171     // in the class definition of the same name as the specialization (Peter Dimov):
172     //    invalid template argument for template parameter 'F', expected a class template
173     template <typename T>
174     using dynamic_step_view = typename gil::dynamic_xy_step_type<T>::type;
175
176 public:
177     using type = any_image_view<mp11::mp_transform<dynamic_step_view, Views>>;
178 };
179
180 }}  // namespace boost::gil
181
182 #endif