Back to home page

EIC code displayed by LXR

 
 

    


Warning, file /include/boost/gil/io/bit_operations.hpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 //
0002 // Copyright 2007-2008 Christian Henning, Andreas Pokorny, Lubomir Bourdev
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_IO_BIT_OPERATIONS_HPP
0009 #define BOOST_GIL_IO_BIT_OPERATIONS_HPP
0010 
0011 #include <boost/gil/io/typedefs.hpp>
0012 
0013 #include <array>
0014 #include <cstddef>
0015 #include <type_traits>
0016 
0017 namespace boost { namespace gil { namespace detail {
0018 
0019 // 1110 1100 -> 0011 0111
0020 template <typename Buffer, typename IsBitAligned>
0021 struct mirror_bits
0022 {
0023     mirror_bits(bool) {};
0024 
0025     void operator()(Buffer&) {}
0026     void operator()(byte_t*, std::size_t){}
0027 };
0028 
0029 // The functor will generate a lookup table since the
0030 // mirror operation is quite costly.
0031 template <typename Buffer>
0032 struct mirror_bits<Buffer, std::true_type>
0033 {
0034     mirror_bits(bool apply_operation = true)
0035         : apply_operation_(apply_operation)
0036     {
0037         if(apply_operation_)
0038         {
0039             byte_t i = 0;
0040             do
0041             {
0042                 lookup_[i] = mirror(i);
0043             }
0044             while (i++ != 255);
0045         }
0046    }
0047 
0048     void operator()(Buffer& buffer)
0049     {
0050         if (apply_operation_)
0051             for_each(buffer.begin(), buffer.end(), [this](byte_t& c) { lookup(c); });
0052     }
0053 
0054     void operator()(byte_t *dst, std::size_t size)
0055     {
0056         for (std::size_t i = 0; i < size; ++i)
0057         {
0058             lookup(*dst);
0059             ++dst;
0060         }
0061     }
0062 
0063 private:
0064 
0065     void lookup(byte_t& c)
0066     {
0067         c = lookup_[c];
0068     }
0069 
0070     static byte_t mirror(byte_t c)
0071     {
0072         byte_t result = 0;
0073         for (int i = 0; i < 8; ++i)
0074         {
0075             result = result << 1;
0076             result |= (c & 1);
0077             c = c >> 1;
0078         }
0079 
0080         return result;
0081     }
0082 
0083     std::array<byte_t, 256> lookup_;
0084     bool apply_operation_;
0085 
0086 };
0087 
0088 // 0011 1111 -> 1100 0000
0089 template <typename Buffer, typename IsBitAligned>
0090 struct negate_bits
0091 {
0092     void operator()(Buffer&) {};
0093 };
0094 
0095 template <typename Buffer>
0096 struct negate_bits<Buffer, std::true_type>
0097 {
0098     void operator()(Buffer& buffer)
0099     {
0100         for_each(buffer.begin(), buffer.end(),
0101             negate_bits<Buffer, std::true_type>::negate);
0102     }
0103 
0104     void operator()(byte_t* dst, std::size_t size)
0105     {
0106         for (std::size_t i = 0; i < size; ++i)
0107         {
0108             negate(*dst);
0109             ++dst;
0110         }
0111     }
0112 
0113 private:
0114 
0115     static void negate(byte_t& b)
0116     {
0117         b = ~b;
0118     }
0119 };
0120 
0121 // 11101100 -> 11001110
0122 template <typename Buffer, typename IsBitAligned>
0123 struct swap_half_bytes
0124 {
0125     void operator()(Buffer&) {};
0126 };
0127 
0128 template <typename Buffer>
0129 struct swap_half_bytes<Buffer, std::true_type>
0130 {
0131     void operator()(Buffer& buffer)
0132     {
0133         for_each(buffer.begin(), buffer.end(),
0134             swap_half_bytes<Buffer, std::true_type>::swap);
0135     }
0136 
0137     void operator()(byte_t* dst, std::size_t size)
0138     {
0139         for (std::size_t i = 0; i < size; ++i)
0140         {
0141             swap(*dst);
0142             ++dst;
0143         }
0144     }
0145 
0146 private:
0147 
0148     static void swap(byte_t& c)
0149     {
0150         c = ((c << 4) & 0xF0) | ((c >> 4) & 0x0F);
0151     }
0152 };
0153 
0154 template <typename Buffer>
0155 struct do_nothing
0156 {
0157    do_nothing() = default;
0158 
0159    void operator()(Buffer&) {}
0160 };
0161 
0162 /// Count consecutive zeros on the right
0163 template <typename T>
0164 inline unsigned int trailing_zeros(T x) noexcept
0165 {
0166     unsigned int n = 0;
0167 
0168     x = ~x & (x - 1);
0169     while (x)
0170     {
0171         n = n + 1;
0172         x = x >> 1;
0173     }
0174 
0175     return n;
0176 }
0177 
0178 /// Counts ones in a bit-set
0179 template <typename T>
0180 inline
0181 unsigned int count_ones(T x) noexcept
0182 {
0183     unsigned int n = 0;
0184 
0185     while (x)
0186     {
0187         // clear the least significant bit set
0188         x &= x - 1;
0189         ++n;
0190     }
0191 
0192     return n;
0193 }
0194 
0195 }}} // namespace boost::gil::detail
0196 
0197 #endif