Skip to content

Commit abb7ce7

Browse files
committed
🔧 fixes for #45
1 parent 1d9b1e1 commit abb7ce7

File tree

4 files changed

+79
-77
lines changed

4 files changed

+79
-77
lines changed

src/Data/MaskPatternTester.php

Lines changed: 50 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313
namespace chillerlan\QRCode\Data;
1414

15-
use function abs, call_user_func;
15+
use function abs, call_user_func_array;
1616

1717
/**
1818
* The sole purpose of this class is to receive a QRMatrix object and run the pattern tests on it.
@@ -58,7 +58,7 @@ public function testPattern():int{
5858
$penalty = 0;
5959

6060
for($level = 1; $level <= 4; $level++){
61-
$penalty += call_user_func([$this, 'testLevel'.$level]);
61+
$penalty += call_user_func_array([$this, 'testLevel'.$level], [$this->matrix->matrix(true)]);
6262
}
6363

6464
return (int)$penalty;
@@ -67,12 +67,12 @@ public function testPattern():int{
6767
/**
6868
* Checks for each group of five or more same-colored modules in a row (or column)
6969
*
70-
* @return float
70+
* @return int
7171
*/
72-
protected function testLevel1():float{
72+
protected function testLevel1(array $m):int{
7373
$penalty = 0;
7474

75-
foreach($this->matrix->matrix() as $y => $row){
75+
foreach($m as $y => $row){
7676
foreach($row as $x => $val){
7777
$count = 0;
7878

@@ -84,11 +84,11 @@ protected function testLevel1():float{
8484

8585
for($rx = -1; $rx <= 1; $rx++){
8686

87-
if(($ry === 0 && $rx === 0) || ($x + $rx < 0 || $this->moduleCount <= $x + $rx)){
87+
if(($ry === 0 && $rx === 0) || (($x + $rx) < 0 || $this->moduleCount <= ($x + $rx))){
8888
continue;
8989
}
9090

91-
if($this->matrix->check($x + $rx, $y + $ry) === ($val >> 8 > 0)){
91+
if($m[$y + $ry][$x + $rx] === $val){
9292
$count++;
9393
}
9494

@@ -108,107 +108,90 @@ protected function testLevel1():float{
108108
/**
109109
* Checks for each 2x2 area of same-colored modules in the matrix
110110
*
111-
* @return float
111+
* @return int
112112
*/
113-
protected function testLevel2():float{
113+
protected function testLevel2(array $m):int{
114114
$penalty = 0;
115115

116-
foreach($this->matrix->matrix() as $y => $row){
116+
foreach($m as $y => $row){
117117

118-
if($y > $this->moduleCount - 2){
118+
if($y > ($this->moduleCount - 2)){
119119
break;
120120
}
121121

122122
foreach($row as $x => $val){
123123

124-
if($x > $this->moduleCount - 2){
124+
if($x > ($this->moduleCount - 2)){
125125
break;
126126
}
127127

128-
$count = 0;
129-
130-
if($val >> 8 > 0){
131-
$count++;
132-
}
133-
134-
if($this->matrix->check($y, $x + 1)){
135-
$count++;
136-
}
137-
138-
if($this->matrix->check($y + 1, $x)){
139-
$count++;
140-
}
141-
142-
if($this->matrix->check($y + 1, $x + 1)){
143-
$count++;
128+
if(
129+
$val === $m[$y][$x + 1]
130+
&& $val === $m[$y + 1][$x]
131+
&& $val === $m[$y + 1][$x + 1]
132+
){
133+
$penalty++;
144134
}
145-
146-
if($count === 0 || $count === 4){
147-
$penalty += 3;
148-
}
149-
150135
}
151136
}
152137

153-
return $penalty;
138+
return 3 * $penalty;
154139
}
155140

156141
/**
157-
* Checks if there are patterns that look similar to the finder patterns
142+
* Checks if there are patterns that look similar to the finder patterns (1:1:3:1:1 ratio)
158143
*
159-
* @return float
144+
* @return int
160145
*/
161-
protected function testLevel3():float{
162-
$penalty = 0;
146+
protected function testLevel3(array $m):int{
147+
$penalties = 0;
163148

164-
foreach($this->matrix->matrix() as $y => $row){
149+
foreach($m as $y => $row){
165150
foreach($row as $x => $val){
166151

167-
if($x <= $this->moduleCount - 7){
168-
if(
169-
$this->matrix->check($x , $y)
170-
&& !$this->matrix->check($x + 1, $y)
171-
&& $this->matrix->check($x + 2, $y)
172-
&& $this->matrix->check($x + 3, $y)
173-
&& $this->matrix->check($x + 4, $y)
174-
&& !$this->matrix->check($x + 5, $y)
175-
&& $this->matrix->check($x + 6, $y)
176-
){
177-
$penalty += 40;
178-
}
152+
if(
153+
($x + 6) < $this->moduleCount
154+
&& $val
155+
&& !$m[$y][$x + 1]
156+
&& $m[$y][$x + 2]
157+
&& $m[$y][$x + 3]
158+
&& $m[$y][$x + 4]
159+
&& !$m[$y][$x + 5]
160+
&& $m[$y][$x + 6]
161+
){
162+
$penalties++;
179163
}
180164

181-
if($y <= $this->moduleCount - 7){
182-
if(
183-
$this->matrix->check($x, $y)
184-
&& !$this->matrix->check($x, $y + 1)
185-
&& $this->matrix->check($x, $y + 2)
186-
&& $this->matrix->check($x, $y + 3)
187-
&& $this->matrix->check($x, $y + 4)
188-
&& !$this->matrix->check($x, $y + 5)
189-
&& $this->matrix->check($x, $y + 6)
190-
){
191-
$penalty += 40;
192-
}
165+
if(
166+
($y + 6) < $this->moduleCount
167+
&& $val
168+
&& !$m[$y + 1][$x]
169+
&& $m[$y + 2][$x]
170+
&& $m[$y + 3][$x]
171+
&& $m[$y + 4][$x]
172+
&& !$m[$y + 5][$x]
173+
&& $m[$y + 6][$x]
174+
){
175+
$penalties++;
193176
}
194177

195178
}
196179
}
197180

198-
return $penalty;
181+
return $penalties * 40;
199182
}
200183

201184
/**
202185
* Checks if more than half of the modules are dark or light, with a larger penalty for a larger difference
203186
*
204187
* @return float
205188
*/
206-
protected function testLevel4():float{
189+
protected function testLevel4(array $m):float{
207190
$count = 0;
208191

209-
foreach($this->matrix->matrix() as $y => $row){
192+
foreach($m as $y => $row){
210193
foreach($row as $x => $val){
211-
if($val >> 8 > 0){
194+
if($val){
212195
$count++;
213196
}
214197
}

src/Data/QRMatrix.php

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -220,10 +220,27 @@ public function __construct(int $version, int $eclevel){
220220
}
221221

222222
/**
223-
* @return array
223+
* Returns the data matrix, returns a pure boolean representation if $boolean is set to true
224+
*
225+
* @return int[][]|bool[][]
224226
*/
225-
public function matrix():array{
226-
return $this->matrix;
227+
public function matrix(bool $boolean = false):array{
228+
229+
if(!$boolean){
230+
return $this->matrix;
231+
}
232+
233+
$matrix = [];
234+
235+
foreach($this->matrix as $y => $row){
236+
$matrix[$y] = [];
237+
238+
foreach($row as $x => $val){
239+
$matrix[$y][$x] = ($val >> 8) > 0;
240+
}
241+
}
242+
243+
return $matrix;
227244
}
228245

229246
/**
@@ -600,6 +617,9 @@ public function mapData(array $data, int $maskPattern):QRMatrix{
600617
/**
601618
* ISO/IEC 18004:2000 Section 8.8.1
602619
*
620+
* Note that some versions of the QR code standard have had errors in the section about mask patterns.
621+
* The information below has been corrected. (https://www.thonky.com/qr-code-tutorial/mask-patterns)
622+
*
603623
* @see \chillerlan\QRCode\QRMatrix::mapData()
604624
*
605625
* @internal
@@ -617,10 +637,10 @@ protected function getMask(int $maskPattern):Closure{
617637

618638
return [
619639
0b000 => function($x, $y):int{ return ($x + $y) % 2; },
620-
0b001 => function($x, $y):int{ return $x % 2; },
621-
0b010 => function($x, $y):int{ return $y % 3; },
640+
0b001 => function($x, $y):int{ return $y % 2; },
641+
0b010 => function($x, $y):int{ return $x % 3; },
622642
0b011 => function($x, $y):int{ return ($x + $y) % 3; },
623-
0b100 => function($x, $y):int{ return ((int)($x / 2) + (int)($y / 3)) % 2; },
643+
0b100 => function($x, $y):int{ return ((int)($y / 2) + (int)($x / 3)) % 2; },
624644
0b101 => function($x, $y):int{ return (($x * $y) % 2) + (($x * $y) % 3); },
625645
0b110 => function($x, $y):int{ return ((($x * $y) % 2) + (($x * $y) % 3)) % 2; },
626646
0b111 => function($x, $y):int{ return ((($x * $y) % 3) + (($x + $y) % 2)) % 2; },

tests/Data/MaskPatternTesterTest.php

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,9 @@ class MaskPatternTesterTest extends QRTestAbstract{
2121

2222
// coverage
2323
public function testMaskpattern(){
24-
$matrix = (new Byte(new QROptions(['version' => 10]), 'test'))->initMatrix(0, true);
24+
$matrix = (new Byte(new QROptions(['version' => 10]), 'test'))->initMatrix(3, true);
2525

26-
$this->assertSame(6178, (new MaskPatternTester($matrix))->testPattern());
26+
$this->assertSame(4243, (new MaskPatternTester($matrix))->testPattern());
2727
}
2828

29-
3029
}

tests/QRCodeTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ public function testCustomOutput(){
109109
'outputInterface' => MyCustomOutput::class,
110110
]);
111111

112-
$expected = '000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011111110101011110100001011110011111110000000010000010011111001010011111001010000010000000010111010111000001101011000001010111010000000010111010111010110000011010110010111010000000010111010100110101100000110101010111010000000010000010001101011000001101011010000010000000011111110101010101010101010101011111110000000000000000001010011111001010011000000000000000011110010101111010000101111010100111010000000001110001001011110100001011110110010010000000001100010011111001010011111001011110010000000011010000101000001101011000001011001010000000001101011010010110000011010110100000100000000000001001001110101100000110101101011100000000011100010100101011000001101011001100000000000000001000101100101001111100101111101010000000000111011111010111101000010111101100000000000001111000010000101111010000101101001110000000000100011110001111100101001111101000110000000010001001001101100000110101100110100010000000011100111001001101011000001101111011000000000010110101000000011010110000011011101100000000001111011110000110101100000110100001000000000010111100001111110010100111110100110100000000011001011111100001011110100001011010110000000000100101001101000010111101000000100110000000001011011100010100111110010100110011100000000010010101010011010110000011010000010010000000000111011101100000110101100001111110000000000000000000111011000001101011001000110110000000011111110000110000011010110011010111110000000010000010010010011111001010011000111100000000010111010010111010000101111011111101100000000010111010101011110100001011111100010010000000010111010111111001010011111011101010100000000010000010111000001101011000011001101000000000011111110111010110000011010110111100110000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000';
112+
$expected = '000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011111110111010000101111010000011111110000000010000010111000001101011000001010000010000000010111010101101011000001101011010111010000000010111010110100111110010100111010111010000000010111010000001101011000001101010111010000000010000010100111110010100111110010000010000000011111110101010101010101010101011111110000000000000000010010100111110010100000000000000000011001110000101111010000101111001011110000000000000000111010000101111010000111100010000000001011010100111110010100111110011001010000000010000101111101011000001101011110011110000000000011010100011000001101011000101110100000000011001100001001101011000001101010011010000000010110111110000001101011000001100110100000000010000100100010100111110010100001100100000000011111110111101111010000101111010100110000000011010000111010000101111010000111100100000000010101111111111110010100111110011001000000000010110001110101011000001101011110011010000000001001111100011000001101011000101110010000000011000100110001101011000001101010011100000000001000011001000001101011000001100110000000000011101001011010100111110010100001100000000000010111010001101111010000101111010100110000000011100000001010000101111010000111100000000000000001110110111110010100111110011001000000000000011001011101011000001101011110011100000000011111110101011000001101011001111110110000000000000000110001101011000001101000111100000000011111110001000001101011000011010110000000000010000010101010100111110010101000100100000000010111010111101111010000101111111100110000000010111010011010000101111010001101100010000000010111010000111110010100111100101101100000000010000010101101011000001101001100111100000000011111110101011000001101011000110010110000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000';
113113

114114
$this->assertSame($expected, $this->reflection->newInstanceArgs([$options])->render('test'));
115115
}

0 commit comments

Comments
 (0)