@sythos/js_barcode_universal 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +215 -0
- package/NOTICE.md +106 -0
- package/README.md +433 -0
- package/bundle/sythos-barcode.esm.js +7998 -0
- package/bundle/sythos-barcode.js +7948 -0
- package/examples/create.html +731 -0
- package/examples/read.html +341 -0
- package/licenses/README.md +42 -0
- package/licenses/codabar.license +74 -0
- package/licenses/code-11.license +69 -0
- package/licenses/code-128.license +69 -0
- package/licenses/code-39.license +70 -0
- package/licenses/code-93.license +71 -0
- package/licenses/ean-13.license +70 -0
- package/licenses/ean-8.license +70 -0
- package/licenses/gs1-128.license +71 -0
- package/licenses/isbn.license +76 -0
- package/licenses/itf-14.license +69 -0
- package/licenses/itf.license +70 -0
- package/licenses/msi-plessey.license +72 -0
- package/licenses/pharmacode.license +71 -0
- package/licenses/qr-code.license +75 -0
- package/licenses/upc-a.license +72 -0
- package/licenses/upc-e.license +69 -0
- package/package.json +89 -0
- package/src/core/bit-buffer.js +174 -0
- package/src/core/bit-matrix.js +241 -0
- package/src/core/errors.js +61 -0
- package/src/core/galois-field.js +204 -0
- package/src/core/index.js +56 -0
- package/src/core/reed-solomon.js +313 -0
- package/src/image/binarizer.js +270 -0
- package/src/image/grid-sampler.js +164 -0
- package/src/image/index.js +40 -0
- package/src/image/luminance.js +196 -0
- package/src/image/perspective.js +195 -0
- package/src/index.js +240 -0
- package/src/oned/index.js +89 -0
- package/src/oned/patterns.js +384 -0
- package/src/oned/reader.js +918 -0
- package/src/oned/writers.js +741 -0
- package/src/qr/decoder.js +575 -0
- package/src/qr/detector.js +630 -0
- package/src/qr/encoder.js +958 -0
- package/src/qr/index.js +44 -0
- package/src/qr/tables.js +737 -0
- package/src/render/image-data.js +125 -0
- package/src/render/index.js +130 -0
- package/src/render/options.js +160 -0
- package/src/render/png.js +295 -0
- package/src/render/svg.js +120 -0
- package/src/render/webgl.js +206 -0
- package/src/render/webgpu.js +369 -0
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
QR Code — format provenance and usability
|
|
2
|
+
==========================================================================
|
|
3
|
+
|
|
4
|
+
This file records where the QR Code symbology comes from, what governs
|
|
5
|
+
it, and the basis on which this project implements and redistributes it.
|
|
6
|
+
|
|
7
|
+
It is an ENGINEERING INVENTORY, NOT LEGAL ADVICE. Items marked [TO VERIFY]
|
|
8
|
+
have not been independently confirmed by the author.
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
ORIGIN
|
|
12
|
+
--------------------------------------------------------------------------
|
|
13
|
+
|
|
14
|
+
Devised by DENSO WAVE INCORPORATED (Japan) in 1994, for tracking parts in
|
|
15
|
+
vehicle manufacturing.
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
SPECIFICATION
|
|
19
|
+
--------------------------------------------------------------------------
|
|
20
|
+
|
|
21
|
+
ISO/IEC 18004 — QR Code bar code symbology specification.
|
|
22
|
+
Published by ISO/IEC. The specification TEXT is copyrighted by its
|
|
23
|
+
publisher and is paywalled; it is not reproduced here.
|
|
24
|
+
|
|
25
|
+
Specification TEXT is copyrighted by its publisher. The SYMBOLOGY it
|
|
26
|
+
describes is not — an encoding scheme is a system, not a work of
|
|
27
|
+
authorship. This project implements the symbology; it does not reproduce,
|
|
28
|
+
redistribute or excerpt any specification document.
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
PATENT STATUS
|
|
32
|
+
--------------------------------------------------------------------------
|
|
33
|
+
|
|
34
|
+
DENSO WAVE holds patents relating to QR Code and has publicly stated that
|
|
35
|
+
it does not exercise those rights for the standardised symbology, which is
|
|
36
|
+
what made QR Code ubiquitous. [TO VERIFY]
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
TRADEMARK
|
|
40
|
+
--------------------------------------------------------------------------
|
|
41
|
+
|
|
42
|
+
"QR Code" is a REGISTERED TRADEMARK of DENSO WAVE INCORPORATED. This is
|
|
43
|
+
the most important entry in this file: the mark does not restrict
|
|
44
|
+
implementing the symbology, but it does constrain how a product is NAMED
|
|
45
|
+
and BRANDED. Describing software as "reads QR Code" is descriptive use;
|
|
46
|
+
naming a product "QR Code Studio" is not.
|
|
47
|
+
|
|
48
|
+
A trademark does not restrict implementing a symbology. It restricts
|
|
49
|
+
branding — how a product names and presents itself.
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
IMPLEMENTATION BASIS IN THIS PROJECT
|
|
53
|
+
--------------------------------------------------------------------------
|
|
54
|
+
|
|
55
|
+
QR Code is implemented here from published descriptions of the format,
|
|
56
|
+
which are systems and facts rather than works of authorship. No source
|
|
57
|
+
code and no constant table from any other barcode implementation was used,
|
|
58
|
+
consulted or copied, under any licence.
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
CONCLUSION
|
|
62
|
+
--------------------------------------------------------------------------
|
|
63
|
+
|
|
64
|
+
On the basis of the references below, QR Code is understood to be freely
|
|
65
|
+
implementable and redistributable, and this project's implementation of it
|
|
66
|
+
is distributed under the MIT License with no additional restriction.
|
|
67
|
+
|
|
68
|
+
References relied upon:
|
|
69
|
+
- ISO/IEC 18004, ISO/IEC
|
|
70
|
+
- DENSO WAVE's published position on its QR Code patent rights [TO VERIFY]
|
|
71
|
+
- QR Code trademark registration, DENSO WAVE INCORPORATED [TO VERIFY]
|
|
72
|
+
|
|
73
|
+
This is an engineering assessment, not legal advice. Items marked
|
|
74
|
+
[TO VERIFY] have not been independently confirmed by the author. If your
|
|
75
|
+
use is commercially sensitive, obtain your own legal review.
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
UPC-A — format provenance and usability
|
|
2
|
+
==========================================================================
|
|
3
|
+
|
|
4
|
+
This file records where the UPC-A symbology comes from, what governs
|
|
5
|
+
it, and the basis on which this project implements and redistributes it.
|
|
6
|
+
|
|
7
|
+
It is an ENGINEERING INVENTORY, NOT LEGAL ADVICE. Items marked [TO VERIFY]
|
|
8
|
+
have not been independently confirmed by the author.
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
ORIGIN
|
|
12
|
+
--------------------------------------------------------------------------
|
|
13
|
+
|
|
14
|
+
The Universal Product Code, adopted in the United States in 1973 and first
|
|
15
|
+
scanned in retail in 1974. The symbol encoding is commonly credited to
|
|
16
|
+
work at IBM, but the corporate and personal credit is [TO VERIFY] and no
|
|
17
|
+
individual is named here. Administered today by GS1.
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
SPECIFICATION
|
|
21
|
+
--------------------------------------------------------------------------
|
|
22
|
+
|
|
23
|
+
ISO/IEC 15420 — EAN/UPC bar code symbology specification.
|
|
24
|
+
GS1 General Specifications, GS1 AISBL — freely published; redistribution
|
|
25
|
+
terms are GS1's own [TO VERIFY]
|
|
26
|
+
|
|
27
|
+
Specification TEXT is copyrighted by its publisher. The SYMBOLOGY it
|
|
28
|
+
describes is not — an encoding scheme is a system, not a work of
|
|
29
|
+
authorship. This project implements the symbology; it does not reproduce,
|
|
30
|
+
redistribute or excerpt any specification document.
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
PATENT STATUS
|
|
34
|
+
--------------------------------------------------------------------------
|
|
35
|
+
|
|
36
|
+
The originating patents date from the early 1970s and are understood to
|
|
37
|
+
have expired long ago. [TO VERIFY]
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
TRADEMARK
|
|
41
|
+
--------------------------------------------------------------------------
|
|
42
|
+
|
|
43
|
+
"GS1" and its symbology names are trademarks of GS1 AISBL.
|
|
44
|
+
|
|
45
|
+
A trademark does not restrict implementing a symbology. It restricts
|
|
46
|
+
branding — how a product names and presents itself.
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
IMPLEMENTATION BASIS IN THIS PROJECT
|
|
50
|
+
--------------------------------------------------------------------------
|
|
51
|
+
|
|
52
|
+
UPC-A is implemented here from published descriptions of the format,
|
|
53
|
+
which are systems and facts rather than works of authorship. No source
|
|
54
|
+
code and no constant table from any other barcode implementation was used,
|
|
55
|
+
consulted or copied, under any licence.
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
CONCLUSION
|
|
59
|
+
--------------------------------------------------------------------------
|
|
60
|
+
|
|
61
|
+
On the basis of the references below, UPC-A is understood to be freely
|
|
62
|
+
implementable and redistributable, and this project's implementation of it
|
|
63
|
+
is distributed under the MIT License with no additional restriction.
|
|
64
|
+
|
|
65
|
+
References relied upon:
|
|
66
|
+
- ISO/IEC 15420, ISO/IEC
|
|
67
|
+
- GS1 General Specifications, GS1 AISBL — freely published;
|
|
68
|
+
redistribution terms are GS1's own [TO VERIFY]
|
|
69
|
+
|
|
70
|
+
This is an engineering assessment, not legal advice. Items marked
|
|
71
|
+
[TO VERIFY] have not been independently confirmed by the author. If your
|
|
72
|
+
use is commercially sensitive, obtain your own legal review.
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
UPC-E — format provenance and usability
|
|
2
|
+
==========================================================================
|
|
3
|
+
|
|
4
|
+
This file records where the UPC-E symbology comes from, what governs
|
|
5
|
+
it, and the basis on which this project implements and redistributes it.
|
|
6
|
+
|
|
7
|
+
It is an ENGINEERING INVENTORY, NOT LEGAL ADVICE. Items marked [TO VERIFY]
|
|
8
|
+
have not been independently confirmed by the author.
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
ORIGIN
|
|
12
|
+
--------------------------------------------------------------------------
|
|
13
|
+
|
|
14
|
+
The zero-suppressed form of UPC-A, encoding six digits in place of twelve
|
|
15
|
+
for small packages. Part of the same GS1-administered family.
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
SPECIFICATION
|
|
19
|
+
--------------------------------------------------------------------------
|
|
20
|
+
|
|
21
|
+
ISO/IEC 15420 — EAN/UPC bar code symbology specification.
|
|
22
|
+
GS1 General Specifications, GS1 AISBL — freely published; redistribution
|
|
23
|
+
terms are GS1's own [TO VERIFY]
|
|
24
|
+
|
|
25
|
+
Specification TEXT is copyrighted by its publisher. The SYMBOLOGY it
|
|
26
|
+
describes is not — an encoding scheme is a system, not a work of
|
|
27
|
+
authorship. This project implements the symbology; it does not reproduce,
|
|
28
|
+
redistribute or excerpt any specification document.
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
PATENT STATUS
|
|
32
|
+
--------------------------------------------------------------------------
|
|
33
|
+
|
|
34
|
+
Shares the patent history of UPC-A; understood expired. [TO VERIFY]
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
TRADEMARK
|
|
38
|
+
--------------------------------------------------------------------------
|
|
39
|
+
|
|
40
|
+
"GS1" and its symbology names are trademarks of GS1 AISBL.
|
|
41
|
+
|
|
42
|
+
A trademark does not restrict implementing a symbology. It restricts
|
|
43
|
+
branding — how a product names and presents itself.
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
IMPLEMENTATION BASIS IN THIS PROJECT
|
|
47
|
+
--------------------------------------------------------------------------
|
|
48
|
+
|
|
49
|
+
UPC-E is implemented here from published descriptions of the format,
|
|
50
|
+
which are systems and facts rather than works of authorship. No source
|
|
51
|
+
code and no constant table from any other barcode implementation was used,
|
|
52
|
+
consulted or copied, under any licence.
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
CONCLUSION
|
|
56
|
+
--------------------------------------------------------------------------
|
|
57
|
+
|
|
58
|
+
On the basis of the references below, UPC-E is understood to be freely
|
|
59
|
+
implementable and redistributable, and this project's implementation of it
|
|
60
|
+
is distributed under the MIT License with no additional restriction.
|
|
61
|
+
|
|
62
|
+
References relied upon:
|
|
63
|
+
- ISO/IEC 15420, ISO/IEC
|
|
64
|
+
- GS1 General Specifications, GS1 AISBL — freely published;
|
|
65
|
+
redistribution terms are GS1's own [TO VERIFY]
|
|
66
|
+
|
|
67
|
+
This is an engineering assessment, not legal advice. Items marked
|
|
68
|
+
[TO VERIFY] have not been independently confirmed by the author. If your
|
|
69
|
+
use is commercially sensitive, obtain your own legal review.
|
package/package.json
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@sythos/js_barcode_universal",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Read and write barcodes in JavaScript. 100% original code, zero runtime dependencies. QR Code, EAN/UPC, ISBN, Code 128, Code 39, Code 93, ITF, Codabar, MSI, Code 11 and Pharmacode.",
|
|
5
|
+
"author": "Sythos",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"type": "module",
|
|
8
|
+
"main": "./src/index.js",
|
|
9
|
+
"module": "./src/index.js",
|
|
10
|
+
"browser": "./bundle/sythos-barcode.js",
|
|
11
|
+
"unpkg": "./bundle/sythos-barcode.js",
|
|
12
|
+
"jsdelivr": "./bundle/sythos-barcode.js",
|
|
13
|
+
"sideEffects": false,
|
|
14
|
+
"engines": {
|
|
15
|
+
"node": ">=18"
|
|
16
|
+
},
|
|
17
|
+
"publishConfig": {
|
|
18
|
+
"access": "public"
|
|
19
|
+
},
|
|
20
|
+
"exports": {
|
|
21
|
+
".": "./src/index.js",
|
|
22
|
+
"./core": "./src/core/index.js",
|
|
23
|
+
"./image": "./src/image/index.js",
|
|
24
|
+
"./oned": "./src/oned/index.js",
|
|
25
|
+
"./qr": "./src/qr/index.js",
|
|
26
|
+
"./render": "./src/render/index.js",
|
|
27
|
+
"./render/svg": "./src/render/svg.js",
|
|
28
|
+
"./render/png": "./src/render/png.js",
|
|
29
|
+
"./render/image-data": "./src/render/image-data.js",
|
|
30
|
+
"./bundle": "./bundle/sythos-barcode.esm.js",
|
|
31
|
+
"./bundle/iife": "./bundle/sythos-barcode.js",
|
|
32
|
+
"./package.json": "./package.json"
|
|
33
|
+
},
|
|
34
|
+
"files": [
|
|
35
|
+
"src",
|
|
36
|
+
"bundle",
|
|
37
|
+
"examples",
|
|
38
|
+
"licenses",
|
|
39
|
+
"LICENSE",
|
|
40
|
+
"NOTICE.md",
|
|
41
|
+
"README.md"
|
|
42
|
+
],
|
|
43
|
+
"keywords": [
|
|
44
|
+
"barcode",
|
|
45
|
+
"barcode-generator",
|
|
46
|
+
"barcode-scanner",
|
|
47
|
+
"qrcode",
|
|
48
|
+
"qr",
|
|
49
|
+
"qr-code",
|
|
50
|
+
"ean",
|
|
51
|
+
"ean13",
|
|
52
|
+
"ean8",
|
|
53
|
+
"upc",
|
|
54
|
+
"upca",
|
|
55
|
+
"upce",
|
|
56
|
+
"isbn",
|
|
57
|
+
"code128",
|
|
58
|
+
"gs1-128",
|
|
59
|
+
"code39",
|
|
60
|
+
"code93",
|
|
61
|
+
"itf",
|
|
62
|
+
"itf14",
|
|
63
|
+
"codabar",
|
|
64
|
+
"msi",
|
|
65
|
+
"code11",
|
|
66
|
+
"pharmacode",
|
|
67
|
+
"scanner",
|
|
68
|
+
"decoder",
|
|
69
|
+
"encoder",
|
|
70
|
+
"generator",
|
|
71
|
+
"reader",
|
|
72
|
+
"writer",
|
|
73
|
+
"zero-dependencies",
|
|
74
|
+
"no-dependencies",
|
|
75
|
+
"browser",
|
|
76
|
+
"nodejs",
|
|
77
|
+
"esm"
|
|
78
|
+
],
|
|
79
|
+
"repository": {
|
|
80
|
+
"type": "git",
|
|
81
|
+
"url": "git+https://github.com/Sythos/JS_Barcode_Universal.git"
|
|
82
|
+
},
|
|
83
|
+
"bugs": {
|
|
84
|
+
"url": "https://github.com/Sythos/JS_Barcode_Universal/issues"
|
|
85
|
+
},
|
|
86
|
+
"homepage": "https://github.com/Sythos/JS_Barcode_Universal#readme",
|
|
87
|
+
"dependencies": {},
|
|
88
|
+
"devDependencies": {}
|
|
89
|
+
}
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Sythos Barcode Suite
|
|
3
|
+
*
|
|
4
|
+
* MIT License
|
|
5
|
+
*
|
|
6
|
+
* Copyright (c) 2026 Sythos
|
|
7
|
+
*
|
|
8
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
9
|
+
* of this software and associated documentation files (the "Software"), to deal
|
|
10
|
+
* in the Software without restriction, including without limitation the rights
|
|
11
|
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
12
|
+
* copies of the Software, and to permit persons to whom the Software is
|
|
13
|
+
* furnished to do so, subject to the following conditions:
|
|
14
|
+
*
|
|
15
|
+
* The above copyright notice and this permission notice shall be included in all
|
|
16
|
+
* copies or substantial portions of the Software.
|
|
17
|
+
*
|
|
18
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
19
|
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
20
|
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
21
|
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
22
|
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
23
|
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
24
|
+
* SOFTWARE.
|
|
25
|
+
*
|
|
26
|
+
* SPDX-License-Identifier: MIT
|
|
27
|
+
*
|
|
28
|
+
* Original work. No code from any other barcode implementation.
|
|
29
|
+
*/
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Bit-level writing and reading, MSB-first.
|
|
33
|
+
*
|
|
34
|
+
* Every 2D symbology serialises its payload as a bitstream that does not
|
|
35
|
+
* respect byte boundaries — QR alone mixes 4-bit mode indicators, 10-bit
|
|
36
|
+
* character-count fields and 11-bit alphanumeric pairs. These two classes are
|
|
37
|
+
* the write and read halves of that.
|
|
38
|
+
*
|
|
39
|
+
* @module core/bit-buffer
|
|
40
|
+
*/
|
|
41
|
+
|
|
42
|
+
import { FormatError } from './errors.js';
|
|
43
|
+
|
|
44
|
+
/** Growable MSB-first bit writer. */
|
|
45
|
+
export class BitWriter {
|
|
46
|
+
constructor() {
|
|
47
|
+
/** @type {number[]} Packed bytes; the last one may be partially filled. */
|
|
48
|
+
this.bytes = [];
|
|
49
|
+
this.bitLength = 0;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/** @returns {number} Bits written so far. */
|
|
53
|
+
get length() {
|
|
54
|
+
return this.bitLength;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Append the low `count` bits of `value`, most significant first.
|
|
59
|
+
*
|
|
60
|
+
* @param {number} value
|
|
61
|
+
* @param {number} count
|
|
62
|
+
*/
|
|
63
|
+
put(value, count) {
|
|
64
|
+
for (let i = count - 1; i >= 0; i--) {
|
|
65
|
+
this.putBit(((value >>> i) & 1) === 1);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/** @param {boolean} bit */
|
|
70
|
+
putBit(bit) {
|
|
71
|
+
const idx = this.bitLength >>> 3;
|
|
72
|
+
if (this.bytes.length <= idx) this.bytes.push(0);
|
|
73
|
+
if (bit) this.bytes[idx] |= 0x80 >>> (this.bitLength & 7);
|
|
74
|
+
this.bitLength++;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/** @param {ArrayLike<number>} data */
|
|
78
|
+
putBytes(data) {
|
|
79
|
+
for (let i = 0; i < data.length; i++) this.put(data[i], 8);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/** Pad with zero bits until the length is a multiple of 8. */
|
|
83
|
+
padToByte() {
|
|
84
|
+
while (this.bitLength & 7) this.putBit(false);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* @returns {Uint8Array} Byte view; trailing bits of the final byte are zero.
|
|
89
|
+
*/
|
|
90
|
+
toBytes() {
|
|
91
|
+
return Uint8Array.from(this.bytes);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/** @returns {string} Debug view, e.g. "0100 0011 0101". */
|
|
95
|
+
toString() {
|
|
96
|
+
let s = '';
|
|
97
|
+
for (let i = 0; i < this.bitLength; i++) {
|
|
98
|
+
if (i && i % 4 === 0) s += ' ';
|
|
99
|
+
s += (this.bytes[i >>> 3] >>> (7 - (i & 7))) & 1;
|
|
100
|
+
}
|
|
101
|
+
return s;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/** MSB-first bit reader over a byte array. */
|
|
106
|
+
export class BitReader {
|
|
107
|
+
/** @param {ArrayLike<number>} bytes */
|
|
108
|
+
constructor(bytes) {
|
|
109
|
+
this.bytes = bytes;
|
|
110
|
+
this.byteOffset = 0;
|
|
111
|
+
this.bitOffset = 0;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/** @returns {number} Bits not yet consumed. */
|
|
115
|
+
available() {
|
|
116
|
+
return 8 * (this.bytes.length - this.byteOffset) - this.bitOffset;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Read `count` bits (1..32) as an unsigned integer, most significant first.
|
|
121
|
+
*
|
|
122
|
+
* @param {number} count
|
|
123
|
+
* @returns {number}
|
|
124
|
+
* @throws {FormatError} If the stream is exhausted.
|
|
125
|
+
*/
|
|
126
|
+
read(count) {
|
|
127
|
+
if (count < 1 || count > 32) {
|
|
128
|
+
throw new FormatError(`BitReader: cannot read ${count} bits`);
|
|
129
|
+
}
|
|
130
|
+
if (count > this.available()) {
|
|
131
|
+
throw new FormatError(
|
|
132
|
+
`BitReader: needed ${count} bits, ${this.available()} remain`
|
|
133
|
+
);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
let result = 0;
|
|
137
|
+
let remaining = count;
|
|
138
|
+
|
|
139
|
+
// Finish the partially consumed byte first, then take whole bytes.
|
|
140
|
+
if (this.bitOffset > 0) {
|
|
141
|
+
const inCurrent = 8 - this.bitOffset;
|
|
142
|
+
const take = Math.min(remaining, inCurrent);
|
|
143
|
+
const shift = inCurrent - take;
|
|
144
|
+
const mask = (0xff >> this.bitOffset) & ~((1 << shift) - 1);
|
|
145
|
+
result = (this.bytes[this.byteOffset] & mask) >> shift;
|
|
146
|
+
remaining -= take;
|
|
147
|
+
this.bitOffset += take;
|
|
148
|
+
if (this.bitOffset === 8) {
|
|
149
|
+
this.bitOffset = 0;
|
|
150
|
+
this.byteOffset++;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
while (remaining >= 8) {
|
|
155
|
+
result = (result << 8) | (this.bytes[this.byteOffset] & 0xff);
|
|
156
|
+
this.byteOffset++;
|
|
157
|
+
remaining -= 8;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
if (remaining > 0) {
|
|
161
|
+
const shift = 8 - remaining;
|
|
162
|
+
const mask = ~((1 << shift) - 1) & 0xff;
|
|
163
|
+
result = (result << remaining) | ((this.bytes[this.byteOffset] & mask) >> shift);
|
|
164
|
+
this.bitOffset += remaining;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
return result >>> 0;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/** @returns {boolean} */
|
|
171
|
+
readBit() {
|
|
172
|
+
return this.read(1) === 1;
|
|
173
|
+
}
|
|
174
|
+
}
|