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