Boost GIL


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(),
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 
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 
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
BOOST_FORCEINLINE auto apply_operation(variant< Types > &arg, UnaryOp op)
Invokes a generic mutable operation (represented as a unary function object) on a variant.
Definition: apply_operation.hpp:21
void swap(boost::gil::packed_channel_reference< BF, FB, NB, M > const x, R &y)
swap for packed_channel_reference
Definition: channel.hpp:529