Skip to content

Commit 17c570b

Browse files
authored
Merge pull request #158 from LZZZZ/binary_mode
Added a new hint `BINARY_MODE` to allow working with binary QRCodes.
2 parents 7e0cbfa + a992372 commit 17c570b

File tree

5 files changed

+52
-19
lines changed

5 files changed

+52
-19
lines changed

lib/Qrcode/Decoder/DecodedBitStreamParser.php

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -309,24 +309,27 @@ private static function decodeByteSegment(
309309
$readBytes[$i] = $bits->readBits(8); //(byte)
310310
}
311311
$text = implode(array_map('chr', $readBytes));
312-
$encoding = '';
313-
if ($currentCharacterSetECI == null) {
314-
// The spec isn't clear on this mode; see
315-
// section 6.4.5: t does not say which encoding to assuming
316-
// upon decoding. I have seen ISO-8859-1 used as well as
317-
// Shift_JIS -- without anything like an ECI designator to
318-
// give a hint.
312+
if ($hints !== null && array_key_exists('BINARY_MODE', $hints) && $hints['BINARY_MODE']) {
313+
$result .= $text;
314+
} else {
315+
$encoding = '';
316+
if ($currentCharacterSetECI == null) {
317+
// The spec isn't clear on this mode; see
318+
// section 6.4.5: t does not say which encoding to assuming
319+
// upon decoding. I have seen ISO-8859-1 used as well as
320+
// Shift_JIS -- without anything like an ECI designator to
321+
// give a hint.
319322

320-
try {
321-
$encoding = mb_detect_encoding($text, $hints);
322-
} catch (ValueError $e) {
323-
$encoding = mb_detect_encoding($text, mb_detect_order(), false);
324-
}
325-
} else {
326-
$encoding = $currentCharacterSetECI->name();
327-
}
328-
$result .= mb_convert_encoding($text, $encoding); //(new String(readBytes, encoding));
329-
// $result .= $text; //(new String(readBytes, encoding));
323+
try {
324+
$encoding = mb_detect_encoding($text, $hints);
325+
} catch (ValueError $e) {
326+
$encoding = mb_detect_encoding($text, mb_detect_order(), false);
327+
}
328+
} else {
329+
$encoding = $currentCharacterSetECI->name();
330+
}
331+
$result .= mb_convert_encoding($text, $encoding); //(new String(readBytes, encoding));
332+
}
330333

331334
$byteSegments = array_merge($byteSegments, $readBytes);
332335
}

lib/Qrcode/Decoder/Decoder.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ public function decodeBits(\Zxing\Common\BitMatrix $bits, $hints = null): string
147147
}
148148
}
149149

150-
private function decodeParser(\Zxing\Qrcode\Decoder\BitMatrixParser $parser, array $hints = null): DecoderResult
150+
private function decodeParser(\Zxing\Qrcode\Decoder\BitMatrixParser $parser, ?array $hints = null): DecoderResult
151151
{
152152
$version = $parser->readVersion();
153153
$ecLevel = $parser->readFormatInformation()->getErrorCorrectionLevel();

lib/Qrcode/Detector/Detector.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ public function __construct(private BitMatrix $image)
5252
* @throws NotFoundException if QR Code cannot be found
5353
* @throws FormatException if a QR Code cannot be decoded
5454
*/
55-
final public function detect(array $hints = null): DetectorResult
55+
final public function detect(?array $hints = null): DetectorResult
5656
{/*Map<DecodeHintType,?>*/
5757

5858
$resultPointCallback = ($hints !== null && array_key_exists('NEED_RESULT_POINT_CALLBACK', $hints)) ?

tests/QrReaderTest.php

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,36 @@ public function testText3()
5555
$this->assertSame("https://www.gosuslugi.ru/covid-cert/verify/9770000014233333?lang=ru&ck=733a9d218d312fe134f1c2cc06e1a800", $qrcode->text());
5656
}
5757

58+
/**
59+
* The following test is meant to check if it works with QRCodes containing raw binary data.
60+
* The test qrcode image was generated with `qrencode -8 -r 'binary-test.bin' -o 'test-binary-test.png'`.
61+
*
62+
* @return void
63+
*/
64+
public function testBinary() {
65+
$image = __DIR__ . "/qrcodes/binary-test.png";
66+
$expected = hex2bin(
67+
'000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f'.
68+
'202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f'.
69+
'404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f'.
70+
'606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f'.
71+
'808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f'.
72+
'a0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebf'.
73+
'c0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedf'.
74+
'e0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff'
75+
);
76+
77+
$qrcode = new QrReader($image);
78+
$qrcode->decode([
79+
'BINARY_MODE' => true
80+
]);
81+
$this->assertSame(null, $qrcode->getError());
82+
$result = $qrcode->getResult();
83+
$this->assertInstanceOf(Result::class, $result);
84+
$text = $result->getText();
85+
$this->assertEquals($expected, $text);
86+
}
87+
5888
// TODO: fix this test
5989
// public function testText4()
6090
// {

tests/qrcodes/binary-test.png

1 KB
Loading

0 commit comments

Comments
 (0)