🚿 extract methods and move to ReedSolomonDecoder

This commit is contained in:
smiley
2022-05-10 14:05:52 +02:00
parent 10e1162d0e
commit f1b05e420d
2 changed files with 44 additions and 39 deletions
+43 -1
View File
@@ -34,6 +34,48 @@ use function array_fill, array_reverse, count;
*/
final class ReedSolomonDecoder{
/**
* Error-correct and copy data blocks together into a stream of bytes
*/
public function decode(array $dataBlocks):array{
$resultBytes = [];
foreach($dataBlocks as $dataBlock){
[$numDataCodewords, $codewordBytes] = $dataBlock;
$corrected = $this->correctErrors($codewordBytes, $numDataCodewords);
for($i = 0; $i < $numDataCodewords; $i++){
$resultBytes[] = $corrected[$i];
}
}
return $resultBytes;
}
/**
* Given data and error-correction codewords received, possibly corrupted by errors, attempts to
* correct the errors in-place using Reed-Solomon error correction.
*/
private function correctErrors(array $codewordBytes, int $numDataCodewords):array{
// First read into an array of ints
$codewordsInts = [];
foreach($codewordBytes as $codewordByte){
$codewordsInts[] = $codewordByte & 0xFF;
}
$decoded = $this->decodeWords($codewordsInts, (count($codewordBytes) - $numDataCodewords));
// Copy back into array of bytes -- only need to worry about the bytes that were data
// We don't care about errors in the error-correction codewords
for($i = 0; $i < $numDataCodewords; $i++){
$codewordBytes[$i] = $decoded[$i];
}
return $codewordBytes;
}
/**
* Decodes given set of received codewords, which include both data and error-correction
* codewords. Really, this means it uses Reed-Solomon to detect and correct errors, in-place,
@@ -45,7 +87,7 @@ final class ReedSolomonDecoder{
* @return int[]
* @throws \RuntimeException if decoding fails for any reason
*/
public function decode(array $received, int $numEccCodewords):array{
private function decodeWords(array $received, int $numEccCodewords):array{
$poly = new GenericGFPoly($received);
$syndromeCoefficients = [];
$error = false;
+1 -38
View File
@@ -83,21 +83,7 @@ final class Decoder{
}
$this->eccLevel = $this->formatInfo->getErrorCorrectionLevel();
$dataBlocks = $this->getDataBlocks($rawCodewords);
$resultBytes = [];
$resultOffset = 0;
// Error-correct and copy data blocks together into a stream of bytes
foreach($dataBlocks as $dataBlock){
[$numDataCodewords, $codewordBytes] = $dataBlock;
$corrected = $this->correctErrors($codewordBytes, $numDataCodewords);
for($i = 0; $i < $numDataCodewords; $i++){
$resultBytes[$resultOffset++] = $corrected[$i];
}
}
$resultBytes = (new ReedSolomonDecoder)->decode($this->getDataBlocks($rawCodewords));
// Decode the contents of that stream of bytes
return $this->decodeBitStream($resultBytes);
}
@@ -178,29 +164,6 @@ final class Decoder{
return $result;
}
/**
* Given data and error-correction codewords received, possibly corrupted by errors, attempts to
* correct the errors in-place using Reed-Solomon error correction.
*/
private function correctErrors(array $codewordBytes, int $numDataCodewords):array{
// First read into an array of ints
$codewordsInts = [];
foreach($codewordBytes as $i => $codewordByte){
$codewordsInts[$i] = $codewordByte & 0xFF;
}
$decoded = (new ReedSolomonDecoder)->decode($codewordsInts, (count($codewordBytes) - $numDataCodewords));
// Copy back into array of bytes -- only need to worry about the bytes that were data
// We don't care about errors in the error-correction codewords
for($i = 0; $i < $numDataCodewords; $i++){
$codewordBytes[$i] = $decoded[$i];
}
return $codewordBytes;
}
/**
* @throws \chillerlan\QRCode\Decoder\QRCodeDecoderException
*/