2 // Copyright 2005-2007 Adobe Systems Incorporated
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
8 #ifndef BOOST_GIL_CONCEPTS_IMAGE_VIEW_HPP
9 #define BOOST_GIL_CONCEPTS_IMAGE_VIEW_HPP
11 #include <boost/gil/concepts/basic.hpp>
12 #include <boost/gil/concepts/concept_check.hpp>
13 #include <boost/gil/concepts/fwd.hpp>
14 #include <boost/gil/concepts/pixel.hpp>
15 #include <boost/gil/concepts/pixel_dereference.hpp>
16 #include <boost/gil/concepts/pixel_iterator.hpp>
17 #include <boost/gil/concepts/pixel_locator.hpp>
18 #include <boost/gil/concepts/point.hpp>
19 #include <boost/gil/concepts/detail/utility.hpp>
23 #include <type_traits>
25 #if defined(BOOST_CLANG)
26 #pragma clang diagnostic push
27 #pragma clang diagnostic ignored "-Wunused-local-typedefs"
30 #if defined(BOOST_GCC) && (BOOST_GCC >= 40900)
31 #pragma GCC diagnostic push
32 #pragma GCC diagnostic ignored "-Wunused-local-typedefs"
33 #pragma GCC diagnostic ignored "-Wunused-but-set-variable"
36 namespace boost { namespace gil {
38 /// \defgroup ImageViewNDConcept ImageViewNDLocatorConcept
39 /// \ingroup ImageViewConcept
40 /// \brief N-dimensional range
42 /// \defgroup ImageView2DConcept ImageView2DConcept
43 /// \ingroup ImageViewConcept
44 /// \brief 2-dimensional range
46 /// \defgroup PixelImageViewConcept ImageViewConcept
47 /// \ingroup ImageViewConcept
48 /// \brief 2-dimensional range over pixel data
50 /// \ingroup ImageViewNDConcept
51 /// \brief N-dimensional view over immutable values
54 /// concept RandomAccessNDImageViewConcept<Regular View>
56 /// typename value_type;
57 /// typename reference; // result of dereferencing
58 /// typename difference_type; // result of operator-(iterator,iterator) (1-dimensional!)
59 /// typename const_t; where RandomAccessNDImageViewConcept<View>; // same as View, but over immutable values
60 /// typename point_t; where PointNDConcept<point_t>; // N-dimensional point
61 /// typename locator; where RandomAccessNDLocatorConcept<locator>; // N-dimensional locator.
62 /// typename iterator; where RandomAccessTraversalConcept<iterator>; // 1-dimensional iterator over all values
63 /// typename reverse_iterator; where RandomAccessTraversalConcept<reverse_iterator>;
64 /// typename size_type; // the return value of size()
66 /// // Equivalent to RandomAccessNDLocatorConcept::axis
67 /// template <size_t D> struct axis {
68 /// typename coord_t = point_t::axis<D>::coord_t;
69 /// typename iterator; where RandomAccessTraversalConcept<iterator>; // iterator along D-th axis.
70 /// where SameType<coord_t, iterator::difference_type>;
71 /// where SameType<iterator::value_type,value_type>;
74 /// // Defines the type of a view similar to this type, except it invokes Deref upon dereferencing
75 /// template <PixelDereferenceAdaptorConcept Deref> struct add_deref {
76 /// typename type; where RandomAccessNDImageViewConcept<type>;
77 /// static type make(const View& v, const Deref& deref);
80 /// static const size_t num_dimensions = point_t::num_dimensions;
82 /// // Create from a locator at the top-left corner and dimensions
83 /// View::View(const locator&, const point_type&);
85 /// size_type View::size() const; // total number of elements
86 /// reference operator[](View, const difference_type&) const; // 1-dimensional reference
87 /// iterator View::begin() const;
88 /// iterator View::end() const;
89 /// reverse_iterator View::rbegin() const;
90 /// reverse_iterator View::rend() const;
91 /// iterator View::at(const point_t&);
92 /// point_t View::dimensions() const; // number of elements along each dimension
93 /// bool View::is_1d_traversable() const; // can an iterator over the first dimension visit each value? I.e. are there gaps between values?
95 /// // iterator along a given dimension starting at a given point
96 /// template <size_t D> View::axis<D>::iterator View::axis_iterator(const point_t&) const;
98 /// reference operator()(View,const point_t&) const;
101 template <typename View>
102 struct RandomAccessNDImageViewConcept
106 gil_function_requires<Regular<View>>();
108 using value_type = typename View::value_type;
109 using reference = typename View::reference; // result of dereferencing
110 using pointer = typename View::pointer;
111 using difference_type = typename View::difference_type; // result of operator-(1d_iterator,1d_iterator)
112 using const_t = typename View::const_t; // same as this type, but over const values
113 using point_t = typename View::point_t; // N-dimensional point
114 using locator = typename View::locator; // N-dimensional locator
115 using iterator = typename View::iterator;
116 using const_iterator = typename View::const_iterator;
117 using reverse_iterator = typename View::reverse_iterator;
118 using size_type = typename View::size_type;
119 static const std::size_t N=View::num_dimensions;
121 gil_function_requires<RandomAccessNDLocatorConcept<locator>>();
122 gil_function_requires<boost_concepts::RandomAccessTraversalConcept<iterator>>();
123 gil_function_requires<boost_concepts::RandomAccessTraversalConcept<reverse_iterator>>();
125 using first_it_type = typename View::template axis<0>::iterator;
126 using last_it_type = typename View::template axis<N-1>::iterator;
127 gil_function_requires<boost_concepts::RandomAccessTraversalConcept<first_it_type>>();
128 gil_function_requires<boost_concepts::RandomAccessTraversalConcept<last_it_type>>();
130 // static_assert(typename std::iterator_traits<first_it_type>::difference_type, typename point_t::template axis<0>::coord_t>::value, "");
131 // static_assert(typename std::iterator_traits<last_it_type>::difference_type, typename point_t::template axis<N-1>::coord_t>::value, "");
133 // point_t must be an N-dimensional point, each dimension of which must have the same type as difference_type of the corresponding iterator
134 gil_function_requires<PointNDConcept<point_t>>();
135 static_assert(point_t::num_dimensions == N, "");
136 static_assert(std::is_same
138 typename std::iterator_traits<first_it_type>::difference_type,
139 typename point_t::template axis<0>::coord_t
141 static_assert(std::is_same
143 typename std::iterator_traits<last_it_type>::difference_type,
144 typename point_t::template axis<N-1>::coord_t
150 reverse_iterator rit;
151 difference_type d; detail::initialize_it(d); ignore_unused_variable_warning(d);
153 View(p,lc); // view must be constructible from a locator and a point
155 p = view.dimensions();
157 size_type sz = view.size(); ignore_unused_variable_warning(sz);
158 bool is_contiguous = view.is_1d_traversable();
159 ignore_unused_variable_warning(is_contiguous);
166 reference r1 = view[d]; ignore_unused_variable_warning(r1); // 1D access
167 reference r2 = view(p); ignore_unused_variable_warning(r2); // 2D access
169 // get 1-D iterator of any dimension at a given pixel location
170 first_it_type fi = view.template axis_iterator<0>(p);
171 ignore_unused_variable_warning(fi);
172 last_it_type li = view.template axis_iterator<N-1>(p);
173 ignore_unused_variable_warning(li);
175 using deref_t = PixelDereferenceAdaptorArchetype<typename View::value_type>;
176 using dtype = typename View::template add_deref<deref_t>::type;
181 /// \ingroup ImageView2DConcept
182 /// \brief 2-dimensional view over immutable values
185 /// concept RandomAccess2DImageViewConcept<RandomAccessNDImageViewConcept View> {
186 /// where num_dimensions==2;
188 /// typename x_iterator = axis<0>::iterator;
189 /// typename y_iterator = axis<1>::iterator;
190 /// typename x_coord_t = axis<0>::coord_t;
191 /// typename y_coord_t = axis<1>::coord_t;
192 /// typename xy_locator = locator;
194 /// x_coord_t View::width() const;
195 /// y_coord_t View::height() const;
198 /// x_iterator View::x_at(const point_t&) const;
199 /// x_iterator View::row_begin(y_coord_t) const;
200 /// x_iterator View::row_end (y_coord_t) const;
203 /// y_iterator View::y_at(const point_t&) const;
204 /// y_iterator View::col_begin(x_coord_t) const;
205 /// y_iterator View::col_end (x_coord_t) const;
207 /// // navigating in 2D
208 /// xy_locator View::xy_at(const point_t&) const;
210 /// // (x,y) versions of all methods taking point_t
211 /// View::View(x_coord_t,y_coord_t,const locator&);
212 /// iterator View::at(x_coord_t,y_coord_t) const;
213 /// reference operator()(View,x_coord_t,y_coord_t) const;
214 /// xy_locator View::xy_at(x_coord_t,y_coord_t) const;
215 /// x_iterator View::x_at(x_coord_t,y_coord_t) const;
216 /// y_iterator View::y_at(x_coord_t,y_coord_t) const;
219 template <typename View>
220 struct RandomAccess2DImageViewConcept
224 gil_function_requires<RandomAccessNDImageViewConcept<View>>();
225 static_assert(View::num_dimensions == 2, "");
227 // TODO: This executes the requirements for RandomAccessNDLocatorConcept again. Fix it to improve compile time
228 gil_function_requires<RandomAccess2DLocatorConcept<typename View::locator>>();
230 using dynamic_x_step_t = typename dynamic_x_step_type<View>::type;
231 using dynamic_y_step_t = typename dynamic_y_step_type<View>::type;
232 using transposed_t = typename transposed_type<View>::type;
233 using x_iterator = typename View::x_iterator;
234 using y_iterator = typename View::y_iterator;
235 using x_coord_t = typename View::x_coord_t;
236 using y_coord_t = typename View::y_coord_t;
237 using xy_locator = typename View::xy_locator;
239 x_coord_t xd = 0; ignore_unused_variable_warning(xd);
240 y_coord_t yd = 0; ignore_unused_variable_warning(yd);
243 typename View::point_t d;
245 View(xd, yd, xy_locator()); // constructible with width, height, 2d_locator
247 xy_locator lc = view.xy_at(xd, yd);
250 typename View::reference r = view(xd, yd);
251 ignore_unused_variable_warning(r);
256 xit = view.x_at(xd,yd);
257 xit = view.row_begin(xd);
258 xit = view.row_end(xd);
261 yit = view.y_at(xd,yd);
262 yit = view.col_begin(xd);
263 yit = view.col_end(xd);
268 /// \brief GIL view as Collection.
270 /// \see https://www.boost.org/libs/utility/Collection.html
272 template <typename View>
273 struct CollectionImageViewConcept
277 using value_type = typename View::value_type;
278 using iterator = typename View::iterator;
279 using const_iterator = typename View::const_iterator;
280 using reference = typename View::reference;
281 using const_reference = typename View::const_reference;
282 using pointer = typename View::pointer;
283 using difference_type = typename View::difference_type;
284 using size_type= typename View::size_type;
297 ignore_unused_variable_warning(s);
307 /// \brief GIL view as ForwardCollection.
309 /// \see https://www.boost.org/libs/utility/Collection.html
311 template <typename View>
312 struct ForwardCollectionImageViewConcept
316 gil_function_requires<CollectionImageViewConcept<View>>();
318 using reference = typename View::reference;
319 using const_reference = typename View::const_reference;
321 reference r = view.front();
322 ignore_unused_variable_warning(r);
324 const_reference cr = view.front();
325 ignore_unused_variable_warning(cr);
330 /// \brief GIL view as ReversibleCollection.
332 /// \see https://www.boost.org/libs/utility/Collection.html
334 template <typename View>
335 struct ReversibleCollectionImageViewConcept
339 gil_function_requires<CollectionImageViewConcept<View>>();
341 using reverse_iterator = typename View::reverse_iterator;
342 using reference = typename View::reference;
343 using const_reference = typename View::const_reference;
349 reference r = view.back();
350 ignore_unused_variable_warning(r);
352 const_reference cr = view.back();
353 ignore_unused_variable_warning(cr);
358 /// \ingroup PixelImageViewConcept
359 /// \brief GIL's 2-dimensional view over immutable GIL pixels
361 /// concept ImageViewConcept<RandomAccess2DImageViewConcept View>
363 /// where PixelValueConcept<value_type>;
364 /// where PixelIteratorConcept<x_iterator>;
365 /// where PixelIteratorConcept<y_iterator>;
366 /// where x_coord_t == y_coord_t;
368 /// typename coord_t = x_coord_t;
370 /// std::size_t View::num_channels() const;
373 template <typename View>
374 struct ImageViewConcept
378 gil_function_requires<RandomAccess2DImageViewConcept<View>>();
380 // TODO: This executes the requirements for RandomAccess2DLocatorConcept again. Fix it to improve compile time
381 gil_function_requires<PixelLocatorConcept<typename View::xy_locator>>();
383 static_assert(std::is_same<typename View::x_coord_t, typename View::y_coord_t>::value, "");
385 using coord_t = typename View::coord_t; // 1D difference type (same for all dimensions)
386 std::size_t num_chan = view.num_channels(); ignore_unused_variable_warning(num_chan);
393 /// \tparam View Models RandomAccessNDImageViewConcept
394 template <typename View>
395 struct RandomAccessNDImageViewIsMutableConcept
399 gil_function_requires<detail::RandomAccessNDLocatorIsMutableConcept<typename View::locator>>();
401 gil_function_requires<detail::RandomAccessIteratorIsMutableConcept<typename View::iterator>>();
403 gil_function_requires<detail::RandomAccessIteratorIsMutableConcept
405 typename View::reverse_iterator
408 gil_function_requires<detail::RandomAccessIteratorIsMutableConcept
410 typename View::template axis<0>::iterator
413 gil_function_requires<detail::RandomAccessIteratorIsMutableConcept
415 typename View::template axis<View::num_dimensions - 1>::iterator
418 typename View::difference_type diff;
420 ignore_unused_variable_warning(diff);
422 typename View::point_t pt;
423 typename View::value_type v;
432 /// \tparam View Models RandomAccessNDImageViewConcept
433 template <typename View>
434 struct RandomAccess2DImageViewIsMutableConcept
438 gil_function_requires<detail::RandomAccessNDImageViewIsMutableConcept<View>>();
439 typename View::x_coord_t xd = 0; ignore_unused_variable_warning(xd);
440 typename View::y_coord_t yd = 0; ignore_unused_variable_warning(yd);
441 typename View::value_type v; initialize_it(v);
447 /// \tparam View Models ImageViewConcept
448 template <typename View>
449 struct PixelImageViewIsMutableConcept
453 gil_function_requires<detail::RandomAccess2DImageViewIsMutableConcept<View>>();
457 } // namespace detail
459 /// \ingroup ImageViewNDConcept
460 /// \brief N-dimensional view over mutable values
463 /// concept MutableRandomAccessNDImageViewConcept<RandomAccessNDImageViewConcept View>
465 /// where Mutable<reference>;
468 template <typename View>
469 struct MutableRandomAccessNDImageViewConcept
473 gil_function_requires<RandomAccessNDImageViewConcept<View>>();
474 gil_function_requires<detail::RandomAccessNDImageViewIsMutableConcept<View>>();
478 /// \ingroup ImageView2DConcept
479 /// \brief 2-dimensional view over mutable values
482 /// concept MutableRandomAccess2DImageViewConcept<RandomAccess2DImageViewConcept View>
483 /// : MutableRandomAccessNDImageViewConcept<View> {};
485 template <typename View>
486 struct MutableRandomAccess2DImageViewConcept
490 gil_function_requires<RandomAccess2DImageViewConcept<View>>();
491 gil_function_requires<detail::RandomAccess2DImageViewIsMutableConcept<View>>();
495 /// \ingroup PixelImageViewConcept
496 /// \brief GIL's 2-dimensional view over mutable GIL pixels
499 /// concept MutableImageViewConcept<ImageViewConcept View>
500 /// : MutableRandomAccess2DImageViewConcept<View> {};
502 template <typename View>
503 struct MutableImageViewConcept
507 gil_function_requires<ImageViewConcept<View>>();
508 gil_function_requires<detail::PixelImageViewIsMutableConcept<View>>();
512 /// \brief Returns whether two views are compatible
514 /// Views are compatible if their pixels are compatible.
515 /// Compatible views can be assigned and copy constructed from one another.
517 /// \tparam V1 Models ImageViewConcept
518 /// \tparam V2 Models ImageViewConcept
520 template <typename V1, typename V2>
521 struct views_are_compatible
522 : pixels_are_compatible<typename V1::value_type, typename V2::value_type>
526 /// \ingroup ImageViewConcept
527 /// \brief Views are compatible if they have the same color spaces and compatible channel values.
529 /// Constness and layout are not important for compatibility.
532 /// concept ViewsCompatibleConcept<ImageViewConcept V1, ImageViewConcept V2>
534 /// where PixelsCompatibleConcept<V1::value_type, P2::value_type>;
537 template <typename V1, typename V2>
538 struct ViewsCompatibleConcept
542 static_assert(views_are_compatible<V1, V2>::value, "");
546 }} // namespace boost::gil
548 #if defined(BOOST_CLANG)
549 #pragma clang diagnostic pop
552 #if defined(BOOST_GCC) && (BOOST_GCC >= 40900)
553 #pragma GCC diagnostic pop