Просмотр исходного кода

:shower: extract methods and move to ReedSolomonDecoder

smiley 3 лет назад
Родитель
Сommit
f1b05e420d
2 измененных файлов с 44 добавлено и 39 удалено
  1. 43 1
      src/Common/ReedSolomonDecoder.php
  2. 1 38
      src/Decoder/Decoder.php

+ 43 - 1
src/Common/ReedSolomonDecoder.php

@@ -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
src/Decoder/Decoder.php

@@ -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
 	 */