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