Boost GIL


any_image.hpp
1 //
2 // Copyright 2005-2007 Adobe Systems Incorporated
3 // Copyright 2020 Samuel Debionne
4 //
5 // Distributed under the Boost Software License, Version 1.0
6 // See accompanying file LICENSE_1_0.txt or copy at
7 // http://www.boost.org/LICENSE_1_0.txt
8 //
9 #ifndef BOOST_GIL_EXTENSION_DYNAMIC_IMAGE_ANY_IMAGE_HPP
10 #define BOOST_GIL_EXTENSION_DYNAMIC_IMAGE_ANY_IMAGE_HPP
11 
12 #include <boost/gil/extension/dynamic_image/any_image_view.hpp>
13 #include <boost/gil/extension/dynamic_image/apply_operation.hpp>
14 
15 #include <boost/gil/image.hpp>
16 #include <boost/gil/detail/mp11.hpp>
17 
18 #include <boost/config.hpp>
19 #include <boost/variant2/variant.hpp>
20 
21 #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
22 #pragma warning(push)
23 #pragma warning(disable:4512) //assignment operator could not be generated
24 #endif
25 
26 namespace boost { namespace gil {
27 
28 namespace detail {
29 
30 template <typename T>
31 using get_view_t = typename T::view_t;
32 
33 template <typename Images>
34 using images_get_views_t = mp11::mp_transform<get_view_t, Images>;
35 
36 template <typename T>
37 using get_const_view_t = typename T::const_view_t;
38 
39 template <typename Images>
40 using images_get_const_views_t = mp11::mp_transform<get_const_view_t, Images>;
41 
42 struct recreate_image_fnobj
43 {
44  using result_type = void;
45  point<std::ptrdiff_t> const& _dimensions;
46  unsigned _alignment;
47 
48  recreate_image_fnobj(point<std::ptrdiff_t> const& dims, unsigned alignment)
49  : _dimensions(dims), _alignment(alignment)
50  {}
51 
52  template <typename Image>
53  result_type operator()(Image& img) const { img.recreate(_dimensions,_alignment); }
54 };
55 
56 template <typename AnyView> // Models AnyViewConcept
57 struct any_image_get_view
58 {
59  using result_type = AnyView;
60  template <typename Image>
61  result_type operator()(Image& img) const
62  {
63  return result_type(view(img));
64  }
65 };
66 
67 template <typename AnyConstView> // Models AnyConstViewConcept
68 struct any_image_get_const_view
69 {
70  using result_type = AnyConstView;
71  template <typename Image>
72  result_type operator()(Image const& img) const { return result_type{const_view(img)}; }
73 };
74 
75 } // namespce detail
76 
87 
88 template <typename ...Images>
89 class any_image : public variant2::variant<Images...>
90 {
91  using parent_t = variant2::variant<Images...>;
92 public:
93  using view_t = mp11::mp_rename<detail::images_get_views_t<any_image>, any_image_view>;
94  using const_view_t = mp11::mp_rename<detail::images_get_const_views_t<any_image>, any_image_view>;
95  using x_coord_t = std::ptrdiff_t;
96  using y_coord_t = std::ptrdiff_t;
98 
99  any_image() = default;
100  any_image(any_image const& img) : parent_t((parent_t const&)img) {}
101 
102  template <typename Image>
103  explicit any_image(Image const& img) : parent_t(img) {}
104 
105  template <typename Image>
106  any_image(Image&& img) : parent_t(std::move(img)) {}
107 
108  template <typename Image>
109  explicit any_image(Image& img, bool do_swap) : parent_t(img, do_swap) {}
110 
111  template <typename ...OtherImages>
113  : parent_t((variant2::variant<OtherImages...> const&)img)
114  {}
115 
116  any_image& operator=(any_image const& img)
117  {
118  parent_t::operator=((parent_t const&)img);
119  return *this;
120  }
121 
122  template <typename Image>
123  any_image& operator=(Image const& img)
124  {
125  parent_t::operator=(img);
126  return *this;
127  }
128 
129  template <typename ...OtherImages>
130  any_image& operator=(any_image<OtherImages...> const& img)
131  {
132  parent_t::operator=((typename variant2::variant<OtherImages...> const&)img);
133  return *this;
134  }
135 
136  void recreate(const point_t& dims, unsigned alignment=1)
137  {
138  apply_operation(*this, detail::recreate_image_fnobj(dims, alignment));
139  }
140 
141  void recreate(x_coord_t width, y_coord_t height, unsigned alignment=1)
142  {
143  recreate({ width, height }, alignment);
144  }
145 
146  std::size_t num_channels() const
147  {
148  return apply_operation(*this, detail::any_type_get_num_channels());
149  }
150 
151  point_t dimensions() const
152  {
153  return apply_operation(*this, detail::any_type_get_dimensions());
154  }
155 
156  x_coord_t width() const { return dimensions().x; }
157  y_coord_t height() const { return dimensions().y; }
158 };
159 
163 
165 
168 template <typename ...Images>
169 BOOST_FORCEINLINE
170 auto view(any_image<Images...>& img) -> typename any_image<Images...>::view_t
171 {
172  using view_t = typename any_image<Images...>::view_t;
173  return apply_operation(img, detail::any_image_get_view<view_t>());
174 }
175 
178 template <typename ...Images>
179 BOOST_FORCEINLINE
180 auto const_view(any_image<Images...> const& img) -> typename any_image<Images...>::const_view_t
181 {
182  using view_t = typename any_image<Images...>::const_view_t;
183  return apply_operation(img, detail::any_image_get_const_view<view_t>());
184 }
186 
187 }} // namespace boost::gil
188 
189 #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
190 #pragma warning(pop)
191 #endif
192 
193 #endif
BOOST_FORCEINLINE auto apply_operation(Variant1 &&arg1, Visitor &&op)
Applies the visitor op to the variants.
Definition: apply_operation.hpp:19
Represents a run-time specified image. Note it does NOT model ImageConcept.
Definition: any_image.hpp:89
BOOST_FORCEINLINE auto view(any_image< Images... > &img) -> typename any_image< Images... >::view_t
Returns the non-constant-pixel view of any image. The returned view is any view.
Definition: any_image.hpp:170
Represents a run-time specified image view. Models HasDynamicXStepTypeConcept, HasDynamicYStepTypeCon...
Definition: any_image_view.hpp:74
Returns the number of channels of a pixel-based GIL construct.
Definition: locator.hpp:38
BOOST_FORCEINLINE auto const_view(any_image< Images... > const &img) -> typename any_image< Images... >::const_view_t
Returns the constant-pixel view of any image. The returned view is any view.
Definition: any_image.hpp:180