diff --git a/lib/Qrcode/Decoder/DecodedBitStreamParser.php b/lib/Qrcode/Decoder/DecodedBitStreamParser.php index 147361b..ae211cd 100644 --- a/lib/Qrcode/Decoder/DecodedBitStreamParser.php +++ b/lib/Qrcode/Decoder/DecodedBitStreamParser.php @@ -309,24 +309,27 @@ private static function decodeByteSegment( $readBytes[$i] = $bits->readBits(8); //(byte) } $text = implode(array_map('chr', $readBytes)); - $encoding = ''; - if ($currentCharacterSetECI == null) { - // The spec isn't clear on this mode; see - // section 6.4.5: t does not say which encoding to assuming - // upon decoding. I have seen ISO-8859-1 used as well as - // Shift_JIS -- without anything like an ECI designator to - // give a hint. + if ($hints !== null && array_key_exists('BINARY_MODE', $hints) && $hints['BINARY_MODE']) { + $result .= $text; + } else { + $encoding = ''; + if ($currentCharacterSetECI == null) { + // The spec isn't clear on this mode; see + // section 6.4.5: t does not say which encoding to assuming + // upon decoding. I have seen ISO-8859-1 used as well as + // Shift_JIS -- without anything like an ECI designator to + // give a hint. - try { - $encoding = mb_detect_encoding($text, $hints); - } catch (ValueError $e) { - $encoding = mb_detect_encoding($text, mb_detect_order(), false); - } - } else { - $encoding = $currentCharacterSetECI->name(); - } - $result .= mb_convert_encoding($text, $encoding); //(new String(readBytes, encoding)); - // $result .= $text; //(new String(readBytes, encoding)); + try { + $encoding = mb_detect_encoding($text, $hints); + } catch (ValueError $e) { + $encoding = mb_detect_encoding($text, mb_detect_order(), false); + } + } else { + $encoding = $currentCharacterSetECI->name(); + } + $result .= mb_convert_encoding($text, $encoding); //(new String(readBytes, encoding)); + } $byteSegments = array_merge($byteSegments, $readBytes); } diff --git a/lib/Qrcode/Decoder/Decoder.php b/lib/Qrcode/Decoder/Decoder.php index c88279e..c6b0f89 100644 --- a/lib/Qrcode/Decoder/Decoder.php +++ b/lib/Qrcode/Decoder/Decoder.php @@ -147,7 +147,7 @@ public function decodeBits(\Zxing\Common\BitMatrix $bits, $hints = null): string } } - private function decodeParser(\Zxing\Qrcode\Decoder\BitMatrixParser $parser, array $hints = null): DecoderResult + private function decodeParser(\Zxing\Qrcode\Decoder\BitMatrixParser $parser, ?array $hints = null): DecoderResult { $version = $parser->readVersion(); $ecLevel = $parser->readFormatInformation()->getErrorCorrectionLevel(); diff --git a/lib/Qrcode/Detector/Detector.php b/lib/Qrcode/Detector/Detector.php index f3dac17..9bd4734 100644 --- a/lib/Qrcode/Detector/Detector.php +++ b/lib/Qrcode/Detector/Detector.php @@ -52,7 +52,7 @@ public function __construct(private BitMatrix $image) * @throws NotFoundException if QR Code cannot be found * @throws FormatException if a QR Code cannot be decoded */ - final public function detect(array $hints = null): DetectorResult + final public function detect(?array $hints = null): DetectorResult {/*Map*/ $resultPointCallback = ($hints !== null && array_key_exists('NEED_RESULT_POINT_CALLBACK', $hints)) ? diff --git a/tests/QrReaderTest.php b/tests/QrReaderTest.php index 68dd7b7..4368a86 100644 --- a/tests/QrReaderTest.php +++ b/tests/QrReaderTest.php @@ -55,6 +55,36 @@ public function testText3() $this->assertSame("https://www.gosuslugi.ru/covid-cert/verify/9770000014233333?lang=ru&ck=733a9d218d312fe134f1c2cc06e1a800", $qrcode->text()); } + /** + * The following test is meant to check if it works with QRCodes containing raw binary data. + * The test qrcode image was generated with `qrencode -8 -r 'binary-test.bin' -o 'test-binary-test.png'`. + * + * @return void + */ + public function testBinary() { + $image = __DIR__ . "/qrcodes/binary-test.png"; + $expected = hex2bin( + '000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f'. + '202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f'. + '404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f'. + '606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f'. + '808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f'. + 'a0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebf'. + 'c0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedf'. + 'e0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff' + ); + + $qrcode = new QrReader($image); + $qrcode->decode([ + 'BINARY_MODE' => true + ]); + $this->assertSame(null, $qrcode->getError()); + $result = $qrcode->getResult(); + $this->assertInstanceOf(Result::class, $result); + $text = $result->getText(); + $this->assertEquals($expected, $text); + } + // TODO: fix this test // public function testText4() // { diff --git a/tests/qrcodes/binary-test.png b/tests/qrcodes/binary-test.png new file mode 100644 index 0000000..b2fc3b6 Binary files /dev/null and b/tests/qrcodes/binary-test.png differ