zxing-cpp: strip to core library only (remove tests/wrappers/examples/docs); .gitignore: fix /core to allow zxing-cpp/core/ dir
This commit is contained in:
1 parent
22c24d135e
commit
8051dfe4e5
2506 files changed
+57271
-30087
No files matched your search
@@ -0,0 +1,201 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
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& operator=(const BitArray &) = delete;
|
||||
|
||||
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)
|
||||
{
|
||||
assert(numBits >= 1 && numBits <= 32);
|
||||
|
||||
for (; numBits; --numBits)
|
||||
_bits.push_back((value >> (numBits-1)) & 1);
|
||||
}
|
||||
|
||||
void appendBits(uint32_t value, int numBits)
|
||||
{
|
||||
appendBits(static_cast<int>(value), numBits);
|
||||
}
|
||||
|
||||
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>>>
|
||||
constexpr 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>>>
|
||||
constexpr int ToInt(const ARRAY& a)
|
||||
{
|
||||
assert(Reduce(a) <= 32);
|
||||
|
||||
int pattern = 0;
|
||||
for (int i = 0; i < Size(a); i++) {
|
||||
if (a[i] < 0) // negative shift is undefined behavior
|
||||
return -1;
|
||||
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 peekBits(int n) const
|
||||
{
|
||||
assert(n <= 32);
|
||||
if (cur + n > bits.end())
|
||||
throw std::out_of_range("BitArrayView::peekBits() 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 = peekBits(n);
|
||||
cur += n;
|
||||
return res;
|
||||
}
|
||||
|
||||
int size() const
|
||||
{
|
||||
return narrow_cast<int>(bits.end() - cur);
|
||||
}
|
||||
|
||||
explicit operator bool() const { return size(); }
|
||||
};
|
||||
|
||||
} // ZXing
|
||||
Reference in new issue
Block a user