| 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"#endifnamespace 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;/// };/// \endcodetemplate <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;/// };/// \endcodetemplate <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;/// };/// \endcodetemplate <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 RandomAccessNDImageViewConcepttemplate <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 RandomAccessNDImageViewConcepttemplate <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 ImageViewConcepttemplate <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>;/// };/// \endcodetemplate <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> {};/// \endcodetemplate <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> {};/// \endcodetemplate <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>;/// };/// \endcodetemplate <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
 |