123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557 |
- //
- // Copyright 2005-2007 Adobe Systems Incorporated
- //
- // Distributed under the Boost Software License, Version 1.0
- // See accompanying file LICENSE_1_0.txt or copy at
- // http://www.boost.org/LICENSE_1_0.txt
- //
- #ifndef BOOST_GIL_CONCEPTS_IMAGE_VIEW_HPP
- #define BOOST_GIL_CONCEPTS_IMAGE_VIEW_HPP
- #include <boost/gil/concepts/basic.hpp>
- #include <boost/gil/concepts/concept_check.hpp>
- #include <boost/gil/concepts/fwd.hpp>
- #include <boost/gil/concepts/pixel.hpp>
- #include <boost/gil/concepts/pixel_dereference.hpp>
- #include <boost/gil/concepts/pixel_iterator.hpp>
- #include <boost/gil/concepts/pixel_locator.hpp>
- #include <boost/gil/concepts/point.hpp>
- #include <boost/gil/concepts/detail/utility.hpp>
- #include <cstddef>
- #include <iterator>
- #include <type_traits>
- #if defined(BOOST_CLANG)
- #pragma clang diagnostic push
- #pragma clang diagnostic ignored "-Wunknown-pragmas"
- #pragma clang diagnostic ignored "-Wunused-local-typedefs"
- #endif
- #if defined(BOOST_GCC) && (BOOST_GCC >= 40900)
- #pragma GCC diagnostic push
- #pragma GCC diagnostic ignored "-Wunused-local-typedefs"
- #pragma GCC diagnostic ignored "-Wunused-but-set-variable"
- #endif
- namespace boost { namespace gil {
- /// \defgroup ImageViewNDConcept ImageViewNDLocatorConcept
- /// \ingroup ImageViewConcept
- /// \brief N-dimensional range
- /// \defgroup ImageView2DConcept ImageView2DLocatorConcept
- /// \ingroup ImageViewConcept
- /// \brief 2-dimensional range
- /// \defgroup PixelImageViewConcept ImageViewConcept
- /// \ingroup ImageViewConcept
- /// \brief 2-dimensional range over pixel data
- /// \ingroup ImageViewNDConcept
- /// \brief N-dimensional view over immutable values
- ///
- /// \code
- /// concept RandomAccessNDImageViewConcept<Regular View>
- /// {
- /// typename value_type;
- /// typename reference; // result of dereferencing
- /// typename difference_type; // result of operator-(iterator,iterator) (1-dimensional!)
- /// typename const_t; where RandomAccessNDImageViewConcept<View>; // same as View, but over immutable values
- /// typename point_t; where PointNDConcept<point_t>; // N-dimensional point
- /// typename locator; where RandomAccessNDLocatorConcept<locator>; // N-dimensional locator.
- /// typename iterator; where RandomAccessTraversalConcept<iterator>; // 1-dimensional iterator over all values
- /// typename reverse_iterator; where RandomAccessTraversalConcept<reverse_iterator>;
- /// typename size_type; // the return value of size()
- ///
- /// // Equivalent to RandomAccessNDLocatorConcept::axis
- /// template <size_t D> struct axis {
- /// typename coord_t = point_t::axis<D>::coord_t;
- /// typename iterator; where RandomAccessTraversalConcept<iterator>; // iterator along D-th axis.
- /// where SameType<coord_t, iterator::difference_type>;
- /// where SameType<iterator::value_type,value_type>;
- /// };
- ///
- /// // Defines the type of a view similar to this type, except it invokes Deref upon dereferencing
- /// template <PixelDereferenceAdaptorConcept Deref> struct add_deref {
- /// typename type; where RandomAccessNDImageViewConcept<type>;
- /// static type make(const View& v, const Deref& deref);
- /// };
- ///
- /// static const size_t num_dimensions = point_t::num_dimensions;
- ///
- /// // Create from a locator at the top-left corner and dimensions
- /// View::View(const locator&, const point_type&);
- ///
- /// size_type View::size() const; // total number of elements
- /// reference operator[](View, const difference_type&) const; // 1-dimensional reference
- /// iterator View::begin() const;
- /// iterator View::end() const;
- /// reverse_iterator View::rbegin() const;
- /// reverse_iterator View::rend() const;
- /// iterator View::at(const point_t&);
- /// point_t View::dimensions() const; // number of elements along each dimension
- /// bool View::is_1d_traversable() const; // can an iterator over the first dimension visit each value? I.e. are there gaps between values?
- ///
- /// // iterator along a given dimension starting at a given point
- /// template <size_t D> View::axis<D>::iterator View::axis_iterator(const point_t&) const;
- ///
- /// reference operator()(View,const point_t&) const;
- /// };
- /// \endcode
- template <typename View>
- struct RandomAccessNDImageViewConcept
- {
- void constraints()
- {
- gil_function_requires<Regular<View>>();
- using value_type = typename View::value_type;
- using reference = typename View::reference; // result of dereferencing
- using pointer = typename View::pointer;
- using difference_type = typename View::difference_type; // result of operator-(1d_iterator,1d_iterator)
- using const_t = typename View::const_t; // same as this type, but over const values
- using point_t = typename View::point_t; // N-dimensional point
- using locator = typename View::locator; // N-dimensional locator
- using iterator = typename View::iterator;
- using const_iterator = typename View::const_iterator;
- using reverse_iterator = typename View::reverse_iterator;
- using size_type = typename View::size_type;
- static const std::size_t N=View::num_dimensions;
- gil_function_requires<RandomAccessNDLocatorConcept<locator>>();
- gil_function_requires<boost_concepts::RandomAccessTraversalConcept<iterator>>();
- gil_function_requires<boost_concepts::RandomAccessTraversalConcept<reverse_iterator>>();
- using first_it_type = typename View::template axis<0>::iterator;
- using last_it_type = typename View::template axis<N-1>::iterator;
- gil_function_requires<boost_concepts::RandomAccessTraversalConcept<first_it_type>>();
- gil_function_requires<boost_concepts::RandomAccessTraversalConcept<last_it_type>>();
- // static_assert(typename std::iterator_traits<first_it_type>::difference_type, typename point_t::template axis<0>::coord_t>::value, "");
- // static_assert(typename std::iterator_traits<last_it_type>::difference_type, typename point_t::template axis<N-1>::coord_t>::value, "");
- // point_t must be an N-dimensional point, each dimension of which must have the same type as difference_type of the corresponding iterator
- gil_function_requires<PointNDConcept<point_t>>();
- static_assert(point_t::num_dimensions == N, "");
- static_assert(std::is_same
- <
- typename std::iterator_traits<first_it_type>::difference_type,
- typename point_t::template axis<0>::coord_t
- >::value, "");
- static_assert(std::is_same
- <
- typename std::iterator_traits<last_it_type>::difference_type,
- typename point_t::template axis<N-1>::coord_t
- >::value, "");
- point_t p;
- locator lc;
- iterator it;
- reverse_iterator rit;
- difference_type d; detail::initialize_it(d); ignore_unused_variable_warning(d);
- View(p,lc); // view must be constructible from a locator and a point
- p = view.dimensions();
- lc = view.pixels();
- size_type sz = view.size(); ignore_unused_variable_warning(sz);
- bool is_contiguous = view.is_1d_traversable();
- ignore_unused_variable_warning(is_contiguous);
- it = view.begin();
- it = view.end();
- rit = view.rbegin();
- rit = view.rend();
- reference r1 = view[d]; ignore_unused_variable_warning(r1); // 1D access
- reference r2 = view(p); ignore_unused_variable_warning(r2); // 2D access
- // get 1-D iterator of any dimension at a given pixel location
- first_it_type fi = view.template axis_iterator<0>(p);
- ignore_unused_variable_warning(fi);
- last_it_type li = view.template axis_iterator<N-1>(p);
- ignore_unused_variable_warning(li);
- using deref_t = PixelDereferenceAdaptorArchetype<typename View::value_type>;
- using dtype = typename View::template add_deref<deref_t>::type;
- }
- View view;
- };
- /// \ingroup ImageView2DConcept
- /// \brief 2-dimensional view over immutable values
- ///
- /// \code
- /// concept RandomAccess2DImageViewConcept<RandomAccessNDImageViewConcept View> {
- /// where num_dimensions==2;
- ///
- /// typename x_iterator = axis<0>::iterator;
- /// typename y_iterator = axis<1>::iterator;
- /// typename x_coord_t = axis<0>::coord_t;
- /// typename y_coord_t = axis<1>::coord_t;
- /// typename xy_locator = locator;
- ///
- /// x_coord_t View::width() const;
- /// y_coord_t View::height() const;
- ///
- /// // X-navigation
- /// x_iterator View::x_at(const point_t&) const;
- /// x_iterator View::row_begin(y_coord_t) const;
- /// x_iterator View::row_end (y_coord_t) const;
- ///
- /// // Y-navigation
- /// y_iterator View::y_at(const point_t&) const;
- /// y_iterator View::col_begin(x_coord_t) const;
- /// y_iterator View::col_end (x_coord_t) const;
- ///
- /// // navigating in 2D
- /// xy_locator View::xy_at(const point_t&) const;
- ///
- /// // (x,y) versions of all methods taking point_t
- /// View::View(x_coord_t,y_coord_t,const locator&);
- /// iterator View::at(x_coord_t,y_coord_t) const;
- /// reference operator()(View,x_coord_t,y_coord_t) const;
- /// xy_locator View::xy_at(x_coord_t,y_coord_t) const;
- /// x_iterator View::x_at(x_coord_t,y_coord_t) const;
- /// y_iterator View::y_at(x_coord_t,y_coord_t) const;
- /// };
- /// \endcode
- template <typename View>
- struct RandomAccess2DImageViewConcept
- {
- void constraints()
- {
- gil_function_requires<RandomAccessNDImageViewConcept<View>>();
- static_assert(View::num_dimensions == 2, "");
- // TODO: This executes the requirements for RandomAccessNDLocatorConcept again. Fix it to improve compile time
- gil_function_requires<RandomAccess2DLocatorConcept<typename View::locator>>();
- using dynamic_x_step_t = typename dynamic_x_step_type<View>::type;
- using dynamic_y_step_t = typename dynamic_y_step_type<View>::type;
- using transposed_t = typename transposed_type<View>::type;
- using x_iterator = typename View::x_iterator;
- using y_iterator = typename View::y_iterator;
- using x_coord_t = typename View::x_coord_t;
- using y_coord_t = typename View::y_coord_t;
- using xy_locator = typename View::xy_locator;
- x_coord_t xd = 0; ignore_unused_variable_warning(xd);
- y_coord_t yd = 0; ignore_unused_variable_warning(yd);
- x_iterator xit;
- y_iterator yit;
- typename View::point_t d;
- View(xd, yd, xy_locator()); // constructible with width, height, 2d_locator
- xy_locator lc = view.xy_at(xd, yd);
- lc = view.xy_at(d);
- typename View::reference r = view(xd, yd);
- ignore_unused_variable_warning(r);
- xd = view.width();
- yd = view.height();
- xit = view.x_at(d);
- xit = view.x_at(xd,yd);
- xit = view.row_begin(xd);
- xit = view.row_end(xd);
- yit = view.y_at(d);
- yit = view.y_at(xd,yd);
- yit = view.col_begin(xd);
- yit = view.col_end(xd);
- }
- View view;
- };
- /// \brief GIL view as Collection.
- ///
- /// \see https://www.boost.org/libs/utility/Collection.html
- ///
- template <typename View>
- struct CollectionImageViewConcept
- {
- void constraints()
- {
- using value_type = typename View::value_type;
- using iterator = typename View::iterator;
- using const_iterator = typename View::const_iterator;
- using reference = typename View::reference;
- using const_reference = typename View::const_reference;
- using pointer = typename View::pointer;
- using difference_type = typename View::difference_type;
- using size_type= typename View::size_type;
- iterator i;
- i = view1.begin();
- i = view2.end();
- const_iterator ci;
- ci = view1.begin();
- ci = view2.end();
- size_type s;
- s = view1.size();
- s = view2.size();
- ignore_unused_variable_warning(s);
- view1.empty();
- view1.swap(view2);
- }
- View view1;
- View view2;
- };
- /// \brief GIL view as ForwardCollection.
- ///
- /// \see https://www.boost.org/libs/utility/Collection.html
- ///
- template <typename View>
- struct ForwardCollectionImageViewConcept
- {
- void constraints()
- {
- gil_function_requires<CollectionImageViewConcept<View>>();
- using reference = typename View::reference;
- using const_reference = typename View::const_reference;
- reference r = view.front();
- ignore_unused_variable_warning(r);
- const_reference cr = view.front();
- ignore_unused_variable_warning(cr);
- }
- View view;
- };
- /// \brief GIL view as ReversibleCollection.
- ///
- /// \see https://www.boost.org/libs/utility/Collection.html
- ///
- template <typename View>
- struct ReversibleCollectionImageViewConcept
- {
- void constraints()
- {
- gil_function_requires<CollectionImageViewConcept<View>>();
- using reverse_iterator = typename View::reverse_iterator;
- using reference = typename View::reference;
- using const_reference = typename View::const_reference;
- reverse_iterator i;
- i = view.rbegin();
- i = view.rend();
- reference r = view.back();
- ignore_unused_variable_warning(r);
- const_reference cr = view.back();
- ignore_unused_variable_warning(cr);
- }
- View view;
- };
- /// \ingroup PixelImageViewConcept
- /// \brief GIL's 2-dimensional view over immutable GIL pixels
- /// \code
- /// concept ImageViewConcept<RandomAccess2DImageViewConcept View>
- /// {
- /// where PixelValueConcept<value_type>;
- /// where PixelIteratorConcept<x_iterator>;
- /// where PixelIteratorConcept<y_iterator>;
- /// where x_coord_t == y_coord_t;
- ///
- /// typename coord_t = x_coord_t;
- ///
- /// std::size_t View::num_channels() const;
- /// };
- /// \endcode
- template <typename View>
- struct ImageViewConcept
- {
- void constraints()
- {
- gil_function_requires<RandomAccess2DImageViewConcept<View>>();
- // TODO: This executes the requirements for RandomAccess2DLocatorConcept again. Fix it to improve compile time
- gil_function_requires<PixelLocatorConcept<typename View::xy_locator>>();
- static_assert(std::is_same<typename View::x_coord_t, typename View::y_coord_t>::value, "");
- using coord_t = typename View::coord_t; // 1D difference type (same for all dimensions)
- std::size_t num_chan = view.num_channels(); ignore_unused_variable_warning(num_chan);
- }
- View view;
- };
- namespace detail {
- /// \tparam View Models RandomAccessNDImageViewConcept
- template <typename View>
- struct RandomAccessNDImageViewIsMutableConcept
- {
- void constraints()
- {
- gil_function_requires<detail::RandomAccessNDLocatorIsMutableConcept<typename View::locator>>();
- gil_function_requires<detail::RandomAccessIteratorIsMutableConcept<typename View::iterator>>();
- gil_function_requires<detail::RandomAccessIteratorIsMutableConcept
- <
- typename View::reverse_iterator
- >>();
- gil_function_requires<detail::RandomAccessIteratorIsMutableConcept
- <
- typename View::template axis<0>::iterator
- >>();
- gil_function_requires<detail::RandomAccessIteratorIsMutableConcept
- <
- typename View::template axis<View::num_dimensions - 1>::iterator
- >>();
- typename View::difference_type diff;
- initialize_it(diff);
- ignore_unused_variable_warning(diff);
- typename View::point_t pt;
- typename View::value_type v;
- initialize_it(v);
- view[diff] = v;
- view(pt) = v;
- }
- View view;
- };
- /// \tparam View Models RandomAccessNDImageViewConcept
- template <typename View>
- struct RandomAccess2DImageViewIsMutableConcept
- {
- void constraints()
- {
- gil_function_requires<detail::RandomAccessNDImageViewIsMutableConcept<View>>();
- typename View::x_coord_t xd = 0; ignore_unused_variable_warning(xd);
- typename View::y_coord_t yd = 0; ignore_unused_variable_warning(yd);
- typename View::value_type v; initialize_it(v);
- view(xd, yd) = v;
- }
- View view;
- };
- /// \tparam View Models ImageViewConcept
- template <typename View>
- struct PixelImageViewIsMutableConcept
- {
- void constraints()
- {
- gil_function_requires<detail::RandomAccess2DImageViewIsMutableConcept<View>>();
- }
- };
- } // namespace detail
- /// \ingroup ImageViewNDConcept
- /// \brief N-dimensional view over mutable values
- ///
- /// \code
- /// concept MutableRandomAccessNDImageViewConcept<RandomAccessNDImageViewConcept View>
- /// {
- /// where Mutable<reference>;
- /// };
- /// \endcode
- template <typename View>
- struct MutableRandomAccessNDImageViewConcept
- {
- void constraints()
- {
- gil_function_requires<RandomAccessNDImageViewConcept<View>>();
- gil_function_requires<detail::RandomAccessNDImageViewIsMutableConcept<View>>();
- }
- };
- /// \ingroup ImageView2DConcept
- /// \brief 2-dimensional view over mutable values
- ///
- /// \code
- /// concept MutableRandomAccess2DImageViewConcept<RandomAccess2DImageViewConcept View>
- /// : MutableRandomAccessNDImageViewConcept<View> {};
- /// \endcode
- template <typename View>
- struct MutableRandomAccess2DImageViewConcept
- {
- void constraints()
- {
- gil_function_requires<RandomAccess2DImageViewConcept<View>>();
- gil_function_requires<detail::RandomAccess2DImageViewIsMutableConcept<View>>();
- }
- };
- /// \ingroup PixelImageViewConcept
- /// \brief GIL's 2-dimensional view over mutable GIL pixels
- ///
- /// \code
- /// concept MutableImageViewConcept<ImageViewConcept View>
- /// : MutableRandomAccess2DImageViewConcept<View> {};
- /// \endcode
- template <typename View>
- struct MutableImageViewConcept
- {
- void constraints()
- {
- gil_function_requires<ImageViewConcept<View>>();
- gil_function_requires<detail::PixelImageViewIsMutableConcept<View>>();
- }
- };
- /// \brief Returns whether two views are compatible
- ///
- /// Views are compatible if their pixels are compatible.
- /// Compatible views can be assigned and copy constructed from one another.
- ///
- /// \tparam V1 Models ImageViewConcept
- /// \tparam V2 Models ImageViewConcept
- ///
- template <typename V1, typename V2>
- struct views_are_compatible
- : pixels_are_compatible<typename V1::value_type, typename V2::value_type>
- {
- };
- /// \ingroup ImageViewConcept
- /// \brief Views are compatible if they have the same color spaces and compatible channel values.
- ///
- /// Constness and layout are not important for compatibility.
- ///
- /// \code
- /// concept ViewsCompatibleConcept<ImageViewConcept V1, ImageViewConcept V2>
- /// {
- /// where PixelsCompatibleConcept<V1::value_type, P2::value_type>;
- /// };
- /// \endcode
- template <typename V1, typename V2>
- struct ViewsCompatibleConcept
- {
- void constraints()
- {
- static_assert(views_are_compatible<V1, V2>::value, "");
- }
- };
- }} // namespace boost::gil
- #if defined(BOOST_CLANG)
- #pragma clang diagnostic pop
- #endif
- #if defined(BOOST_GCC) && (BOOST_GCC >= 40900)
- #pragma GCC diagnostic pop
- #endif
- #endif
|