summaryrefslogtreecommitdiff
path: root/boost/gil/concepts/image_view.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/gil/concepts/image_view.hpp')
-rw-r--r--boost/gil/concepts/image_view.hpp555
1 files changed, 555 insertions, 0 deletions
diff --git a/boost/gil/concepts/image_view.hpp b/boost/gil/concepts/image_view.hpp
new file mode 100644
index 0000000000..0c9004f2f8
--- /dev/null
+++ b/boost/gil/concepts/image_view.hpp
@@ -0,0 +1,555 @@
+//
+// 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>
+
+#if defined(BOOST_CLANG)
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wunused-local-typedefs"
+#endif
+
+#if defined(BOOST_GCC) && (BOOST_GCC >= 40600)
+#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 ImageView2DConcept
+/// \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(is_same
+ <
+ typename std::iterator_traits<first_it_type>::difference_type,
+ typename point_t::template axis<0>::coord_t
+ >::value, "");
+ static_assert(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(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 >= 40600)
+#pragma GCC diagnostic pop
+#endif
+
+#endif