]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/gil/concepts/image_view.hpp
update source to Ceph Pacific 16.2.2
[ceph.git] / ceph / src / boost / boost / gil / concepts / 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_CONCEPTS_IMAGE_VIEW_HPP
9 #define BOOST_GIL_CONCEPTS_IMAGE_VIEW_HPP
10
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>
20
21 #include <cstddef>
22 #include <iterator>
23 #include <type_traits>
24
25 #if defined(BOOST_CLANG)
26 #pragma clang diagnostic push
27 #pragma clang diagnostic ignored "-Wunknown-pragmas"
28 #pragma clang diagnostic ignored "-Wunused-local-typedefs"
29 #endif
30
31 #if defined(BOOST_GCC) && (BOOST_GCC >= 40900)
32 #pragma GCC diagnostic push
33 #pragma GCC diagnostic ignored "-Wunused-local-typedefs"
34 #pragma GCC diagnostic ignored "-Wunused-but-set-variable"
35 #endif
36
37 namespace boost { namespace gil {
38
39 /// \defgroup ImageViewNDConcept ImageViewNDLocatorConcept
40 /// \ingroup ImageViewConcept
41 /// \brief N-dimensional range
42
43 /// \defgroup ImageView2DConcept ImageView2DLocatorConcept
44 /// \ingroup ImageViewConcept
45 /// \brief 2-dimensional range
46
47 /// \defgroup PixelImageViewConcept ImageViewConcept
48 /// \ingroup ImageViewConcept
49 /// \brief 2-dimensional range over pixel data
50
51 /// \ingroup ImageViewNDConcept
52 /// \brief N-dimensional view over immutable values
53 ///
54 /// \code
55 /// concept RandomAccessNDImageViewConcept<Regular View>
56 /// {
57 /// typename value_type;
58 /// typename reference; // result of dereferencing
59 /// typename difference_type; // result of operator-(iterator,iterator) (1-dimensional!)
60 /// typename const_t; where RandomAccessNDImageViewConcept<View>; // same as View, but over immutable values
61 /// typename point_t; where PointNDConcept<point_t>; // N-dimensional point
62 /// typename locator; where RandomAccessNDLocatorConcept<locator>; // N-dimensional locator.
63 /// typename iterator; where RandomAccessTraversalConcept<iterator>; // 1-dimensional iterator over all values
64 /// typename reverse_iterator; where RandomAccessTraversalConcept<reverse_iterator>;
65 /// typename size_type; // the return value of size()
66 ///
67 /// // Equivalent to RandomAccessNDLocatorConcept::axis
68 /// template <size_t D> struct axis {
69 /// typename coord_t = point_t::axis<D>::coord_t;
70 /// typename iterator; where RandomAccessTraversalConcept<iterator>; // iterator along D-th axis.
71 /// where SameType<coord_t, iterator::difference_type>;
72 /// where SameType<iterator::value_type,value_type>;
73 /// };
74 ///
75 /// // Defines the type of a view similar to this type, except it invokes Deref upon dereferencing
76 /// template <PixelDereferenceAdaptorConcept Deref> struct add_deref {
77 /// typename type; where RandomAccessNDImageViewConcept<type>;
78 /// static type make(const View& v, const Deref& deref);
79 /// };
80 ///
81 /// static const size_t num_dimensions = point_t::num_dimensions;
82 ///
83 /// // Create from a locator at the top-left corner and dimensions
84 /// View::View(const locator&, const point_type&);
85 ///
86 /// size_type View::size() const; // total number of elements
87 /// reference operator[](View, const difference_type&) const; // 1-dimensional reference
88 /// iterator View::begin() const;
89 /// iterator View::end() const;
90 /// reverse_iterator View::rbegin() const;
91 /// reverse_iterator View::rend() const;
92 /// iterator View::at(const point_t&);
93 /// point_t View::dimensions() const; // number of elements along each dimension
94 /// bool View::is_1d_traversable() const; // can an iterator over the first dimension visit each value? I.e. are there gaps between values?
95 ///
96 /// // iterator along a given dimension starting at a given point
97 /// template <size_t D> View::axis<D>::iterator View::axis_iterator(const point_t&) const;
98 ///
99 /// reference operator()(View,const point_t&) const;
100 /// };
101 /// \endcode
102 template <typename View>
103 struct RandomAccessNDImageViewConcept
104 {
105 void constraints()
106 {
107 gil_function_requires<Regular<View>>();
108
109 using value_type = typename View::value_type;
110 using reference = typename View::reference; // result of dereferencing
111 using pointer = typename View::pointer;
112 using difference_type = typename View::difference_type; // result of operator-(1d_iterator,1d_iterator)
113 using const_t = typename View::const_t; // same as this type, but over const values
114 using point_t = typename View::point_t; // N-dimensional point
115 using locator = typename View::locator; // N-dimensional locator
116 using iterator = typename View::iterator;
117 using const_iterator = typename View::const_iterator;
118 using reverse_iterator = typename View::reverse_iterator;
119 using size_type = typename View::size_type;
120 static const std::size_t N=View::num_dimensions;
121
122 gil_function_requires<RandomAccessNDLocatorConcept<locator>>();
123 gil_function_requires<boost_concepts::RandomAccessTraversalConcept<iterator>>();
124 gil_function_requires<boost_concepts::RandomAccessTraversalConcept<reverse_iterator>>();
125
126 using first_it_type = typename View::template axis<0>::iterator;
127 using last_it_type = typename View::template axis<N-1>::iterator;
128 gil_function_requires<boost_concepts::RandomAccessTraversalConcept<first_it_type>>();
129 gil_function_requires<boost_concepts::RandomAccessTraversalConcept<last_it_type>>();
130
131 // static_assert(typename std::iterator_traits<first_it_type>::difference_type, typename point_t::template axis<0>::coord_t>::value, "");
132 // static_assert(typename std::iterator_traits<last_it_type>::difference_type, typename point_t::template axis<N-1>::coord_t>::value, "");
133
134 // point_t must be an N-dimensional point, each dimension of which must have the same type as difference_type of the corresponding iterator
135 gil_function_requires<PointNDConcept<point_t>>();
136 static_assert(point_t::num_dimensions == N, "");
137 static_assert(std::is_same
138 <
139 typename std::iterator_traits<first_it_type>::difference_type,
140 typename point_t::template axis<0>::coord_t
141 >::value, "");
142 static_assert(std::is_same
143 <
144 typename std::iterator_traits<last_it_type>::difference_type,
145 typename point_t::template axis<N-1>::coord_t
146 >::value, "");
147
148 point_t p;
149 locator lc;
150 iterator it;
151 reverse_iterator rit;
152 difference_type d; detail::initialize_it(d); ignore_unused_variable_warning(d);
153
154 View(p,lc); // view must be constructible from a locator and a point
155
156 p = view.dimensions();
157 lc = view.pixels();
158 size_type sz = view.size(); ignore_unused_variable_warning(sz);
159 bool is_contiguous = view.is_1d_traversable();
160 ignore_unused_variable_warning(is_contiguous);
161
162 it = view.begin();
163 it = view.end();
164 rit = view.rbegin();
165 rit = view.rend();
166
167 reference r1 = view[d]; ignore_unused_variable_warning(r1); // 1D access
168 reference r2 = view(p); ignore_unused_variable_warning(r2); // 2D access
169
170 // get 1-D iterator of any dimension at a given pixel location
171 first_it_type fi = view.template axis_iterator<0>(p);
172 ignore_unused_variable_warning(fi);
173 last_it_type li = view.template axis_iterator<N-1>(p);
174 ignore_unused_variable_warning(li);
175
176 using deref_t = PixelDereferenceAdaptorArchetype<typename View::value_type>;
177 using dtype = typename View::template add_deref<deref_t>::type;
178 }
179 View view;
180 };
181
182 /// \ingroup ImageView2DConcept
183 /// \brief 2-dimensional view over immutable values
184 ///
185 /// \code
186 /// concept RandomAccess2DImageViewConcept<RandomAccessNDImageViewConcept View> {
187 /// where num_dimensions==2;
188 ///
189 /// typename x_iterator = axis<0>::iterator;
190 /// typename y_iterator = axis<1>::iterator;
191 /// typename x_coord_t = axis<0>::coord_t;
192 /// typename y_coord_t = axis<1>::coord_t;
193 /// typename xy_locator = locator;
194 ///
195 /// x_coord_t View::width() const;
196 /// y_coord_t View::height() const;
197 ///
198 /// // X-navigation
199 /// x_iterator View::x_at(const point_t&) const;
200 /// x_iterator View::row_begin(y_coord_t) const;
201 /// x_iterator View::row_end (y_coord_t) const;
202 ///
203 /// // Y-navigation
204 /// y_iterator View::y_at(const point_t&) const;
205 /// y_iterator View::col_begin(x_coord_t) const;
206 /// y_iterator View::col_end (x_coord_t) const;
207 ///
208 /// // navigating in 2D
209 /// xy_locator View::xy_at(const point_t&) const;
210 ///
211 /// // (x,y) versions of all methods taking point_t
212 /// View::View(x_coord_t,y_coord_t,const locator&);
213 /// iterator View::at(x_coord_t,y_coord_t) const;
214 /// reference operator()(View,x_coord_t,y_coord_t) const;
215 /// xy_locator View::xy_at(x_coord_t,y_coord_t) const;
216 /// x_iterator View::x_at(x_coord_t,y_coord_t) const;
217 /// y_iterator View::y_at(x_coord_t,y_coord_t) const;
218 /// };
219 /// \endcode
220 template <typename View>
221 struct RandomAccess2DImageViewConcept
222 {
223 void constraints()
224 {
225 gil_function_requires<RandomAccessNDImageViewConcept<View>>();
226 static_assert(View::num_dimensions == 2, "");
227
228 // TODO: This executes the requirements for RandomAccessNDLocatorConcept again. Fix it to improve compile time
229 gil_function_requires<RandomAccess2DLocatorConcept<typename View::locator>>();
230
231 using dynamic_x_step_t = typename dynamic_x_step_type<View>::type;
232 using dynamic_y_step_t = typename dynamic_y_step_type<View>::type;
233 using transposed_t = typename transposed_type<View>::type;
234 using x_iterator = typename View::x_iterator;
235 using y_iterator = typename View::y_iterator;
236 using x_coord_t = typename View::x_coord_t;
237 using y_coord_t = typename View::y_coord_t;
238 using xy_locator = typename View::xy_locator;
239
240 x_coord_t xd = 0; ignore_unused_variable_warning(xd);
241 y_coord_t yd = 0; ignore_unused_variable_warning(yd);
242 x_iterator xit;
243 y_iterator yit;
244 typename View::point_t d;
245
246 View(xd, yd, xy_locator()); // constructible with width, height, 2d_locator
247
248 xy_locator lc = view.xy_at(xd, yd);
249 lc = view.xy_at(d);
250
251 typename View::reference r = view(xd, yd);
252 ignore_unused_variable_warning(r);
253 xd = view.width();
254 yd = view.height();
255
256 xit = view.x_at(d);
257 xit = view.x_at(xd,yd);
258 xit = view.row_begin(xd);
259 xit = view.row_end(xd);
260
261 yit = view.y_at(d);
262 yit = view.y_at(xd,yd);
263 yit = view.col_begin(xd);
264 yit = view.col_end(xd);
265 }
266 View view;
267 };
268
269 /// \brief GIL view as Collection.
270 ///
271 /// \see https://www.boost.org/libs/utility/Collection.html
272 ///
273 template <typename View>
274 struct CollectionImageViewConcept
275 {
276 void constraints()
277 {
278 using value_type = typename View::value_type;
279 using iterator = typename View::iterator;
280 using const_iterator = typename View::const_iterator;
281 using reference = typename View::reference;
282 using const_reference = typename View::const_reference;
283 using pointer = typename View::pointer;
284 using difference_type = typename View::difference_type;
285 using size_type= typename View::size_type;
286
287 iterator i;
288 i = view1.begin();
289 i = view2.end();
290
291 const_iterator ci;
292 ci = view1.begin();
293 ci = view2.end();
294
295 size_type s;
296 s = view1.size();
297 s = view2.size();
298 ignore_unused_variable_warning(s);
299
300 view1.empty();
301
302 view1.swap(view2);
303 }
304 View view1;
305 View view2;
306 };
307
308 /// \brief GIL view as ForwardCollection.
309 ///
310 /// \see https://www.boost.org/libs/utility/Collection.html
311 ///
312 template <typename View>
313 struct ForwardCollectionImageViewConcept
314 {
315 void constraints()
316 {
317 gil_function_requires<CollectionImageViewConcept<View>>();
318
319 using reference = typename View::reference;
320 using const_reference = typename View::const_reference;
321
322 reference r = view.front();
323 ignore_unused_variable_warning(r);
324
325 const_reference cr = view.front();
326 ignore_unused_variable_warning(cr);
327 }
328 View view;
329 };
330
331 /// \brief GIL view as ReversibleCollection.
332 ///
333 /// \see https://www.boost.org/libs/utility/Collection.html
334 ///
335 template <typename View>
336 struct ReversibleCollectionImageViewConcept
337 {
338 void constraints()
339 {
340 gil_function_requires<CollectionImageViewConcept<View>>();
341
342 using reverse_iterator = typename View::reverse_iterator;
343 using reference = typename View::reference;
344 using const_reference = typename View::const_reference;
345
346 reverse_iterator i;
347 i = view.rbegin();
348 i = view.rend();
349
350 reference r = view.back();
351 ignore_unused_variable_warning(r);
352
353 const_reference cr = view.back();
354 ignore_unused_variable_warning(cr);
355 }
356 View view;
357 };
358
359 /// \ingroup PixelImageViewConcept
360 /// \brief GIL's 2-dimensional view over immutable GIL pixels
361 /// \code
362 /// concept ImageViewConcept<RandomAccess2DImageViewConcept View>
363 /// {
364 /// where PixelValueConcept<value_type>;
365 /// where PixelIteratorConcept<x_iterator>;
366 /// where PixelIteratorConcept<y_iterator>;
367 /// where x_coord_t == y_coord_t;
368 ///
369 /// typename coord_t = x_coord_t;
370 ///
371 /// std::size_t View::num_channels() const;
372 /// };
373 /// \endcode
374 template <typename View>
375 struct ImageViewConcept
376 {
377 void constraints()
378 {
379 gil_function_requires<RandomAccess2DImageViewConcept<View>>();
380
381 // TODO: This executes the requirements for RandomAccess2DLocatorConcept again. Fix it to improve compile time
382 gil_function_requires<PixelLocatorConcept<typename View::xy_locator>>();
383
384 static_assert(std::is_same<typename View::x_coord_t, typename View::y_coord_t>::value, "");
385
386 using coord_t = typename View::coord_t; // 1D difference type (same for all dimensions)
387 std::size_t num_chan = view.num_channels(); ignore_unused_variable_warning(num_chan);
388 }
389 View view;
390 };
391
392 namespace detail {
393
394 /// \tparam View Models RandomAccessNDImageViewConcept
395 template <typename View>
396 struct RandomAccessNDImageViewIsMutableConcept
397 {
398 void constraints()
399 {
400 gil_function_requires<detail::RandomAccessNDLocatorIsMutableConcept<typename View::locator>>();
401
402 gil_function_requires<detail::RandomAccessIteratorIsMutableConcept<typename View::iterator>>();
403
404 gil_function_requires<detail::RandomAccessIteratorIsMutableConcept
405 <
406 typename View::reverse_iterator
407 >>();
408
409 gil_function_requires<detail::RandomAccessIteratorIsMutableConcept
410 <
411 typename View::template axis<0>::iterator
412 >>();
413
414 gil_function_requires<detail::RandomAccessIteratorIsMutableConcept
415 <
416 typename View::template axis<View::num_dimensions - 1>::iterator
417 >>();
418
419 typename View::difference_type diff;
420 initialize_it(diff);
421 ignore_unused_variable_warning(diff);
422
423 typename View::point_t pt;
424 typename View::value_type v;
425 initialize_it(v);
426
427 view[diff] = v;
428 view(pt) = v;
429 }
430 View view;
431 };
432
433 /// \tparam View Models RandomAccessNDImageViewConcept
434 template <typename View>
435 struct RandomAccess2DImageViewIsMutableConcept
436 {
437 void constraints()
438 {
439 gil_function_requires<detail::RandomAccessNDImageViewIsMutableConcept<View>>();
440 typename View::x_coord_t xd = 0; ignore_unused_variable_warning(xd);
441 typename View::y_coord_t yd = 0; ignore_unused_variable_warning(yd);
442 typename View::value_type v; initialize_it(v);
443 view(xd, yd) = v;
444 }
445 View view;
446 };
447
448 /// \tparam View Models ImageViewConcept
449 template <typename View>
450 struct PixelImageViewIsMutableConcept
451 {
452 void constraints()
453 {
454 gil_function_requires<detail::RandomAccess2DImageViewIsMutableConcept<View>>();
455 }
456 };
457
458 } // namespace detail
459
460 /// \ingroup ImageViewNDConcept
461 /// \brief N-dimensional view over mutable values
462 ///
463 /// \code
464 /// concept MutableRandomAccessNDImageViewConcept<RandomAccessNDImageViewConcept View>
465 /// {
466 /// where Mutable<reference>;
467 /// };
468 /// \endcode
469 template <typename View>
470 struct MutableRandomAccessNDImageViewConcept
471 {
472 void constraints()
473 {
474 gil_function_requires<RandomAccessNDImageViewConcept<View>>();
475 gil_function_requires<detail::RandomAccessNDImageViewIsMutableConcept<View>>();
476 }
477 };
478
479 /// \ingroup ImageView2DConcept
480 /// \brief 2-dimensional view over mutable values
481 ///
482 /// \code
483 /// concept MutableRandomAccess2DImageViewConcept<RandomAccess2DImageViewConcept View>
484 /// : MutableRandomAccessNDImageViewConcept<View> {};
485 /// \endcode
486 template <typename View>
487 struct MutableRandomAccess2DImageViewConcept
488 {
489 void constraints()
490 {
491 gil_function_requires<RandomAccess2DImageViewConcept<View>>();
492 gil_function_requires<detail::RandomAccess2DImageViewIsMutableConcept<View>>();
493 }
494 };
495
496 /// \ingroup PixelImageViewConcept
497 /// \brief GIL's 2-dimensional view over mutable GIL pixels
498 ///
499 /// \code
500 /// concept MutableImageViewConcept<ImageViewConcept View>
501 /// : MutableRandomAccess2DImageViewConcept<View> {};
502 /// \endcode
503 template <typename View>
504 struct MutableImageViewConcept
505 {
506 void constraints()
507 {
508 gil_function_requires<ImageViewConcept<View>>();
509 gil_function_requires<detail::PixelImageViewIsMutableConcept<View>>();
510 }
511 };
512
513 /// \brief Returns whether two views are compatible
514 ///
515 /// Views are compatible if their pixels are compatible.
516 /// Compatible views can be assigned and copy constructed from one another.
517 ///
518 /// \tparam V1 Models ImageViewConcept
519 /// \tparam V2 Models ImageViewConcept
520 ///
521 template <typename V1, typename V2>
522 struct views_are_compatible
523 : pixels_are_compatible<typename V1::value_type, typename V2::value_type>
524 {
525 };
526
527 /// \ingroup ImageViewConcept
528 /// \brief Views are compatible if they have the same color spaces and compatible channel values.
529 ///
530 /// Constness and layout are not important for compatibility.
531 ///
532 /// \code
533 /// concept ViewsCompatibleConcept<ImageViewConcept V1, ImageViewConcept V2>
534 /// {
535 /// where PixelsCompatibleConcept<V1::value_type, P2::value_type>;
536 /// };
537 /// \endcode
538 template <typename V1, typename V2>
539 struct ViewsCompatibleConcept
540 {
541 void constraints()
542 {
543 static_assert(views_are_compatible<V1, V2>::value, "");
544 }
545 };
546
547 }} // namespace boost::gil
548
549 #if defined(BOOST_CLANG)
550 #pragma clang diagnostic pop
551 #endif
552
553 #if defined(BOOST_GCC) && (BOOST_GCC >= 40900)
554 #pragma GCC diagnostic pop
555 #endif
556
557 #endif