comparison mupdf-source/thirdparty/zxing-cpp/core/src/BitArray.h @ 2:b50eed0cc0ef upstream

ADD: MuPDF v1.26.7: the MuPDF source as downloaded by a default build of PyMuPDF 1.26.4. The directory name has changed: no version number in the expanded directory now.
author Franz Glasner <fzglas.hg@dom66.de>
date Mon, 15 Sep 2025 11:43:07 +0200
parents
children
comparison
equal deleted inserted replaced
1:1d09e1dec1d9 2:b50eed0cc0ef
1 /*
2 * Copyright 2016 Nu-book Inc.
3 * Copyright 2016 ZXing authors
4 * Copyright 2017 Axel Waggershauser
5 */
6 // SPDX-License-Identifier: Apache-2.0
7
8 #pragma once
9
10 #include "Range.h"
11 #include "ZXAlgorithms.h"
12
13 #include <algorithm>
14 #include <cassert>
15 #include <cstdint>
16 #include <stdexcept>
17 #include <type_traits>
18 #include <vector>
19
20 namespace ZXing {
21
22 class ByteArray;
23
24 /**
25 * A simple, fast array of bits.
26 */
27 class BitArray
28 {
29 std::vector<uint8_t> _bits;
30
31 friend class BitMatrix;
32
33 // Nothing wrong to support it, just to make it explicit, instead of by mistake.
34 // Use copy() below.
35 BitArray(const BitArray &) = default;
36 BitArray& operator=(const BitArray &) = delete;
37
38 public:
39
40 using Iterator = std::vector<uint8_t>::const_iterator;
41
42 BitArray() = default;
43
44 explicit BitArray(int size) : _bits(size, 0) {}
45
46 BitArray(BitArray&& other) noexcept = default;
47 BitArray& operator=(BitArray&& other) noexcept = default;
48
49 BitArray copy() const { return *this; }
50
51 int size() const noexcept { return Size(_bits); }
52
53 int sizeInBytes() const noexcept { return (size() + 7) / 8; }
54
55 bool get(int i) const { return _bits.at(i) != 0; }
56 void set(int i, bool val) { _bits.at(i) = val; }
57
58 // If you know exactly how may bits you are going to iterate
59 // and that you access bit in sequence, iterator is faster than get().
60 // However, be extremely careful since there is no check whatsoever.
61 // (Performance is the reason for the iterator to exist in the first place.)
62 Iterator iterAt(int i) const noexcept { return {_bits.cbegin() + i}; }
63 Iterator begin() const noexcept { return _bits.cbegin(); }
64 Iterator end() const noexcept { return _bits.cend(); }
65
66 /**
67 * Appends the least-significant bits, from value, in order from most-significant to
68 * least-significant. For example, appending 6 bits from 0x000001E will append the bits
69 * 0, 1, 1, 1, 1, 0 in that order.
70 *
71 * @param value {@code int} containing bits to append
72 * @param numBits bits from value to append
73 */
74 void appendBits(int value, int numBits)
75 {
76 for (; numBits; --numBits)
77 _bits.push_back((value >> (numBits-1)) & 1);
78 }
79
80 void appendBit(bool bit) { _bits.push_back(bit); }
81
82 void appendBitArray(const BitArray& other) { _bits.insert(_bits.end(), other.begin(), other.end()); }
83
84 /**
85 * Reverses all bits in the array.
86 */
87 void reverse() { std::reverse(_bits.begin(), _bits.end()); }
88
89 void bitwiseXOR(const BitArray& other);
90
91 /**
92 * @param bitOffset first bit to extract
93 * @param numBytes how many bytes to extract (-1 == until the end, padded with '0')
94 * @return Bytes are written most-significant bit first.
95 */
96 ByteArray toBytes(int bitOffset = 0, int numBytes = -1) const;
97
98 using Range = ZXing::Range<Iterator>;
99 Range range() const { return {begin(), end()}; }
100
101 friend bool operator==(const BitArray& a, const BitArray& b) { return a._bits == b._bits; }
102 };
103
104 template<typename T, typename = std::enable_if_t<std::is_integral_v<T>>>
105 T& AppendBit(T& val, bool bit)
106 {
107 return (val <<= 1) |= static_cast<T>(bit);
108 }
109
110 template <typename ARRAY, typename = std::enable_if_t<std::is_integral_v<typename ARRAY::value_type>>>
111 int ToInt(const ARRAY& a)
112 {
113 assert(Reduce(a) <= 32);
114
115 int pattern = 0;
116 for (int i = 0; i < Size(a); i++)
117 pattern = (pattern << a[i]) | ~(0xffffffff << a[i]) * (~i & 1);
118 return pattern;
119 }
120
121 template <typename T = int, typename = std::enable_if_t<std::is_integral_v<T>>>
122 T ToInt(const BitArray& bits, int pos = 0, int count = 8 * sizeof(T))
123 {
124 assert(0 <= count && count <= 8 * (int)sizeof(T));
125 assert(0 <= pos && pos + count <= bits.size());
126
127 count = std::min(count, bits.size());
128 int res = 0;
129 auto it = bits.iterAt(pos);
130 for (int i = 0; i < count; ++i, ++it)
131 AppendBit(res, *it);
132
133 return res;
134 }
135
136 template <typename T = int, typename = std::enable_if_t<std::is_integral_v<T>>>
137 std::vector<T> ToInts(const BitArray& bits, int wordSize, int totalWords, int offset = 0)
138 {
139 assert(totalWords >= bits.size() / wordSize);
140 assert(wordSize <= 8 * (int)sizeof(T));
141
142 std::vector<T> res(totalWords, 0);
143 for (int i = offset; i < bits.size(); i += wordSize)
144 res[(i - offset) / wordSize] = ToInt(bits, i, wordSize);
145
146 return res;
147 }
148
149 class BitArrayView
150 {
151 const BitArray& bits;
152 BitArray::Iterator cur;
153
154 public:
155 BitArrayView(const BitArray& bits) : bits(bits), cur(bits.begin()) {}
156
157 BitArrayView& skipBits(int n)
158 {
159 if (cur + n > bits.end())
160 throw std::out_of_range("BitArrayView::skipBits() out of range.");
161 cur += n;
162 return *this;
163 }
164
165 int peakBits(int n) const
166 {
167 assert(n <= 32);
168 if (cur + n > bits.end())
169 throw std::out_of_range("BitArrayView::peakBits() out of range.");
170 int res = 0;
171 for (auto i = cur; n > 0; --n, i++)
172 AppendBit(res, *i);
173 return res;
174 }
175
176 int readBits(int n)
177 {
178 int res = peakBits(n);
179 cur += n;
180 return res;
181 }
182
183 int size() const
184 {
185 return narrow_cast<int>(bits.end() - cur);
186 }
187
188 explicit operator bool() const { return size(); }
189 };
190
191 } // ZXing