mirror of
https://github.com/chillerlan/php-qrcode.git
synced 2026-09-01 21:18:16 +00:00
🚿 moved interleaved data mapping from QRMatrix to ReedSolomonEncoder
This commit is contained in:
@@ -10,8 +10,7 @@
|
||||
|
||||
namespace chillerlan\QRCode\Common;
|
||||
|
||||
use SplFixedArray;
|
||||
|
||||
use chillerlan\QRCode\Data\QRMatrix;
|
||||
use function array_fill, array_merge, count, max;
|
||||
|
||||
/**
|
||||
@@ -21,16 +20,15 @@ use function array_fill, array_merge, count, max;
|
||||
*/
|
||||
final class ReedSolomonEncoder{
|
||||
|
||||
private SplFixedArray $interleavedData;
|
||||
private int $interleavedDataIndex;
|
||||
private array $interleavedData;
|
||||
private int $interleavedDataIndex;
|
||||
|
||||
/**
|
||||
* ECC interleaving
|
||||
*
|
||||
* @return \SplFixedArray<int>
|
||||
*/
|
||||
public function interleaveEcBytes(BitBuffer $bitBuffer, Version $version, EccLevel $eccLevel):SplFixedArray{
|
||||
[$numEccCodewords, [[$l1, $b1], [$l2, $b2]]] = $version->getRSBlocks($eccLevel);
|
||||
public function interleaveEcBytes(BitBuffer $bitBuffer, QRMatrix $matrix):QRMatrix{
|
||||
$version = $matrix->version();
|
||||
[$numEccCodewords, [[$l1, $b1], [$l2, $b2]]] = $version->getRSBlocks($matrix->eccLevel());
|
||||
|
||||
$rsBlocks = array_fill(0, $l1, [$numEccCodewords + $b1, $b1]);
|
||||
|
||||
@@ -61,14 +59,14 @@ final class ReedSolomonEncoder{
|
||||
$dataByteOffset += $dataByteCount;
|
||||
}
|
||||
|
||||
$this->interleavedData = new SplFixedArray($version->getTotalCodewords());
|
||||
$this->interleavedData = array_fill(0, $version->getTotalCodewords(), 0);
|
||||
$this->interleavedDataIndex = 0;
|
||||
$numRsBlocks = $l1 + $l2;
|
||||
|
||||
$this->interleave($dataBytes, $maxDataBytes, $numRsBlocks);
|
||||
$this->interleave($ecBytes, $maxEcBytes, $numRsBlocks);
|
||||
|
||||
return $this->interleavedData;
|
||||
return $this->mapData($matrix);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -112,4 +110,60 @@ final class ReedSolomonEncoder{
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Maps the interleaved binary $data on the matrix
|
||||
*/
|
||||
private function mapData(QRMatrix $matrix):QRMatrix{
|
||||
$byteCount = count($this->interleavedData);
|
||||
$size = $matrix->size();
|
||||
$y = $size - 1;
|
||||
$inc = -1;
|
||||
$byteIndex = 0;
|
||||
$bitIndex = 7;
|
||||
|
||||
for($i = $y; $i > 0; $i -= 2){
|
||||
|
||||
if($i === 6){
|
||||
$i--;
|
||||
}
|
||||
|
||||
while(true){
|
||||
for($c = 0; $c < 2; $c++){
|
||||
$x = $i - $c;
|
||||
|
||||
if($matrix->get($x, $y) !== QRMatrix::M_NULL){
|
||||
continue;
|
||||
}
|
||||
|
||||
$v = false;
|
||||
|
||||
if($byteIndex < $byteCount){
|
||||
$v = (($this->interleavedData[$byteIndex] >> $bitIndex) & 1) === 1;
|
||||
}
|
||||
|
||||
$matrix->set($x, $y, $v, QRMatrix::M_DATA);
|
||||
$bitIndex--;
|
||||
|
||||
if($bitIndex === -1){
|
||||
$byteIndex++;
|
||||
$bitIndex = 7;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$y += $inc;
|
||||
|
||||
if($y < 0 || $size <= $y){
|
||||
$y -= $inc;
|
||||
$inc = -$inc;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return $matrix;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+5
-4
@@ -94,12 +94,13 @@ final class QRData{
|
||||
* returns a fresh matrix object with the data written and masked with the given $maskPattern
|
||||
*/
|
||||
public function writeMatrix(MaskPattern $maskPattern):QRMatrix{
|
||||
$data = (new ReedSolomonEncoder)->interleaveEcBytes($this->bitBuffer, $this->version, $this->eccLevel);
|
||||
|
||||
return (new QRMatrix($this->version, $this->eccLevel))
|
||||
$matrix = (new QRMatrix($this->version, $this->eccLevel))
|
||||
->initFunctionalPatterns()
|
||||
->initFormatInfo($maskPattern)
|
||||
->mapData($data)
|
||||
;
|
||||
|
||||
return (new ReedSolomonEncoder)
|
||||
->interleaveEcBytes($this->bitBuffer, $matrix)
|
||||
->mask($maskPattern)
|
||||
;
|
||||
}
|
||||
|
||||
@@ -532,68 +532,6 @@ final class QRMatrix{
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Maps the binary $data array from QRData::maskECC() on the matrix,
|
||||
* masking the data using $maskPattern (ISO/IEC 18004:2000 Section 8.8)
|
||||
*
|
||||
* @see \chillerlan\QRCode\Data\QRData::maskECC()
|
||||
*
|
||||
* @param \SplFixedArray<int> $data
|
||||
*
|
||||
* @return \chillerlan\QRCode\Data\QRMatrix
|
||||
*/
|
||||
public function mapData(SplFixedArray $data):self{
|
||||
$byteCount = $data->count();
|
||||
$y = $this->moduleCount - 1;
|
||||
$inc = -1;
|
||||
$byteIndex = 0;
|
||||
$bitIndex = 7;
|
||||
|
||||
for($i = $y; $i > 0; $i -= 2){
|
||||
|
||||
if($i === 6){
|
||||
$i--;
|
||||
}
|
||||
|
||||
while(true){
|
||||
for($c = 0; $c < 2; $c++){
|
||||
$x = $i - $c;
|
||||
|
||||
if($this->matrix[$y][$x] !== $this::M_NULL){
|
||||
continue;
|
||||
}
|
||||
|
||||
$v = false;
|
||||
|
||||
if($byteIndex < $byteCount){
|
||||
$v = (($data[$byteIndex] >> $bitIndex) & 1) === 1;
|
||||
}
|
||||
|
||||
$this->matrix[$y][$x] = $this::M_DATA | ($v ? $this::IS_DARK : 0);
|
||||
$bitIndex--;
|
||||
|
||||
if($bitIndex === -1){
|
||||
$byteIndex++;
|
||||
$bitIndex = 7;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$y += $inc;
|
||||
|
||||
if($y < 0 || $this->moduleCount <= $y){
|
||||
$y -= $inc;
|
||||
$inc = -$inc;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies the mask pattern
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user