Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2024-11-15 09:12:37

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_BIT_ALIGNED_PIXEL_ITERATOR_HPP
0009 #define BOOST_GIL_BIT_ALIGNED_PIXEL_ITERATOR_HPP
0010 
0011 #include <boost/gil/bit_aligned_pixel_reference.hpp>
0012 #include <boost/gil/pixel_iterator.hpp>
0013 
0014 #include <boost/config.hpp>
0015 #include <boost/iterator/iterator_facade.hpp>
0016 
0017 #include <functional>
0018 #include <type_traits>
0019 
0020 namespace boost { namespace gil {
0021 
0022 /// A model of a heterogeneous pixel that is not byte aligned.
0023 /// Examples are bitmap (1-bit pixels) or 6-bit RGB (222).
0024 
0025 /// \defgroup PixelIteratorNonAlignedPixelIterator bit_aligned_pixel_iterator
0026 /// \ingroup PixelIteratorModel
0027 /// \brief An iterator over non-byte-aligned pixels. Models PixelIteratorConcept, PixelBasedConcept, MemoryBasedIteratorConcept, HasDynamicXStepTypeConcept
0028 
0029 ////////////////////////////////////////////////////////////////////////////////////////
0030 /// \brief An iterator over non-byte-aligned pixels. Models PixelIteratorConcept, PixelBasedConcept, MemoryBasedIteratorConcept, HasDynamicXStepTypeConcept
0031 ///
0032 /// An iterator over pixels that correspond to non-byte-aligned bit ranges. Examples of such pixels are single bit grayscale pixel, or a 6-bit RGB 222 pixel.
0033 ///
0034 /// \ingroup PixelIteratorNonAlignedPixelIterator PixelBasedModel
0035 
0036 template <typename NonAlignedPixelReference>
0037 struct bit_aligned_pixel_iterator : public iterator_facade<bit_aligned_pixel_iterator<NonAlignedPixelReference>,
0038                                                   typename NonAlignedPixelReference::value_type,
0039                                                   std::random_access_iterator_tag,
0040                                                   const NonAlignedPixelReference,
0041                                                   typename NonAlignedPixelReference::bit_range_t::difference_type> {
0042 private:
0043     using parent_t = iterator_facade<bit_aligned_pixel_iterator<NonAlignedPixelReference>,
0044                             typename NonAlignedPixelReference::value_type,
0045                             std::random_access_iterator_tag,
0046                             const NonAlignedPixelReference,
0047                             typename NonAlignedPixelReference::bit_range_t::difference_type>;
0048     template <typename Ref> friend struct bit_aligned_pixel_iterator;
0049 
0050     using bit_range_t = typename NonAlignedPixelReference::bit_range_t;
0051 public:
0052     using difference_type = typename parent_t::difference_type;
0053     using reference = typename parent_t::reference;
0054 
0055     bit_aligned_pixel_iterator() {}
0056     bit_aligned_pixel_iterator(const bit_aligned_pixel_iterator& p) : _bit_range(p._bit_range) {}
0057     bit_aligned_pixel_iterator& operator=(const bit_aligned_pixel_iterator& p) { _bit_range=p._bit_range; return *this; }
0058 
0059     template <typename Ref> bit_aligned_pixel_iterator(const bit_aligned_pixel_iterator<Ref>& p) : _bit_range(p._bit_range) {}
0060 
0061     bit_aligned_pixel_iterator(reference* ref) : _bit_range(ref->bit_range()) {}
0062     explicit bit_aligned_pixel_iterator(typename bit_range_t::byte_t* data, int bit_offset=0) : _bit_range(data,bit_offset) {}
0063 
0064     /// For some reason operator[] provided by iterator_adaptor returns a custom class that is convertible to reference
0065     /// We require our own reference because it is registered in iterator_traits
0066     auto operator[](difference_type d) const -> reference { bit_aligned_pixel_iterator it=*this; it.advance(d); return *it; }
0067 
0068     auto operator->() const -> reference { return **this; }
0069     auto bit_range() const -> bit_range_t const& { return _bit_range; }
0070     auto bit_range() -> bit_range_t& { return _bit_range; }
0071 private:
0072     bit_range_t _bit_range;
0073     static constexpr int bit_size = NonAlignedPixelReference::bit_size;
0074 
0075     friend class boost::iterator_core_access;
0076     auto dereference() const -> reference { return NonAlignedPixelReference(_bit_range); }
0077     void increment()                  { ++_bit_range; }
0078     void decrement()                  { --_bit_range; }
0079     void advance(difference_type d)   { _bit_range.bit_advance(d*bit_size); }
0080 
0081     auto distance_to(bit_aligned_pixel_iterator const& it) const -> difference_type { return _bit_range.bit_distance_to(it._bit_range) / bit_size; }
0082     bool equal(const bit_aligned_pixel_iterator& it) const { return _bit_range==it._bit_range; }
0083 };
0084 
0085 template <typename NonAlignedPixelReference>
0086 struct const_iterator_type<bit_aligned_pixel_iterator<NonAlignedPixelReference>>
0087 {
0088     using type =
0089         bit_aligned_pixel_iterator<typename NonAlignedPixelReference::const_reference>;
0090 };
0091 
0092 template <typename NonAlignedPixelReference>
0093 struct iterator_is_mutable<bit_aligned_pixel_iterator<NonAlignedPixelReference>>
0094     : std::integral_constant<bool, NonAlignedPixelReference::is_mutable>
0095 {};
0096 
0097 template <typename NonAlignedPixelReference>
0098 struct is_iterator_adaptor<bit_aligned_pixel_iterator<NonAlignedPixelReference>>
0099     : std::false_type
0100 {};
0101 
0102 /////////////////////////////
0103 //  PixelBasedConcept
0104 /////////////////////////////
0105 
0106 template <typename NonAlignedPixelReference>
0107 struct color_space_type<bit_aligned_pixel_iterator<NonAlignedPixelReference> > : public color_space_type<NonAlignedPixelReference> {};
0108 
0109 template <typename NonAlignedPixelReference>
0110 struct channel_mapping_type<bit_aligned_pixel_iterator<NonAlignedPixelReference> > : public channel_mapping_type<NonAlignedPixelReference> {};
0111 
0112 template <typename NonAlignedPixelReference>
0113 struct is_planar<bit_aligned_pixel_iterator<NonAlignedPixelReference> > : public is_planar<NonAlignedPixelReference> {}; // == false
0114 
0115 /////////////////////////////
0116 //  MemoryBasedIteratorConcept
0117 /////////////////////////////
0118 
0119 template <typename NonAlignedPixelReference>
0120 struct byte_to_memunit<bit_aligned_pixel_iterator<NonAlignedPixelReference>>
0121     : std::integral_constant<int, 8>
0122 {};
0123 
0124 template <typename NonAlignedPixelReference>
0125 inline auto memunit_step(const bit_aligned_pixel_iterator<NonAlignedPixelReference>&) -> std::ptrdiff_t
0126 {
0127     return NonAlignedPixelReference::bit_size;
0128 }
0129 
0130 template <typename NonAlignedPixelReference>
0131 inline auto memunit_distance(bit_aligned_pixel_iterator<NonAlignedPixelReference> const& p1, bit_aligned_pixel_iterator<NonAlignedPixelReference> const& p2) -> std::ptrdiff_t
0132 {
0133     return (p2.bit_range().current_byte() - p1.bit_range().current_byte())*8 + p2.bit_range().bit_offset() - p1.bit_range().bit_offset();
0134 }
0135 
0136 template <typename NonAlignedPixelReference>
0137 inline void memunit_advance(bit_aligned_pixel_iterator<NonAlignedPixelReference>& p, std::ptrdiff_t diff) {
0138     p.bit_range().bit_advance(diff);
0139 }
0140 
0141 template <typename NonAlignedPixelReference>
0142 inline auto memunit_advanced(bit_aligned_pixel_iterator<NonAlignedPixelReference> const& p, std::ptrdiff_t diff) -> bit_aligned_pixel_iterator<NonAlignedPixelReference> {
0143     bit_aligned_pixel_iterator<NonAlignedPixelReference> ret=p;
0144     memunit_advance(ret, diff);
0145     return ret;
0146 }
0147 
0148 template <typename NonAlignedPixelReference> inline
0149 auto memunit_advanced_ref(bit_aligned_pixel_iterator<NonAlignedPixelReference> it, std::ptrdiff_t diff) -> NonAlignedPixelReference
0150 {
0151     return *memunit_advanced(it,diff);
0152 }
0153 /////////////////////////////
0154 //  HasDynamicXStepTypeConcept
0155 /////////////////////////////
0156 
0157 template <typename NonAlignedPixelReference>
0158 struct dynamic_x_step_type<bit_aligned_pixel_iterator<NonAlignedPixelReference> > {
0159     using type = memory_based_step_iterator<bit_aligned_pixel_iterator<NonAlignedPixelReference> >;
0160 };
0161 
0162 /////////////////////////////
0163 //  iterator_type_from_pixel
0164 /////////////////////////////
0165 
0166 template <typename B, typename C, typename L, bool M>
0167 struct iterator_type_from_pixel<const bit_aligned_pixel_reference<B,C,L,M>,false,false,false>
0168 {
0169     using type = bit_aligned_pixel_iterator<bit_aligned_pixel_reference<B,C,L,false>> ;
0170 };
0171 
0172 template <typename B, typename C, typename L, bool M>
0173 struct iterator_type_from_pixel<const bit_aligned_pixel_reference<B,C,L,M>,false,false,true>
0174 {
0175     using type = bit_aligned_pixel_iterator<bit_aligned_pixel_reference<B,C,L,true>>;
0176 };
0177 
0178 template <typename B, typename C, typename L, bool M, bool IsPlanar, bool IsStep, bool IsMutable>
0179 struct iterator_type_from_pixel<bit_aligned_pixel_reference<B,C,L,M>,IsPlanar,IsStep,IsMutable>
0180     : public iterator_type_from_pixel<const bit_aligned_pixel_reference<B,C,L,M>,IsPlanar,IsStep,IsMutable> {};
0181 
0182 } }  // namespace boost::gil
0183 
0184 namespace std {
0185 
0186 // It is important to provide an overload of uninitialized_copy for bit_aligned_pixel_iterator. The default STL implementation calls placement new,
0187 // which is not defined for bit_aligned_pixel_iterator.
0188 template <typename NonAlignedPixelReference>
0189 auto uninitialized_copy(boost::gil::bit_aligned_pixel_iterator<NonAlignedPixelReference> first,
0190     boost::gil::bit_aligned_pixel_iterator<NonAlignedPixelReference> last,
0191     boost::gil::bit_aligned_pixel_iterator<NonAlignedPixelReference> dst)
0192     -> boost::gil::bit_aligned_pixel_iterator<NonAlignedPixelReference>
0193 {
0194     return std::copy(first,last,dst);
0195 }
0196 
0197 } // namespace std
0198 
0199 #endif