Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-15 09:52:11

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_PLANAR_PIXEL_ITERATOR_HPP
0009 #define BOOST_GIL_PLANAR_PIXEL_ITERATOR_HPP
0010 
0011 #include <boost/gil/pixel.hpp>
0012 #include <boost/gil/step_iterator.hpp>
0013 #include <boost/gil/detail/mp11.hpp>
0014 
0015 #include <boost/iterator/iterator_facade.hpp>
0016 
0017 #include <iterator>
0018 #include <type_traits>
0019 
0020 namespace boost { namespace gil {
0021 
0022 //forward declaration (as this file is included in planar_pixel_reference.hpp)
0023 template <typename ChannelReference, typename ColorSpace>
0024 struct planar_pixel_reference;
0025 
0026 /// \defgroup ColorBaseModelPlanarPtr planar_pixel_iterator
0027 /// \ingroup ColorBaseModel
0028 /// \brief A homogeneous color base whose element is a channel iterator. Models HomogeneousColorBaseValueConcept
0029 /// This class is used as an iterator to a planar pixel.
0030 
0031 /// \defgroup PixelIteratorModelPlanarPtr planar_pixel_iterator
0032 /// \ingroup PixelIteratorModel
0033 /// \brief An iterator over planar pixels. Models PixelIteratorConcept, HomogeneousPixelBasedConcept, MemoryBasedIteratorConcept, HasDynamicXStepTypeConcept
0034 
0035 ////////////////////////////////////////////////////////////////////////////////////////
0036 /// \brief An iterator over planar pixels. Models HomogeneousColorBaseConcept, PixelIteratorConcept, HomogeneousPixelBasedConcept, MemoryBasedIteratorConcept, HasDynamicXStepTypeConcept
0037 ///
0038 /// Planar pixels have channel data that is not consecutive in memory.
0039 /// To abstract this we use classes to represent references and pointers to planar pixels.
0040 ///
0041 /// \ingroup PixelIteratorModelPlanarPtr ColorBaseModelPlanarPtr PixelBasedModel
0042 template <typename ChannelPtr, typename ColorSpace>
0043 struct planar_pixel_iterator
0044     :
0045     iterator_facade
0046     <
0047         planar_pixel_iterator<ChannelPtr, ColorSpace>,
0048         pixel<typename std::iterator_traits<ChannelPtr>::value_type,layout<ColorSpace>>,
0049         std::random_access_iterator_tag,
0050         planar_pixel_reference<typename std::iterator_traits<ChannelPtr>::reference, ColorSpace> const
0051     >,
0052     detail::homogeneous_color_base
0053     <
0054         ChannelPtr,
0055         layout<ColorSpace>,
0056         mp11::mp_size<ColorSpace>::value
0057     >
0058 {
0059 private:
0060     using parent_t = iterator_facade
0061         <
0062             planar_pixel_iterator<ChannelPtr, ColorSpace>,
0063             pixel<typename std::iterator_traits<ChannelPtr>::value_type,layout<ColorSpace>>,
0064             std::random_access_iterator_tag,
0065             planar_pixel_reference<typename std::iterator_traits<ChannelPtr>::reference, ColorSpace> const
0066         >;
0067 
0068     using color_base_parent_t = detail::homogeneous_color_base
0069         <
0070             ChannelPtr,
0071             layout<ColorSpace>,
0072             mp11::mp_size<ColorSpace>::value
0073         >;
0074 
0075     using channel_t = typename std::iterator_traits<ChannelPtr>::value_type;
0076 
0077 public:
0078     using value_type = typename parent_t::value_type;
0079     using reference = typename parent_t::reference;
0080     using difference_type = typename parent_t::difference_type;
0081 
0082     planar_pixel_iterator() : color_base_parent_t(0) {}
0083     planar_pixel_iterator(bool) {}        // constructor that does not fill with zero (for performance)
0084 
0085     planar_pixel_iterator(const ChannelPtr& v0, const ChannelPtr& v1) : color_base_parent_t(v0,v1) {}
0086     planar_pixel_iterator(const ChannelPtr& v0, const ChannelPtr& v1, const ChannelPtr& v2) : color_base_parent_t(v0,v1,v2) {}
0087     planar_pixel_iterator(const ChannelPtr& v0, const ChannelPtr& v1, const ChannelPtr& v2, const ChannelPtr& v3) : color_base_parent_t(v0,v1,v2,v3) {}
0088     planar_pixel_iterator(const ChannelPtr& v0, const ChannelPtr& v1, const ChannelPtr& v2, const ChannelPtr& v3, const ChannelPtr& v4) : color_base_parent_t(v0,v1,v2,v3,v4) {}
0089 
0090     template <typename IC1,typename C1>
0091     planar_pixel_iterator(const planar_pixel_iterator<IC1,C1>& ptr) : color_base_parent_t(ptr) {}
0092 
0093     /// Copy constructor and operator= from pointers to compatible planar pixels or planar pixel references.
0094     /// That allow constructs like pointer = &value or pointer = &reference
0095     /// Since we should not override operator& that's the best we can do.
0096     template <typename P>
0097     planar_pixel_iterator(P* pix) : color_base_parent_t(pix, true) {
0098         function_requires<PixelsCompatibleConcept<P,value_type> >();
0099     }
0100 
0101     struct address_of { template <typename T> T* operator()(T& t) { return &t; } };
0102     template <typename P>
0103     planar_pixel_iterator& operator=(P* pix) {
0104         function_requires<PixelsCompatibleConcept<P,value_type> >();
0105         static_transform(*pix,*this, address_of());
0106 
0107         // PERFORMANCE_CHECK: Compare to this:
0108         //this->template semantic_at_c<0>()=&pix->template semantic_at_c<0>();
0109         //this->template semantic_at_c<1>()=&pix->template semantic_at_c<1>();
0110         //this->template semantic_at_c<2>()=&pix->template semantic_at_c<2>();
0111         return *this;
0112     }
0113 
0114     /// For some reason operator[] provided by iterator_facade returns a custom class that is convertible to reference
0115     /// We require our own reference because it is registered in iterator_traits
0116     reference operator[](difference_type d)       const { return memunit_advanced_ref(*this,d*sizeof(channel_t));}
0117 
0118     reference operator->()                        const { return **this; }
0119 
0120     // PERFORMANCE_CHECK: Remove?
0121     bool operator< (const planar_pixel_iterator& ptr)   const { return gil::at_c<0>(*this)< gil::at_c<0>(ptr); }
0122     bool operator!=(const planar_pixel_iterator& ptr)   const { return gil::at_c<0>(*this)!=gil::at_c<0>(ptr); }
0123 private:
0124     friend class boost::iterator_core_access;
0125 
0126     void increment()            { static_transform(*this,*this,detail::inc<ChannelPtr>()); }
0127     void decrement()            { static_transform(*this,*this,detail::dec<ChannelPtr>()); }
0128     void advance(std::ptrdiff_t d){ static_transform(*this,*this,std::bind(detail::plus_asymmetric<ChannelPtr,std::ptrdiff_t>(),std::placeholders::_1,d)); }
0129     reference dereference() const { return this->template deref<reference>(); }
0130 
0131     std::ptrdiff_t distance_to(const planar_pixel_iterator& it) const { return gil::at_c<0>(it)-gil::at_c<0>(*this); }
0132     bool equal(const planar_pixel_iterator& it) const { return gil::at_c<0>(*this)==gil::at_c<0>(it); }
0133 };
0134 
0135 namespace detail {
0136 template <typename I>
0137 struct channel_iterator_is_mutable : std::true_type {};
0138 
0139 template <typename I>
0140 struct channel_iterator_is_mutable<I const*> : std::false_type {};
0141 
0142 } // namespace detail
0143 
0144 template <typename IC, typename C>
0145 struct const_iterator_type<planar_pixel_iterator<IC,C> > {
0146 private:
0147     using channel_t = typename std::iterator_traits<IC>::value_type;
0148 public:
0149     using type = planar_pixel_iterator<typename channel_traits<channel_t>::const_pointer,C>;
0150 };
0151 
0152 // The default implementation when the iterator is a C pointer is to use the standard constness semantics
0153 template <typename IC, typename C>
0154 struct iterator_is_mutable<planar_pixel_iterator<IC,C> > : public detail::channel_iterator_is_mutable<IC> {};
0155 
0156 /////////////////////////////
0157 //  ColorBasedConcept
0158 /////////////////////////////
0159 
0160 template <typename IC, typename C, int K>
0161 struct kth_element_type<planar_pixel_iterator<IC, C>, K>
0162 {
0163     using type = IC;
0164 };
0165 
0166 template <typename IC, typename C, int K>
0167 struct kth_element_reference_type<planar_pixel_iterator<IC, C>, K>
0168     : std::add_lvalue_reference<IC> {};
0169 
0170 template <typename IC, typename C, int K>
0171 struct kth_element_const_reference_type<planar_pixel_iterator<IC, C>, K>
0172     : std::add_lvalue_reference<typename std::add_const<IC>::type>
0173 {};
0174 
0175 /////////////////////////////
0176 //  HomogeneousPixelBasedConcept
0177 /////////////////////////////
0178 
0179 template <typename IC, typename C>
0180 struct color_space_type<planar_pixel_iterator<IC,C>>
0181 {
0182     using type = C;
0183 };
0184 
0185 template <typename IC, typename C>
0186 struct channel_mapping_type<planar_pixel_iterator<IC, C>>
0187     : channel_mapping_type<typename planar_pixel_iterator<IC,C>::value_type>
0188 {};
0189 
0190 template <typename IC, typename C>
0191 struct is_planar<planar_pixel_iterator<IC, C>> : std::true_type {};
0192 
0193 template <typename IC, typename C>
0194 struct channel_type<planar_pixel_iterator<IC, C>>
0195 {
0196     using type = typename std::iterator_traits<IC>::value_type;
0197 };
0198 
0199 /////////////////////////////
0200 //  MemoryBasedIteratorConcept
0201 /////////////////////////////
0202 
0203 template <typename IC, typename C>
0204 inline auto memunit_step(planar_pixel_iterator<IC,C> const&)
0205     -> std::ptrdiff_t
0206 {
0207     return sizeof(typename std::iterator_traits<IC>::value_type);
0208 }
0209 
0210 template <typename IC, typename C>
0211 inline auto memunit_distance(planar_pixel_iterator<IC,C> const& p1, planar_pixel_iterator<IC,C> const& p2)
0212     -> std::ptrdiff_t
0213 {
0214     return memunit_distance(gil::at_c<0>(p1),gil::at_c<0>(p2));
0215 }
0216 
0217 template <typename IC>
0218 struct memunit_advance_fn {
0219     memunit_advance_fn(std::ptrdiff_t diff) : _diff(diff) {}
0220     IC operator()(const IC& p) const { return memunit_advanced(p,_diff); }
0221 
0222     std::ptrdiff_t _diff;
0223 };
0224 
0225 template <typename IC, typename C>
0226 inline void memunit_advance(planar_pixel_iterator<IC,C>& p, std::ptrdiff_t diff) {
0227     static_transform(p, p, memunit_advance_fn<IC>(diff));
0228 }
0229 
0230 template <typename IC, typename C>
0231 inline auto memunit_advanced(planar_pixel_iterator<IC,C> const& p, std::ptrdiff_t diff)
0232     -> planar_pixel_iterator<IC,C>
0233 {
0234     planar_pixel_iterator<IC,C> ret=p;
0235     memunit_advance(ret, diff);
0236     return ret;
0237 }
0238 
0239 template <typename ChannelPtr, typename ColorSpace>
0240 inline auto memunit_advanced_ref(planar_pixel_iterator<ChannelPtr,ColorSpace> const& ptr, std::ptrdiff_t diff)
0241     -> planar_pixel_reference<typename std::iterator_traits<ChannelPtr>::reference,ColorSpace>
0242 {
0243     return planar_pixel_reference<typename std::iterator_traits<ChannelPtr>::reference,ColorSpace>(ptr, diff);
0244 }
0245 
0246 /////////////////////////////
0247 //  HasDynamicXStepTypeConcept
0248 /////////////////////////////
0249 
0250 template <typename IC, typename C>
0251 struct dynamic_x_step_type<planar_pixel_iterator<IC,C> > {
0252     using type = memory_based_step_iterator<planar_pixel_iterator<IC,C>>;
0253 };
0254 } }  // namespace boost::gil
0255 
0256 #endif