PluginProbe ʕ •ᴥ•ʔ
WP 2FA – Two-factor authentication for WordPress / 2.9.0
WP 2FA – Two-factor authentication for WordPress v2.9.0
4.0.0 1.7.1 2.0.0 2.0.1 2.1.0 2.2.0 2.2.1 2.3.0 2.4.0 2.4.1 2.4.2 2.5.0 2.6.0 2.6.1 2.6.2 2.6.3 2.6.4 2.7.0 2.8.0 2.9.0 2.9.1 2.9.2 2.9.3 3.0.0 3.0.1 3.1.0 3.1.1 3.1.1.2 trunk 1.2.0 1.3.0 1.4.0 1.4.1 1.4.2 1.5.0 1.5.1 1.5.2 1.6.0 1.6.1 1.6.2 1.7.0
wp-2fa / includes / classes / bacon / bacon-qr-code / src / Common / BitMatrix.php
wp-2fa / includes / classes / bacon / bacon-qr-code / src / Common Last commit date
BitArray.php 11 months ago BitMatrix.php 11 months ago BitUtils.php 11 months ago CharacterSetEci.php 11 months ago EcBlock.php 11 months ago EcBlocks.php 11 months ago ErrorCorrectionLevel.php 11 months ago FormatInformation.php 11 months ago Mode.php 11 months ago ReedSolomonCodec.php 11 months ago Version.php 11 months ago
BitMatrix.php
259 lines
1 <?php
2
3 declare (strict_types=1);
4 namespace WP2FA_Vendor\BaconQrCode\Common;
5
6 use WP2FA_Vendor\BaconQrCode\Exception\InvalidArgumentException;
7 use SplFixedArray;
8 /**
9 * Bit matrix.
10 *
11 * Represents a 2D matrix of bits. In function arguments below, and throughout
12 * the common module, x is the column position, and y is the row position. The
13 * ordering is always x, y. The origin is at the top-left.
14 */
15 class BitMatrix
16 {
17 /**
18 * Width of the bit matrix.
19 *
20 * @var int
21 */
22 private $width;
23 /**
24 * Height of the bit matrix.
25 *
26 * @var int
27 */
28 private $height;
29 /**
30 * Size in bits of each individual row.
31 *
32 * @var int
33 */
34 private $rowSize;
35 /**
36 * Bits representation.
37 *
38 * @var SplFixedArray<int>
39 */
40 private $bits;
41 /**
42 * @throws InvalidArgumentException if a dimension is smaller than zero
43 */
44 public function __construct(int $width, int $height = null)
45 {
46 if (null === $height) {
47 $height = $width;
48 }
49 if ($width < 1 || $height < 1) {
50 throw new InvalidArgumentException('Both dimensions must be greater than zero');
51 }
52 $this->width = $width;
53 $this->height = $height;
54 $this->rowSize = $width + 31 >> 5;
55 $this->bits = SplFixedArray::fromArray(\array_fill(0, $this->rowSize * $height, 0));
56 }
57 /**
58 * Gets the requested bit, where true means black.
59 */
60 public function get(int $x, int $y) : bool
61 {
62 $offset = $y * $this->rowSize + ($x >> 5);
63 return 0 !== (BitUtils::unsignedRightShift($this->bits[$offset], $x & 0x1f) & 1);
64 }
65 /**
66 * Sets the given bit to true.
67 */
68 public function set(int $x, int $y) : void
69 {
70 $offset = $y * $this->rowSize + ($x >> 5);
71 $this->bits[$offset] = $this->bits[$offset] | 1 << ($x & 0x1f);
72 }
73 /**
74 * Flips the given bit.
75 */
76 public function flip(int $x, int $y) : void
77 {
78 $offset = $y * $this->rowSize + ($x >> 5);
79 $this->bits[$offset] = $this->bits[$offset] ^ 1 << ($x & 0x1f);
80 }
81 /**
82 * Clears all bits (set to false).
83 */
84 public function clear() : void
85 {
86 $max = \count($this->bits);
87 for ($i = 0; $i < $max; ++$i) {
88 $this->bits[$i] = 0;
89 }
90 }
91 /**
92 * Sets a square region of the bit matrix to true.
93 *
94 * @throws InvalidArgumentException if left or top are negative
95 * @throws InvalidArgumentException if width or height are smaller than 1
96 * @throws InvalidArgumentException if region does not fit into the matix
97 */
98 public function setRegion(int $left, int $top, int $width, int $height) : void
99 {
100 if ($top < 0 || $left < 0) {
101 throw new InvalidArgumentException('Left and top must be non-negative');
102 }
103 if ($height < 1 || $width < 1) {
104 throw new InvalidArgumentException('Width and height must be at least 1');
105 }
106 $right = $left + $width;
107 $bottom = $top + $height;
108 if ($bottom > $this->height || $right > $this->width) {
109 throw new InvalidArgumentException('The region must fit inside the matrix');
110 }
111 for ($y = $top; $y < $bottom; ++$y) {
112 $offset = $y * $this->rowSize;
113 for ($x = $left; $x < $right; ++$x) {
114 $index = $offset + ($x >> 5);
115 $this->bits[$index] = $this->bits[$index] | 1 << ($x & 0x1f);
116 }
117 }
118 }
119 /**
120 * A fast method to retrieve one row of data from the matrix as a BitArray.
121 */
122 public function getRow(int $y, BitArray $row = null) : BitArray
123 {
124 if (null === $row || $row->getSize() < $this->width) {
125 $row = new BitArray($this->width);
126 }
127 $offset = $y * $this->rowSize;
128 for ($x = 0; $x < $this->rowSize; ++$x) {
129 $row->setBulk($x << 5, $this->bits[$offset + $x]);
130 }
131 return $row;
132 }
133 /**
134 * Sets a row of data from a BitArray.
135 */
136 public function setRow(int $y, BitArray $row) : void
137 {
138 $bits = $row->getBitArray();
139 for ($i = 0; $i < $this->rowSize; ++$i) {
140 $this->bits[$y * $this->rowSize + $i] = $bits[$i];
141 }
142 }
143 /**
144 * This is useful in detecting the enclosing rectangle of a 'pure' barcode.
145 *
146 * @return int[]|null
147 */
148 public function getEnclosingRectangle() : ?array
149 {
150 $left = $this->width;
151 $top = $this->height;
152 $right = -1;
153 $bottom = -1;
154 for ($y = 0; $y < $this->height; ++$y) {
155 for ($x32 = 0; $x32 < $this->rowSize; ++$x32) {
156 $bits = $this->bits[$y * $this->rowSize + $x32];
157 if (0 !== $bits) {
158 if ($y < $top) {
159 $top = $y;
160 }
161 if ($y > $bottom) {
162 $bottom = $y;
163 }
164 if ($x32 * 32 < $left) {
165 $bit = 0;
166 while ($bits << 31 - $bit === 0) {
167 $bit++;
168 }
169 if ($x32 * 32 + $bit < $left) {
170 $left = $x32 * 32 + $bit;
171 }
172 }
173 }
174 if ($x32 * 32 + 31 > $right) {
175 $bit = 31;
176 while (0 === BitUtils::unsignedRightShift($bits, $bit)) {
177 --$bit;
178 }
179 if ($x32 * 32 + $bit > $right) {
180 $right = $x32 * 32 + $bit;
181 }
182 }
183 }
184 }
185 $width = $right - $left;
186 $height = $bottom - $top;
187 if ($width < 0 || $height < 0) {
188 return null;
189 }
190 return [$left, $top, $width, $height];
191 }
192 /**
193 * Gets the most top left set bit.
194 *
195 * This is useful in detecting a corner of a 'pure' barcode.
196 *
197 * @return int[]|null
198 */
199 public function getTopLeftOnBit() : ?array
200 {
201 $bitsOffset = 0;
202 while ($bitsOffset < \count($this->bits) && 0 === $this->bits[$bitsOffset]) {
203 ++$bitsOffset;
204 }
205 if (\count($this->bits) === $bitsOffset) {
206 return null;
207 }
208 $x = \intdiv($bitsOffset, $this->rowSize);
209 $y = $bitsOffset % $this->rowSize << 5;
210 $bits = $this->bits[$bitsOffset];
211 $bit = 0;
212 while (0 === $bits << 31 - $bit) {
213 ++$bit;
214 }
215 $x += $bit;
216 return [$x, $y];
217 }
218 /**
219 * Gets the most bottom right set bit.
220 *
221 * This is useful in detecting a corner of a 'pure' barcode.
222 *
223 * @return int[]|null
224 */
225 public function getBottomRightOnBit() : ?array
226 {
227 $bitsOffset = \count($this->bits) - 1;
228 while ($bitsOffset >= 0 && 0 === $this->bits[$bitsOffset]) {
229 --$bitsOffset;
230 }
231 if ($bitsOffset < 0) {
232 return null;
233 }
234 $x = \intdiv($bitsOffset, $this->rowSize);
235 $y = $bitsOffset % $this->rowSize << 5;
236 $bits = $this->bits[$bitsOffset];
237 $bit = 0;
238 while (0 === BitUtils::unsignedRightShift($bits, $bit)) {
239 --$bit;
240 }
241 $x += $bit;
242 return [$x, $y];
243 }
244 /**
245 * Gets the width of the matrix,
246 */
247 public function getWidth() : int
248 {
249 return $this->width;
250 }
251 /**
252 * Gets the height of the matrix.
253 */
254 public function getHeight() : int
255 {
256 return $this->height;
257 }
258 }
259