Skip to content

Commit fd885ff

Browse files
committed
🚿 moved interleaved data mapping from QRMatrix to ReedSolomonEncoder
1 parent 27e82de commit fd885ff

File tree

3 files changed

+69
-76
lines changed

3 files changed

+69
-76
lines changed

src/Common/ReedSolomonEncoder.php

Lines changed: 64 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,7 @@
1010

1111
namespace chillerlan\QRCode\Common;
1212

13-
use SplFixedArray;
14-
13+
use chillerlan\QRCode\Data\QRMatrix;
1514
use function array_fill, array_merge, count, max;
1615

1716
/**
@@ -21,16 +20,15 @@
2120
*/
2221
final class ReedSolomonEncoder{
2322

24-
private SplFixedArray $interleavedData;
25-
private int $interleavedDataIndex;
23+
private array $interleavedData;
24+
private int $interleavedDataIndex;
2625

2726
/**
2827
* ECC interleaving
29-
*
30-
* @return \SplFixedArray<int>
3128
*/
32-
public function interleaveEcBytes(BitBuffer $bitBuffer, Version $version, EccLevel $eccLevel):SplFixedArray{
33-
[$numEccCodewords, [[$l1, $b1], [$l2, $b2]]] = $version->getRSBlocks($eccLevel);
29+
public function interleaveEcBytes(BitBuffer $bitBuffer, QRMatrix $matrix):QRMatrix{
30+
$version = $matrix->version();
31+
[$numEccCodewords, [[$l1, $b1], [$l2, $b2]]] = $version->getRSBlocks($matrix->eccLevel());
3432

3533
$rsBlocks = array_fill(0, $l1, [$numEccCodewords + $b1, $b1]);
3634

@@ -61,14 +59,14 @@ public function interleaveEcBytes(BitBuffer $bitBuffer, Version $version, EccLev
6159
$dataByteOffset += $dataByteCount;
6260
}
6361

64-
$this->interleavedData = new SplFixedArray($version->getTotalCodewords());
62+
$this->interleavedData = array_fill(0, $version->getTotalCodewords(), 0);
6563
$this->interleavedDataIndex = 0;
6664
$numRsBlocks = $l1 + $l2;
6765

6866
$this->interleave($dataBytes, $maxDataBytes, $numRsBlocks);
6967
$this->interleave($ecBytes, $maxEcBytes, $numRsBlocks);
7068

71-
return $this->interleavedData;
69+
return $this->mapData($matrix);
7270
}
7371

7472
/**
@@ -112,4 +110,60 @@ private function interleave(array $byteArray, int $maxBytes, int $numRsBlocks):v
112110
}
113111
}
114112

113+
/**
114+
* Maps the interleaved binary $data on the matrix
115+
*/
116+
private function mapData(QRMatrix $matrix):QRMatrix{
117+
$byteCount = count($this->interleavedData);
118+
$size = $matrix->size();
119+
$y = $size - 1;
120+
$inc = -1;
121+
$byteIndex = 0;
122+
$bitIndex = 7;
123+
124+
for($i = $y; $i > 0; $i -= 2){
125+
126+
if($i === 6){
127+
$i--;
128+
}
129+
130+
while(true){
131+
for($c = 0; $c < 2; $c++){
132+
$x = $i - $c;
133+
134+
if($matrix->get($x, $y) !== QRMatrix::M_NULL){
135+
continue;
136+
}
137+
138+
$v = false;
139+
140+
if($byteIndex < $byteCount){
141+
$v = (($this->interleavedData[$byteIndex] >> $bitIndex) & 1) === 1;
142+
}
143+
144+
$matrix->set($x, $y, $v, QRMatrix::M_DATA);
145+
$bitIndex--;
146+
147+
if($bitIndex === -1){
148+
$byteIndex++;
149+
$bitIndex = 7;
150+
}
151+
152+
}
153+
154+
$y += $inc;
155+
156+
if($y < 0 || $size <= $y){
157+
$y -= $inc;
158+
$inc = -$inc;
159+
160+
break;
161+
}
162+
163+
}
164+
}
165+
166+
return $matrix;
167+
}
168+
115169
}

src/Data/QRData.php

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -94,12 +94,13 @@ public function setData(array $dataSegments):self{
9494
* returns a fresh matrix object with the data written and masked with the given $maskPattern
9595
*/
9696
public function writeMatrix(MaskPattern $maskPattern):QRMatrix{
97-
$data = (new ReedSolomonEncoder)->interleaveEcBytes($this->bitBuffer, $this->version, $this->eccLevel);
98-
99-
return (new QRMatrix($this->version, $this->eccLevel))
97+
$matrix = (new QRMatrix($this->version, $this->eccLevel))
10098
->initFunctionalPatterns()
10199
->initFormatInfo($maskPattern)
102-
->mapData($data)
100+
;
101+
102+
return (new ReedSolomonEncoder)
103+
->interleaveEcBytes($this->bitBuffer, $matrix)
103104
->mask($maskPattern)
104105
;
105106
}

src/Data/QRMatrix.php

Lines changed: 0 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -532,68 +532,6 @@ public function setLogoSpace(int $width, int $height, int $startX = null, int $s
532532
return $this;
533533
}
534534

535-
/**
536-
* Maps the binary $data array from QRData::maskECC() on the matrix,
537-
* masking the data using $maskPattern (ISO/IEC 18004:2000 Section 8.8)
538-
*
539-
* @see \chillerlan\QRCode\Data\QRData::maskECC()
540-
*
541-
* @param \SplFixedArray<int> $data
542-
*
543-
* @return \chillerlan\QRCode\Data\QRMatrix
544-
*/
545-
public function mapData(SplFixedArray $data):self{
546-
$byteCount = $data->count();
547-
$y = $this->moduleCount - 1;
548-
$inc = -1;
549-
$byteIndex = 0;
550-
$bitIndex = 7;
551-
552-
for($i = $y; $i > 0; $i -= 2){
553-
554-
if($i === 6){
555-
$i--;
556-
}
557-
558-
while(true){
559-
for($c = 0; $c < 2; $c++){
560-
$x = $i - $c;
561-
562-
if($this->matrix[$y][$x] !== $this::M_NULL){
563-
continue;
564-
}
565-
566-
$v = false;
567-
568-
if($byteIndex < $byteCount){
569-
$v = (($data[$byteIndex] >> $bitIndex) & 1) === 1;
570-
}
571-
572-
$this->matrix[$y][$x] = $this::M_DATA | ($v ? $this::IS_DARK : 0);
573-
$bitIndex--;
574-
575-
if($bitIndex === -1){
576-
$byteIndex++;
577-
$bitIndex = 7;
578-
}
579-
580-
}
581-
582-
$y += $inc;
583-
584-
if($y < 0 || $this->moduleCount <= $y){
585-
$y -= $inc;
586-
$inc = -$inc;
587-
588-
break;
589-
}
590-
591-
}
592-
}
593-
594-
return $this;
595-
}
596-
597535
/**
598536
* Applies the mask pattern
599537
*

0 commit comments

Comments
 (0)