Mercurial > hgrepos > Python2 > PyMuPDF
diff 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 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mupdf-source/thirdparty/zxing-cpp/core/src/BitArray.h Mon Sep 15 11:43:07 2025 +0200 @@ -0,0 +1,191 @@ +/* +* Copyright 2016 Nu-book Inc. +* Copyright 2016 ZXing authors +* Copyright 2017 Axel Waggershauser +*/ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once + +#include "Range.h" +#include "ZXAlgorithms.h" + +#include <algorithm> +#include <cassert> +#include <cstdint> +#include <stdexcept> +#include <type_traits> +#include <vector> + +namespace ZXing { + +class ByteArray; + +/** +* A simple, fast array of bits. +*/ +class BitArray +{ + std::vector<uint8_t> _bits; + + friend class BitMatrix; + + // Nothing wrong to support it, just to make it explicit, instead of by mistake. + // Use copy() below. + BitArray(const BitArray &) = default; + BitArray& operator=(const BitArray &) = delete; + +public: + + using Iterator = std::vector<uint8_t>::const_iterator; + + BitArray() = default; + + explicit BitArray(int size) : _bits(size, 0) {} + + BitArray(BitArray&& other) noexcept = default; + BitArray& operator=(BitArray&& other) noexcept = default; + + BitArray copy() const { return *this; } + + int size() const noexcept { return Size(_bits); } + + int sizeInBytes() const noexcept { return (size() + 7) / 8; } + + bool get(int i) const { return _bits.at(i) != 0; } + void set(int i, bool val) { _bits.at(i) = val; } + + // If you know exactly how may bits you are going to iterate + // and that you access bit in sequence, iterator is faster than get(). + // However, be extremely careful since there is no check whatsoever. + // (Performance is the reason for the iterator to exist in the first place.) + Iterator iterAt(int i) const noexcept { return {_bits.cbegin() + i}; } + Iterator begin() const noexcept { return _bits.cbegin(); } + Iterator end() const noexcept { return _bits.cend(); } + + /** + * Appends the least-significant bits, from value, in order from most-significant to + * least-significant. For example, appending 6 bits from 0x000001E will append the bits + * 0, 1, 1, 1, 1, 0 in that order. + * + * @param value {@code int} containing bits to append + * @param numBits bits from value to append + */ + void appendBits(int value, int numBits) + { + for (; numBits; --numBits) + _bits.push_back((value >> (numBits-1)) & 1); + } + + void appendBit(bool bit) { _bits.push_back(bit); } + + void appendBitArray(const BitArray& other) { _bits.insert(_bits.end(), other.begin(), other.end()); } + + /** + * Reverses all bits in the array. + */ + void reverse() { std::reverse(_bits.begin(), _bits.end()); } + + void bitwiseXOR(const BitArray& other); + + /** + * @param bitOffset first bit to extract + * @param numBytes how many bytes to extract (-1 == until the end, padded with '0') + * @return Bytes are written most-significant bit first. + */ + ByteArray toBytes(int bitOffset = 0, int numBytes = -1) const; + + using Range = ZXing::Range<Iterator>; + Range range() const { return {begin(), end()}; } + + friend bool operator==(const BitArray& a, const BitArray& b) { return a._bits == b._bits; } +}; + +template<typename T, typename = std::enable_if_t<std::is_integral_v<T>>> +T& AppendBit(T& val, bool bit) +{ + return (val <<= 1) |= static_cast<T>(bit); +} + +template <typename ARRAY, typename = std::enable_if_t<std::is_integral_v<typename ARRAY::value_type>>> +int ToInt(const ARRAY& a) +{ + assert(Reduce(a) <= 32); + + int pattern = 0; + for (int i = 0; i < Size(a); i++) + pattern = (pattern << a[i]) | ~(0xffffffff << a[i]) * (~i & 1); + return pattern; +} + +template <typename T = int, typename = std::enable_if_t<std::is_integral_v<T>>> +T ToInt(const BitArray& bits, int pos = 0, int count = 8 * sizeof(T)) +{ + assert(0 <= count && count <= 8 * (int)sizeof(T)); + assert(0 <= pos && pos + count <= bits.size()); + + count = std::min(count, bits.size()); + int res = 0; + auto it = bits.iterAt(pos); + for (int i = 0; i < count; ++i, ++it) + AppendBit(res, *it); + + return res; +} + +template <typename T = int, typename = std::enable_if_t<std::is_integral_v<T>>> +std::vector<T> ToInts(const BitArray& bits, int wordSize, int totalWords, int offset = 0) +{ + assert(totalWords >= bits.size() / wordSize); + assert(wordSize <= 8 * (int)sizeof(T)); + + std::vector<T> res(totalWords, 0); + for (int i = offset; i < bits.size(); i += wordSize) + res[(i - offset) / wordSize] = ToInt(bits, i, wordSize); + + return res; +} + +class BitArrayView +{ + const BitArray& bits; + BitArray::Iterator cur; + +public: + BitArrayView(const BitArray& bits) : bits(bits), cur(bits.begin()) {} + + BitArrayView& skipBits(int n) + { + if (cur + n > bits.end()) + throw std::out_of_range("BitArrayView::skipBits() out of range."); + cur += n; + return *this; + } + + int peakBits(int n) const + { + assert(n <= 32); + if (cur + n > bits.end()) + throw std::out_of_range("BitArrayView::peakBits() out of range."); + int res = 0; + for (auto i = cur; n > 0; --n, i++) + AppendBit(res, *i); + return res; + } + + int readBits(int n) + { + int res = peakBits(n); + cur += n; + return res; + } + + int size() const + { + return narrow_cast<int>(bits.end() - cur); + } + + explicit operator bool() const { return size(); } +}; + +} // ZXing
