2 // Copyright 2007-2008 Christian Henning, Andreas Pokorny, Lubomir Bourdev
4 // Distributed under the Boost Software License, Version 1.0
5 // See accompanying file LICENSE_1_0.txt or copy at
6 // http://www.boost.org/LICENSE_1_0.txt
8 #ifndef BOOST_GIL_IO_BIT_OPERATIONS_HPP
9 #define BOOST_GIL_IO_BIT_OPERATIONS_HPP
11 #include <boost/gil/io/typedefs.hpp>
15 #include <type_traits>
17 namespace boost { namespace gil { namespace detail {
19 // 1110 1100 -> 0011 0111
20 template <typename Buffer, typename IsBitAligned>
25 void operator()(Buffer&) {}
26 void operator()(byte_t*, std::size_t){}
29 // The functor will generate a lookup table since the
30 // mirror operation is quite costly.
31 template <typename Buffer>
32 struct mirror_bits<Buffer, std::true_type>
34 mirror_bits(bool apply_operation = true)
35 : apply_operation_(apply_operation)
42 lookup_[i] = mirror(i);
48 void operator()(Buffer& buffer)
51 for_each(buffer.begin(), buffer.end(), [this](byte_t& c) { lookup(c); });
54 void operator()(byte_t *dst, std::size_t size)
56 for (std::size_t i = 0; i < size; ++i)
65 void lookup(byte_t& c)
70 static byte_t mirror(byte_t c)
73 for (int i = 0; i < 8; ++i)
83 std::array<byte_t, 256> lookup_;
84 bool apply_operation_;
88 // 0011 1111 -> 1100 0000
89 template <typename Buffer, typename IsBitAligned>
92 void operator()(Buffer&) {};
95 template <typename Buffer>
96 struct negate_bits<Buffer, std::true_type>
98 void operator()(Buffer& buffer)
100 for_each(buffer.begin(), buffer.end(),
101 negate_bits<Buffer, std::true_type>::negate);
104 void operator()(byte_t* dst, std::size_t size)
106 for (std::size_t i = 0; i < size; ++i)
115 static void negate(byte_t& b)
121 // 11101100 -> 11001110
122 template <typename Buffer, typename IsBitAligned>
123 struct swap_half_bytes
125 void operator()(Buffer&) {};
128 template <typename Buffer>
129 struct swap_half_bytes<Buffer, std::true_type>
131 void operator()(Buffer& buffer)
133 for_each(buffer.begin(), buffer.end(),
134 swap_half_bytes<Buffer, std::true_type>::swap);
137 void operator()(byte_t* dst, std::size_t size)
139 for (std::size_t i = 0; i < size; ++i)
148 static void swap(byte_t& c)
150 c = ((c << 4) & 0xF0) | ((c >> 4) & 0x0F);
154 template <typename Buffer>
157 do_nothing() = default;
159 void operator()(Buffer&) {}
162 /// Count consecutive zeros on the right
163 template <typename T>
164 inline unsigned int trailing_zeros(T x) noexcept
178 /// Counts ones in a bit-set
179 template <typename T>
181 unsigned int count_ones(T x) noexcept
187 // clear the least significant bit set
195 }}} // namespace boost::gil::detail