Mercurial > hgrepos > Python2 > PyMuPDF
comparison mupdf-source/thirdparty/zxing-cpp/core/src/BitMatrix.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 2022 Axel Waggershauser | |
| 5 */ | |
| 6 // SPDX-License-Identifier: Apache-2.0 | |
| 7 | |
| 8 #pragma once | |
| 9 | |
| 10 #include "Matrix.h" | |
| 11 #include "Point.h" | |
| 12 #include "Range.h" | |
| 13 | |
| 14 #include <cstdint> | |
| 15 #include <stdexcept> | |
| 16 #include <vector> | |
| 17 | |
| 18 namespace ZXing { | |
| 19 | |
| 20 class BitArray; | |
| 21 class ByteMatrix; | |
| 22 | |
| 23 /** | |
| 24 * @brief A simple, fast 2D array of bits. | |
| 25 */ | |
| 26 class BitMatrix | |
| 27 { | |
| 28 int _width = 0; | |
| 29 int _height = 0; | |
| 30 using data_t = uint8_t; | |
| 31 | |
| 32 std::vector<data_t> _bits; | |
| 33 // There is nothing wrong to support this but disable to make it explicit since we may copy something very big here. | |
| 34 // Use copy() below. | |
| 35 BitMatrix(const BitMatrix&) = default; | |
| 36 BitMatrix& operator=(const BitMatrix&) = delete; | |
| 37 | |
| 38 const data_t& get(int i) const | |
| 39 { | |
| 40 #if 1 | |
| 41 return _bits.at(i); | |
| 42 #else | |
| 43 return _bits[i]; | |
| 44 #endif | |
| 45 } | |
| 46 | |
| 47 data_t& get(int i) { return const_cast<data_t&>(static_cast<const BitMatrix*>(this)->get(i)); } | |
| 48 | |
| 49 bool getTopLeftOnBit(int &left, int& top) const; | |
| 50 bool getBottomRightOnBit(int &right, int& bottom) const; | |
| 51 | |
| 52 public: | |
| 53 static constexpr data_t SET_V = 0xff; // allows playing with SIMD binarization | |
| 54 static constexpr data_t UNSET_V = 0; | |
| 55 static_assert(bool(SET_V) && !bool(UNSET_V), "SET_V needs to evaluate to true, UNSET_V to false, see iterator usage"); | |
| 56 | |
| 57 BitMatrix() = default; | |
| 58 | |
| 59 #if defined(__llvm__) || (defined(__GNUC__) && (__GNUC__ > 7)) | |
| 60 __attribute__((no_sanitize("signed-integer-overflow"))) | |
| 61 #endif | |
| 62 BitMatrix(int width, int height) : _width(width), _height(height), _bits(width * height, UNSET_V) | |
| 63 { | |
| 64 if (width != 0 && Size(_bits) / width != height) | |
| 65 throw std::invalid_argument("Invalid size: width * height is too big"); | |
| 66 } | |
| 67 | |
| 68 explicit BitMatrix(int dimension) : BitMatrix(dimension, dimension) {} // Construct a square matrix. | |
| 69 | |
| 70 BitMatrix(BitMatrix&& other) noexcept = default; | |
| 71 BitMatrix& operator=(BitMatrix&& other) noexcept = default; | |
| 72 | |
| 73 BitMatrix copy() const { return *this; } | |
| 74 | |
| 75 Range<data_t*> row(int y) { return {_bits.data() + y * _width, _bits.data() + (y + 1) * _width}; } | |
| 76 Range<const data_t*> row(int y) const { return {_bits.data() + y * _width, _bits.data() + (y + 1) * _width}; } | |
| 77 | |
| 78 Range<StrideIter<const data_t*>> col(int x) const | |
| 79 { | |
| 80 return {{_bits.data() + x + (_height - 1) * _width, -_width}, {_bits.data() + x - _width, -_width}}; | |
| 81 } | |
| 82 | |
| 83 bool get(int x, int y) const { return get(y * _width + x); } | |
| 84 void set(int x, int y, bool val = true) { get(y * _width + x) = val * SET_V; } | |
| 85 | |
| 86 /** | |
| 87 * <p>Flips the given bit.</p> | |
| 88 * | |
| 89 * @param x The horizontal component (i.e. which column) | |
| 90 * @param y The vertical component (i.e. which row) | |
| 91 */ | |
| 92 void flip(int x, int y) | |
| 93 { | |
| 94 auto& v = get(y * _width + x); | |
| 95 v = !v; | |
| 96 } | |
| 97 | |
| 98 void flipAll() | |
| 99 { | |
| 100 for (auto& i : _bits) | |
| 101 i = !i * SET_V; | |
| 102 } | |
| 103 | |
| 104 /** | |
| 105 * <p>Sets a square region of the bit matrix to true.</p> | |
| 106 * | |
| 107 * @param left The horizontal position to begin at (inclusive) | |
| 108 * @param top The vertical position to begin at (inclusive) | |
| 109 * @param width The width of the region | |
| 110 * @param height The height of the region | |
| 111 */ | |
| 112 void setRegion(int left, int top, int width, int height); | |
| 113 | |
| 114 void rotate90(); | |
| 115 | |
| 116 void rotate180(); | |
| 117 | |
| 118 void mirror(); | |
| 119 | |
| 120 /** | |
| 121 * Find the rectangle that contains all non-white pixels. Useful for detection of 'pure' barcodes. | |
| 122 * | |
| 123 * @return True iff this rectangle is at least minWidth x minHeight pixels big | |
| 124 */ | |
| 125 bool findBoundingBox(int &left, int& top, int& width, int& height, int minSize = 1) const; | |
| 126 | |
| 127 int width() const { return _width; } | |
| 128 | |
| 129 int height() const { return _height; } | |
| 130 | |
| 131 bool empty() const { return _bits.empty(); } | |
| 132 | |
| 133 friend bool operator==(const BitMatrix& a, const BitMatrix& b) | |
| 134 { | |
| 135 return a._width == b._width && a._height == b._height && a._bits == b._bits; | |
| 136 } | |
| 137 | |
| 138 template <typename T> | |
| 139 bool isIn(PointT<T> p, int b = 0) const noexcept | |
| 140 { | |
| 141 return b <= p.x && p.x < width() - b && b <= p.y && p.y < height() - b; | |
| 142 } | |
| 143 | |
| 144 bool get(PointI p) const { return get(p.x, p.y); } | |
| 145 bool get(PointF p) const { return get(PointI(p)); } | |
| 146 void set(PointI p, bool v = true) { set(p.x, p.y, v); } | |
| 147 void set(PointF p, bool v = true) { set(PointI(p), v); } | |
| 148 }; | |
| 149 | |
| 150 void GetPatternRow(const BitMatrix& matrix, int r, std::vector<uint16_t>& pr, bool transpose); | |
| 151 | |
| 152 /** | |
| 153 * @brief Inflate scales a BitMatrix up and adds a quiet Zone plus padding | |
| 154 * @param input matrix to be expanded | |
| 155 * @param width new width in bits (pixel) | |
| 156 * @param height new height in bits (pixel) | |
| 157 * @param quietZone size of quiet zone to add in modules | |
| 158 * @return expanded BitMatrix, maybe move(input) if size did not change | |
| 159 */ | |
| 160 BitMatrix Inflate(BitMatrix&& input, int width, int height, int quietZone); | |
| 161 | |
| 162 /** | |
| 163 * @brief Deflate (crop + subsample) a bit matrix | |
| 164 * @param input matrix to be shrinked | |
| 165 * @param width new width | |
| 166 * @param height new height | |
| 167 * @param top cropping starts at top row | |
| 168 * @param left cropping starts at left col | |
| 169 * @param subSampling typically the module size | |
| 170 * @return deflated input | |
| 171 */ | |
| 172 BitMatrix Deflate(const BitMatrix& input, int width, int height, float top, float left, float subSampling); | |
| 173 | |
| 174 template<typename T> | |
| 175 BitMatrix ToBitMatrix(const Matrix<T>& in, T trueValue = {true}) | |
| 176 { | |
| 177 BitMatrix out(in.width(), in.height()); | |
| 178 for (int y = 0; y < in.height(); ++y) | |
| 179 for (int x = 0; x < in.width(); ++x) | |
| 180 if (in.get(x, y) == trueValue) | |
| 181 out.set(x, y); | |
| 182 return out; | |
| 183 } | |
| 184 | |
| 185 template<typename T> | |
| 186 Matrix<T> ToMatrix(const BitMatrix& in, T black = 0, T white = ~0) | |
| 187 { | |
| 188 Matrix<T> res(in.width(), in.height()); | |
| 189 for (int y = 0; y < in.height(); ++y) | |
| 190 for (int x = 0; x < in.width(); ++x) | |
| 191 res.set(x, y, in.get(x, y) ? black : white); | |
| 192 return res; | |
| 193 } | |
| 194 | |
| 195 } // ZXing |
