Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:36:55

0001 //
0002 // Copyright 2005-2007 Adobe Systems Incorporated
0003 //
0004 // Distributed under the Boost Software License, Version 1.0
0005 // See accompanying file LICENSE_1_0.txt or copy at
0006 // http://www.boost.org/LICENSE_1_0.txt
0007 //
0008 #ifndef BOOST_GIL_CONCEPTS_IMAGE_VIEW_HPP
0009 #define BOOST_GIL_CONCEPTS_IMAGE_VIEW_HPP
0010 
0011 #include <boost/gil/concepts/basic.hpp>
0012 #include <boost/gil/concepts/concept_check.hpp>
0013 #include <boost/gil/concepts/fwd.hpp>
0014 #include <boost/gil/concepts/pixel.hpp>
0015 #include <boost/gil/concepts/pixel_dereference.hpp>
0016 #include <boost/gil/concepts/pixel_iterator.hpp>
0017 #include <boost/gil/concepts/pixel_locator.hpp>
0018 #include <boost/gil/concepts/point.hpp>
0019 #include <boost/gil/concepts/detail/utility.hpp>
0020 
0021 #include <cstddef>
0022 #include <iterator>
0023 #include <type_traits>
0024 
0025 #if defined(BOOST_CLANG)
0026 #pragma clang diagnostic push
0027 #pragma clang diagnostic ignored "-Wunknown-pragmas"
0028 #pragma clang diagnostic ignored "-Wunused-local-typedefs"
0029 #endif
0030 
0031 #if defined(BOOST_GCC) && (BOOST_GCC >= 40900)
0032 #pragma GCC diagnostic push
0033 #pragma GCC diagnostic ignored "-Wunused-local-typedefs"
0034 #pragma GCC diagnostic ignored "-Wunused-but-set-variable"
0035 #endif
0036 
0037 namespace boost { namespace gil {
0038 
0039 /// \defgroup ImageViewNDConcept ImageViewNDLocatorConcept
0040 /// \ingroup ImageViewConcept
0041 /// \brief N-dimensional range
0042 
0043 /// \defgroup ImageView2DConcept ImageView2DLocatorConcept
0044 /// \ingroup ImageViewConcept
0045 /// \brief 2-dimensional range
0046 
0047 /// \defgroup PixelImageViewConcept ImageViewConcept
0048 /// \ingroup ImageViewConcept
0049 /// \brief 2-dimensional range over pixel data
0050 
0051 /// \ingroup ImageViewNDConcept
0052 /// \brief N-dimensional view over immutable values
0053 ///
0054 /// \code
0055 /// concept RandomAccessNDImageViewConcept<Regular View>
0056 /// {
0057 ///     typename value_type;
0058 ///     typename reference;       // result of dereferencing
0059 ///     typename difference_type; // result of operator-(iterator,iterator) (1-dimensional!)
0060 ///     typename const_t;  where RandomAccessNDImageViewConcept<View>; // same as View, but over immutable values
0061 ///     typename point_t;  where PointNDConcept<point_t>; // N-dimensional point
0062 ///     typename locator;  where RandomAccessNDLocatorConcept<locator>; // N-dimensional locator.
0063 ///     typename iterator; where RandomAccessTraversalConcept<iterator>; // 1-dimensional iterator over all values
0064 ///     typename reverse_iterator; where RandomAccessTraversalConcept<reverse_iterator>;
0065 ///     typename size_type;       // the return value of size()
0066 ///
0067 ///     // Equivalent to RandomAccessNDLocatorConcept::axis
0068 ///     template <size_t D> struct axis {
0069 ///         typename coord_t = point_t::axis<D>::coord_t;
0070 ///         typename iterator; where RandomAccessTraversalConcept<iterator>;   // iterator along D-th axis.
0071 ///         where SameType<coord_t, iterator::difference_type>;
0072 ///         where SameType<iterator::value_type,value_type>;
0073 ///     };
0074 ///
0075 ///     // Defines the type of a view similar to this type, except it invokes Deref upon dereferencing
0076 ///     template <PixelDereferenceAdaptorConcept Deref> struct add_deref {
0077 ///         typename type;        where RandomAccessNDImageViewConcept<type>;
0078 ///         static type make(const View& v, const Deref& deref);
0079 ///     };
0080 ///
0081 ///     static const size_t num_dimensions = point_t::num_dimensions;
0082 ///
0083 ///     // Create from a locator at the top-left corner and dimensions
0084 ///     View::View(const locator&, const point_type&);
0085 ///
0086 ///     size_type        View::size()       const; // total number of elements
0087 ///     reference        operator[](View, const difference_type&) const; // 1-dimensional reference
0088 ///     iterator         View::begin()      const;
0089 ///     iterator         View::end()        const;
0090 ///     reverse_iterator View::rbegin()     const;
0091 ///     reverse_iterator View::rend()       const;
0092 ///     iterator         View::at(point_t const&);
0093 ///     point_t          View::dimensions() const; // number of elements along each dimension
0094 ///     bool             View::is_1d_traversable() const;   // can an iterator over the first dimension visit each value? I.e. are there gaps between values?
0095 ///
0096 ///     // iterator along a given dimension starting at a given point
0097 ///     template <size_t D> View::axis<D>::iterator View::axis_iterator(point_t const&) const;
0098 ///
0099 ///     reference operator()(View,point_t const&) const;
0100 /// };
0101 /// \endcode
0102 template <typename View>
0103 struct RandomAccessNDImageViewConcept
0104 {
0105     void constraints()
0106     {
0107         gil_function_requires<Regular<View>>();
0108 
0109         using value_type = typename View::value_type;
0110         using reference = typename View::reference; // result of dereferencing
0111         using pointer = typename View::pointer;
0112         using difference_type = typename View::difference_type; // result of operator-(1d_iterator,1d_iterator)
0113         using const_t = typename View::const_t; // same as this type, but over const values
0114         using point_t = typename View::point_t; // N-dimensional point
0115         using locator = typename View::locator; // N-dimensional locator
0116         using iterator = typename View::iterator;
0117         using const_iterator = typename View::const_iterator;
0118         using reverse_iterator = typename View::reverse_iterator;
0119         using size_type = typename View::size_type;
0120         static const std::size_t N=View::num_dimensions;
0121 
0122         gil_function_requires<RandomAccessNDLocatorConcept<locator>>();
0123         gil_function_requires<boost_concepts::RandomAccessTraversalConcept<iterator>>();
0124         gil_function_requires<boost_concepts::RandomAccessTraversalConcept<reverse_iterator>>();
0125 
0126         using first_it_type = typename View::template axis<0>::iterator;
0127         using last_it_type = typename View::template axis<N-1>::iterator;
0128         gil_function_requires<boost_concepts::RandomAccessTraversalConcept<first_it_type>>();
0129         gil_function_requires<boost_concepts::RandomAccessTraversalConcept<last_it_type>>();
0130 
0131 //        static_assert(typename std::iterator_traits<first_it_type>::difference_type, typename point_t::template axis<0>::coord_t>::value, "");
0132 //        static_assert(typename std::iterator_traits<last_it_type>::difference_type, typename point_t::template axis<N-1>::coord_t>::value, "");
0133 
0134         // point_t must be an N-dimensional point, each dimension of which must have the same type as difference_type of the corresponding iterator
0135         gil_function_requires<PointNDConcept<point_t>>();
0136         static_assert(point_t::num_dimensions == N, "");
0137         static_assert(std::is_same
0138             <
0139                 typename std::iterator_traits<first_it_type>::difference_type,
0140                 typename point_t::template axis<0>::coord_t
0141             >::value, "");
0142         static_assert(std::is_same
0143             <
0144                 typename std::iterator_traits<last_it_type>::difference_type,
0145                 typename point_t::template axis<N-1>::coord_t
0146             >::value, "");
0147 
0148         point_t p;
0149         locator lc;
0150         iterator it;
0151         reverse_iterator rit;
0152         difference_type d; detail::initialize_it(d); ignore_unused_variable_warning(d);
0153 
0154         View(p,lc); // view must be constructible from a locator and a point
0155 
0156         p = view.dimensions();
0157         lc = view.pixels();
0158         size_type sz = view.size(); ignore_unused_variable_warning(sz);
0159         bool is_contiguous = view.is_1d_traversable();
0160         ignore_unused_variable_warning(is_contiguous);
0161 
0162         it = view.begin();
0163         it = view.end();
0164         rit = view.rbegin();
0165         rit = view.rend();
0166 
0167         reference r1 = view[d]; ignore_unused_variable_warning(r1); // 1D access
0168         reference r2 = view(p); ignore_unused_variable_warning(r2); // 2D access
0169 
0170         // get 1-D iterator of any dimension at a given pixel location
0171         first_it_type fi = view.template axis_iterator<0>(p);
0172         ignore_unused_variable_warning(fi);
0173         last_it_type li = view.template axis_iterator<N-1>(p);
0174         ignore_unused_variable_warning(li);
0175 
0176         using deref_t = PixelDereferenceAdaptorArchetype<typename View::value_type>;
0177         using dtype = typename View::template add_deref<deref_t>::type;
0178     }
0179     View view;
0180 };
0181 
0182 /// \ingroup ImageView2DConcept
0183 /// \brief 2-dimensional view over immutable values
0184 ///
0185 /// \code
0186 /// concept RandomAccess2DImageViewConcept<RandomAccessNDImageViewConcept View> {
0187 ///     where num_dimensions==2;
0188 ///
0189 ///     typename x_iterator = axis<0>::iterator;
0190 ///     typename y_iterator = axis<1>::iterator;
0191 ///     typename x_coord_t  = axis<0>::coord_t;
0192 ///     typename y_coord_t  = axis<1>::coord_t;
0193 ///     typename xy_locator = locator;
0194 ///
0195 ///     x_coord_t View::width()  const;
0196 ///     y_coord_t View::height() const;
0197 ///
0198 ///     // X-navigation
0199 ///     x_iterator View::x_at(point_t const&) const;
0200 ///     x_iterator View::row_begin(y_coord_t) const;
0201 ///     x_iterator View::row_end  (y_coord_t) const;
0202 ///
0203 ///     // Y-navigation
0204 ///     y_iterator View::y_at(point_t const&) const;
0205 ///     y_iterator View::col_begin(x_coord_t) const;
0206 ///     y_iterator View::col_end  (x_coord_t) const;
0207 ///
0208 ///     // navigating in 2D
0209 ///     xy_locator View::xy_at(point_t const&) const;
0210 ///
0211 ///     // (x,y) versions of all methods taking point_t
0212 ///     View::View(x_coord_t,y_coord_t,const locator&);
0213 ///     iterator View::at(x_coord_t,y_coord_t) const;
0214 ///     reference operator()(View,x_coord_t,y_coord_t) const;
0215 ///     xy_locator View::xy_at(x_coord_t,y_coord_t) const;
0216 ///     x_iterator View::x_at(x_coord_t,y_coord_t) const;
0217 ///     y_iterator View::y_at(x_coord_t,y_coord_t) const;
0218 /// };
0219 /// \endcode
0220 template <typename View>
0221 struct RandomAccess2DImageViewConcept
0222 {
0223     void constraints()
0224     {
0225         gil_function_requires<RandomAccessNDImageViewConcept<View>>();
0226         static_assert(View::num_dimensions == 2, "");
0227 
0228         // TODO: This executes the requirements for RandomAccessNDLocatorConcept again. Fix it to improve compile time
0229         gil_function_requires<RandomAccess2DLocatorConcept<typename View::locator>>();
0230 
0231         using dynamic_x_step_t = typename dynamic_x_step_type<View>::type;
0232         using dynamic_y_step_t = typename dynamic_y_step_type<View>::type;
0233         using transposed_t = typename transposed_type<View>::type;
0234         using x_iterator = typename View::x_iterator;
0235         using y_iterator = typename View::y_iterator;
0236         using x_coord_t = typename View::x_coord_t;
0237         using y_coord_t = typename View::y_coord_t;
0238         using xy_locator = typename View::xy_locator;
0239 
0240         x_coord_t xd = 0; ignore_unused_variable_warning(xd);
0241         y_coord_t yd = 0; ignore_unused_variable_warning(yd);
0242         x_iterator xit;
0243         y_iterator yit;
0244         typename View::point_t d;
0245 
0246         View(xd, yd, xy_locator()); // constructible with width, height, 2d_locator
0247 
0248         xy_locator lc = view.xy_at(xd, yd);
0249         lc = view.xy_at(d);
0250 
0251         typename View::reference r = view(xd, yd);
0252         ignore_unused_variable_warning(r);
0253         xd = view.width();
0254         yd = view.height();
0255 
0256         xit = view.x_at(d);
0257         xit = view.x_at(xd,yd);
0258         xit = view.row_begin(xd);
0259         xit = view.row_end(xd);
0260 
0261         yit = view.y_at(d);
0262         yit = view.y_at(xd,yd);
0263         yit = view.col_begin(xd);
0264         yit = view.col_end(xd);
0265     }
0266     View view;
0267 };
0268 
0269 /// \brief GIL view as Collection.
0270 ///
0271 /// \see https://www.boost.org/libs/utility/Collection.html
0272 ///
0273 template <typename View>
0274 struct CollectionImageViewConcept
0275 {
0276     void constraints()
0277     {
0278         using value_type = typename View::value_type;
0279         using iterator = typename View::iterator;
0280         using const_iterator =  typename View::const_iterator;
0281         using reference = typename View::reference;
0282         using const_reference = typename View::const_reference;
0283         using pointer = typename View::pointer;
0284         using difference_type = typename View::difference_type;
0285         using size_type=  typename View::size_type;
0286 
0287         iterator i;
0288         i = view1.begin();
0289         i = view2.end();
0290 
0291         const_iterator ci;
0292         ci = view1.begin();
0293         ci = view2.end();
0294 
0295         size_type s;
0296         s = view1.size();
0297         s = view2.size();
0298         ignore_unused_variable_warning(s);
0299 
0300         view1.empty();
0301 
0302         view1.swap(view2);
0303     }
0304     View view1;
0305     View view2;
0306 };
0307 
0308 /// \brief GIL view as ForwardCollection.
0309 ///
0310 /// \see https://www.boost.org/libs/utility/Collection.html
0311 ///
0312 template <typename View>
0313 struct ForwardCollectionImageViewConcept
0314 {
0315     void constraints()
0316     {
0317         gil_function_requires<CollectionImageViewConcept<View>>();
0318 
0319         using reference = typename View::reference;
0320         using const_reference = typename View::const_reference;
0321 
0322         reference r = view.front();
0323         ignore_unused_variable_warning(r);
0324 
0325         const_reference cr = view.front();
0326         ignore_unused_variable_warning(cr);
0327     }
0328     View view;
0329 };
0330 
0331 /// \brief GIL view as ReversibleCollection.
0332 ///
0333 /// \see https://www.boost.org/libs/utility/Collection.html
0334 ///
0335 template <typename View>
0336 struct ReversibleCollectionImageViewConcept
0337 {
0338     void constraints()
0339     {
0340         gil_function_requires<CollectionImageViewConcept<View>>();
0341 
0342         using reverse_iterator = typename View::reverse_iterator;
0343         using reference = typename View::reference;
0344         using const_reference = typename View::const_reference;
0345 
0346         reverse_iterator i;
0347         i = view.rbegin();
0348         i = view.rend();
0349 
0350         reference r = view.back();
0351         ignore_unused_variable_warning(r);
0352 
0353         const_reference cr = view.back();
0354         ignore_unused_variable_warning(cr);
0355     }
0356     View view;
0357 };
0358 
0359 /// \ingroup PixelImageViewConcept
0360 /// \brief GIL's 2-dimensional view over immutable GIL pixels
0361 /// \code
0362 /// concept ImageViewConcept<RandomAccess2DImageViewConcept View>
0363 /// {
0364 ///     where PixelValueConcept<value_type>;
0365 ///     where PixelIteratorConcept<x_iterator>;
0366 ///     where PixelIteratorConcept<y_iterator>;
0367 ///     where x_coord_t == y_coord_t;
0368 ///
0369 ///     typename coord_t = x_coord_t;
0370 ///
0371 ///     std::size_t View::num_channels() const;
0372 /// };
0373 /// \endcode
0374 template <typename View>
0375 struct ImageViewConcept
0376 {
0377     void constraints()
0378     {
0379         gil_function_requires<RandomAccess2DImageViewConcept<View>>();
0380 
0381         // TODO: This executes the requirements for RandomAccess2DLocatorConcept again. Fix it to improve compile time
0382         gil_function_requires<PixelLocatorConcept<typename View::xy_locator>>();
0383 
0384         static_assert(std::is_same<typename View::x_coord_t, typename View::y_coord_t>::value, "");
0385 
0386         using coord_t = typename View::coord_t; // 1D difference type (same for all dimensions)
0387         std::size_t num_chan = view.num_channels(); ignore_unused_variable_warning(num_chan);
0388     }
0389     View view;
0390 };
0391 
0392 namespace detail {
0393 
0394 /// \tparam View Models RandomAccessNDImageViewConcept
0395 template <typename View>
0396 struct RandomAccessNDImageViewIsMutableConcept
0397 {
0398     void constraints()
0399     {
0400         gil_function_requires<detail::RandomAccessNDLocatorIsMutableConcept<typename View::locator>>();
0401 
0402         gil_function_requires<detail::RandomAccessIteratorIsMutableConcept<typename View::iterator>>();
0403 
0404         gil_function_requires<detail::RandomAccessIteratorIsMutableConcept
0405             <
0406                 typename View::reverse_iterator
0407             >>();
0408 
0409         gil_function_requires<detail::RandomAccessIteratorIsMutableConcept
0410             <
0411                 typename View::template axis<0>::iterator
0412             >>();
0413 
0414         gil_function_requires<detail::RandomAccessIteratorIsMutableConcept
0415             <
0416                 typename View::template axis<View::num_dimensions - 1>::iterator
0417             >>();
0418 
0419         typename View::difference_type diff;
0420         initialize_it(diff);
0421         ignore_unused_variable_warning(diff);
0422 
0423         typename View::point_t pt;
0424         typename View::value_type v;
0425         initialize_it(v);
0426 
0427         view[diff] = v;
0428         view(pt) = v;
0429     }
0430     View view;
0431 };
0432 
0433 /// \tparam View Models RandomAccessNDImageViewConcept
0434 template <typename View>
0435 struct RandomAccess2DImageViewIsMutableConcept
0436 {
0437     void constraints()
0438     {
0439         gil_function_requires<detail::RandomAccessNDImageViewIsMutableConcept<View>>();
0440         typename View::x_coord_t xd = 0; ignore_unused_variable_warning(xd);
0441         typename View::y_coord_t yd = 0; ignore_unused_variable_warning(yd);
0442         typename View::value_type v; initialize_it(v);
0443         view(xd, yd) = v;
0444     }
0445     View view;
0446 };
0447 
0448 /// \tparam View Models ImageViewConcept
0449 template <typename View>
0450 struct PixelImageViewIsMutableConcept
0451 {
0452     void constraints()
0453     {
0454         gil_function_requires<detail::RandomAccess2DImageViewIsMutableConcept<View>>();
0455     }
0456 };
0457 
0458 } // namespace detail
0459 
0460 /// \ingroup ImageViewNDConcept
0461 /// \brief N-dimensional view over mutable values
0462 ///
0463 /// \code
0464 /// concept MutableRandomAccessNDImageViewConcept<RandomAccessNDImageViewConcept View>
0465 /// {
0466 ///     where Mutable<reference>;
0467 /// };
0468 /// \endcode
0469 template <typename View>
0470 struct MutableRandomAccessNDImageViewConcept
0471 {
0472     void constraints()
0473     {
0474         gil_function_requires<RandomAccessNDImageViewConcept<View>>();
0475         gil_function_requires<detail::RandomAccessNDImageViewIsMutableConcept<View>>();
0476     }
0477 };
0478 
0479 /// \ingroup ImageView2DConcept
0480 /// \brief 2-dimensional view over mutable values
0481 ///
0482 /// \code
0483 /// concept MutableRandomAccess2DImageViewConcept<RandomAccess2DImageViewConcept View>
0484 ///     : MutableRandomAccessNDImageViewConcept<View> {};
0485 /// \endcode
0486 template <typename View>
0487 struct MutableRandomAccess2DImageViewConcept
0488 {
0489     void constraints()
0490     {
0491         gil_function_requires<RandomAccess2DImageViewConcept<View>>();
0492         gil_function_requires<detail::RandomAccess2DImageViewIsMutableConcept<View>>();
0493     }
0494 };
0495 
0496 /// \ingroup PixelImageViewConcept
0497 /// \brief GIL's 2-dimensional view over mutable GIL pixels
0498 ///
0499 /// \code
0500 /// concept MutableImageViewConcept<ImageViewConcept View>
0501 ///     : MutableRandomAccess2DImageViewConcept<View> {};
0502 /// \endcode
0503 template <typename View>
0504 struct MutableImageViewConcept
0505 {
0506     void constraints()
0507     {
0508         gil_function_requires<ImageViewConcept<View>>();
0509         gil_function_requires<detail::PixelImageViewIsMutableConcept<View>>();
0510     }
0511 };
0512 
0513 /// \brief Returns whether two views are compatible
0514 ///
0515 /// Views are compatible if their pixels are compatible.
0516 /// Compatible views can be assigned and copy constructed from one another.
0517 ///
0518 /// \tparam V1 Models ImageViewConcept
0519 /// \tparam V2 Models ImageViewConcept
0520 ///
0521 template <typename V1, typename V2>
0522 struct views_are_compatible
0523     : pixels_are_compatible<typename V1::value_type, typename V2::value_type>
0524 {
0525 };
0526 
0527 /// \ingroup ImageViewConcept
0528 /// \brief Views are compatible if they have the same color spaces and compatible channel values.
0529 ///
0530 /// Constness and layout are not important for compatibility.
0531 ///
0532 /// \code
0533 /// concept ViewsCompatibleConcept<ImageViewConcept V1, ImageViewConcept V2>
0534 /// {
0535 ///     where PixelsCompatibleConcept<V1::value_type, P2::value_type>;
0536 /// };
0537 /// \endcode
0538 template <typename V1, typename V2>
0539 struct ViewsCompatibleConcept
0540 {
0541     void constraints()
0542     {
0543         static_assert(views_are_compatible<V1, V2>::value, "");
0544     }
0545 };
0546 
0547 }} // namespace boost::gil
0548 
0549 #if defined(BOOST_CLANG)
0550 #pragma clang diagnostic pop
0551 #endif
0552 
0553 #if defined(BOOST_GCC) && (BOOST_GCC >= 40900)
0554 #pragma GCC diagnostic pop
0555 #endif
0556 
0557 #endif