mirror of
https://github.com/chillerlan/php-qrcode.git
synced 2026-08-24 12:37:53 +00:00
:octocat: move deinterleaving to ReedSolomonDecoder
This commit is contained in:
+5
-81
@@ -78,96 +78,20 @@ final class Decoder{
|
||||
throw new QRCodeDecoderException('unable to read version or format info'); // @codeCoverageIgnore
|
||||
}
|
||||
|
||||
$resultBytes = (new ReedSolomonDecoder)->decode($this->getDataBlocks($rawCodewords));
|
||||
// Decode the contents of that stream of bytes
|
||||
$resultBytes = (new ReedSolomonDecoder($this->version, $this->eccLevel))->decode($rawCodewords);
|
||||
|
||||
return $this->decodeBitStream($resultBytes);
|
||||
}
|
||||
|
||||
/**
|
||||
* When QR Codes use multiple data blocks, they are actually interleaved.
|
||||
* That is, the first byte of data block 1 to n is written, then the second bytes, and so on. This
|
||||
* method will separate the data into original blocks.
|
||||
* Decode the contents of that stream of bytes
|
||||
*
|
||||
* @param array $rawCodewords bytes as read directly from the QR Code
|
||||
*
|
||||
* @return array DataBlocks containing original bytes, "de-interleaved" from representation in the QR Code
|
||||
* @throws \chillerlan\QRCode\Decoder\QRCodeDecoderException
|
||||
*/
|
||||
private function getDataBlocks(array $rawCodewords):array{
|
||||
|
||||
// Figure out the number and size of data blocks used by this version and
|
||||
// error correction level
|
||||
/** @phan-suppress-next-line PhanTypeMismatchArgumentNullable */
|
||||
[$numEccCodewords, $eccBlocks] = $this->version->getRSBlocks($this->eccLevel);
|
||||
|
||||
// Now establish DataBlocks of the appropriate size and number of data codewords
|
||||
$result = [];//new DataBlock[$totalBlocks];
|
||||
$numResultBlocks = 0;
|
||||
|
||||
foreach($eccBlocks as $blockData){
|
||||
[$numEccBlocks, $eccPerBlock] = $blockData;
|
||||
|
||||
for($i = 0; $i < $numEccBlocks; $i++, $numResultBlocks++){
|
||||
$result[$numResultBlocks] = [$eccPerBlock, array_fill(0, $numEccCodewords + $eccPerBlock, 0)];
|
||||
}
|
||||
}
|
||||
|
||||
// All blocks have the same amount of data, except that the last n
|
||||
// (where n may be 0) have 1 more byte. Figure out where these start.
|
||||
/** @phan-suppress-next-line PhanTypePossiblyInvalidDimOffset */
|
||||
$shorterBlocksTotalCodewords = count($result[0][1]);
|
||||
$longerBlocksStartAt = count($result) - 1;
|
||||
|
||||
while($longerBlocksStartAt >= 0){
|
||||
$numCodewords = count($result[$longerBlocksStartAt][1]);
|
||||
|
||||
if($numCodewords == $shorterBlocksTotalCodewords){
|
||||
break;
|
||||
}
|
||||
|
||||
$longerBlocksStartAt--;
|
||||
}
|
||||
|
||||
$longerBlocksStartAt++;
|
||||
|
||||
$shorterBlocksNumDataCodewords = $shorterBlocksTotalCodewords - $numEccCodewords;
|
||||
// The last elements of result may be 1 element longer;
|
||||
// first fill out as many elements as all of them have
|
||||
$rawCodewordsOffset = 0;
|
||||
|
||||
for($i = 0; $i < $shorterBlocksNumDataCodewords; $i++){
|
||||
for($j = 0; $j < $numResultBlocks; $j++){
|
||||
$result[$j][1][$i] = $rawCodewords[$rawCodewordsOffset++];
|
||||
}
|
||||
}
|
||||
|
||||
// Fill out the last data block in the longer ones
|
||||
for($j = $longerBlocksStartAt; $j < $numResultBlocks; $j++){
|
||||
$result[$j][1][$shorterBlocksNumDataCodewords] = $rawCodewords[$rawCodewordsOffset++];
|
||||
}
|
||||
|
||||
// Now add in error correction blocks
|
||||
/** @phan-suppress-next-line PhanTypePossiblyInvalidDimOffset */
|
||||
$max = count($result[0][1]);
|
||||
|
||||
for($i = $shorterBlocksNumDataCodewords; $i < $max; $i++){
|
||||
for($j = 0; $j < $numResultBlocks; $j++){
|
||||
$iOffset = $j < $longerBlocksStartAt ? $i : $i + 1;
|
||||
$result[$j][1][$iOffset] = $rawCodewords[$rawCodewordsOffset++];
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws \chillerlan\QRCode\Decoder\QRCodeDecoderException
|
||||
*/
|
||||
private function decodeBitStream(array $bytes):DecoderResult{
|
||||
$bitBuffer = new BitBuffer($bytes);
|
||||
private function decodeBitStream(BitBuffer $bitBuffer):DecoderResult{
|
||||
$versionNumber = $this->version->getVersionNumber();
|
||||
$symbolSequence = -1;
|
||||
$parityData = -1;
|
||||
$versionNumber = $this->version->getVersionNumber();
|
||||
$eciCharset = null;
|
||||
$fc1InEffect = false;
|
||||
$result = '';
|
||||
|
||||
Reference in New Issue
Block a user