]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/gil/io/bit_operations.hpp
import new upstream nautilus stable release 14.2.8
[ceph.git] / ceph / src / boost / boost / gil / io / bit_operations.hpp
1 //
2 // Copyright 2007-2008 Christian Henning, Andreas Pokorny, Lubomir Bourdev
3 //
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
7 //
8 #ifndef BOOST_GIL_IO_BIT_OPERATIONS_HPP
9 #define BOOST_GIL_IO_BIT_OPERATIONS_HPP
10
11 #include <boost/gil/io/typedefs.hpp>
12
13 #include <array>
14 #include <cstddef>
15 #include <type_traits>
16
17 namespace boost { namespace gil { namespace detail {
18
19 // 1110 1100 -> 0011 0111
20 template <typename Buffer, typename IsBitAligned>
21 struct mirror_bits
22 {
23 mirror_bits(bool) {};
24
25 void operator()(Buffer&) {}
26 void operator()(byte_t*, std::size_t){}
27 };
28
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>
33 {
34 mirror_bits(bool apply_operation = true)
35 : apply_operation_(apply_operation)
36 {
37 if(apply_operation_)
38 {
39 byte_t i = 0;
40 do
41 {
42 lookup_[i] = mirror(i);
43 }
44 while (i++ != 255);
45 }
46 }
47
48 void operator()(Buffer& buffer)
49 {
50 if (apply_operation_)
51 for_each(buffer.begin(), buffer.end(), [this](byte_t& c) { lookup(c); });
52 }
53
54 void operator()(byte_t *dst, std::size_t size)
55 {
56 for (std::size_t i = 0; i < size; ++i)
57 {
58 lookup(*dst);
59 ++dst;
60 }
61 }
62
63 private:
64
65 void lookup(byte_t& c)
66 {
67 c = lookup_[c];
68 }
69
70 static byte_t mirror(byte_t c)
71 {
72 byte_t result = 0;
73 for (int i = 0; i < 8; ++i)
74 {
75 result = result << 1;
76 result |= (c & 1);
77 c = c >> 1;
78 }
79
80 return result;
81 }
82
83 std::array<byte_t, 256> lookup_;
84 bool apply_operation_;
85
86 };
87
88 // 0011 1111 -> 1100 0000
89 template <typename Buffer, typename IsBitAligned>
90 struct negate_bits
91 {
92 void operator()(Buffer&) {};
93 };
94
95 template <typename Buffer>
96 struct negate_bits<Buffer, std::true_type>
97 {
98 void operator()(Buffer& buffer)
99 {
100 for_each(buffer.begin(), buffer.end(),
101 negate_bits<Buffer, std::true_type>::negate);
102 }
103
104 void operator()(byte_t* dst, std::size_t size)
105 {
106 for (std::size_t i = 0; i < size; ++i)
107 {
108 negate(*dst);
109 ++dst;
110 }
111 }
112
113 private:
114
115 static void negate(byte_t& b)
116 {
117 b = ~b;
118 }
119 };
120
121 // 11101100 -> 11001110
122 template <typename Buffer, typename IsBitAligned>
123 struct swap_half_bytes
124 {
125 void operator()(Buffer&) {};
126 };
127
128 template <typename Buffer>
129 struct swap_half_bytes<Buffer, std::true_type>
130 {
131 void operator()(Buffer& buffer)
132 {
133 for_each(buffer.begin(), buffer.end(),
134 swap_half_bytes<Buffer, std::true_type>::swap);
135 }
136
137 void operator()(byte_t* dst, std::size_t size)
138 {
139 for (std::size_t i = 0; i < size; ++i)
140 {
141 swap(*dst);
142 ++dst;
143 }
144 }
145
146 private:
147
148 static void swap(byte_t& c)
149 {
150 c = ((c << 4) & 0xF0) | ((c >> 4) & 0x0F);
151 }
152 };
153
154 template <typename Buffer>
155 struct do_nothing
156 {
157 do_nothing() = default;
158
159 void operator()(Buffer&) {}
160 };
161
162 /// Count consecutive zeros on the right
163 template <typename T>
164 inline unsigned int trailing_zeros(T x) noexcept
165 {
166 unsigned int n = 0;
167
168 x = ~x & (x - 1);
169 while (x)
170 {
171 n = n + 1;
172 x = x >> 1;
173 }
174
175 return n;
176 }
177
178 /// Counts ones in a bit-set
179 template <typename T>
180 inline
181 unsigned int count_ones(T x) noexcept
182 {
183 unsigned int n = 0;
184
185 while (x)
186 {
187 // clear the least significant bit set
188 x &= x - 1;
189 ++n;
190 }
191
192 return n;
193 }
194
195 }}} // namespace boost::gil::detail
196
197 #endif