Skip to content

Commit 5e1a5d3

Browse files
committed
Add docs everywhere. Upgrade to ts 6.0-rc, jsbt 0.5. Add pkg.json scripts.
1 parent d137596 commit 5e1a5d3

11 files changed

Lines changed: 456 additions & 222 deletions

File tree

README.md

Lines changed: 36 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -76,25 +76,30 @@ const larger = encodeQR(txt, 'gif', { scale: 4 });
7676
// };
7777

7878
console.log(ascii);
79-
> █████████████████████████████████████
80-
> ██ ▄▄▄▄▄ █ ▀▄▄█ ██▀▄▄▄▄█ ▀█ ▄▄▄▄▄ ██
81-
> ██ █ █ █▀▄▀▄ ▄▄█▄█ ██▀█▀▀█ █ █ ██
82-
> ██ █▄▄▄█ ██ ▄▄█▄▀▀ ▀ ██ ▄ ▄█ █▄▄▄█ ██
83-
> ██▄▄▄▄▄▄▄█ ▀ ▀ █▄▀ ▀ ▀▄█ █ █▄▄▄▄▄▄▄██
84-
> ██ █ ▀ ▄▄▀▀▀ █▀ ▄ ▀▀▄▀ ▄█ ▀█ ▀▄▄██
85-
> ██▀▀▀ ▀▄▄██▄▀▀▄█▀ ▀▄█ ▀▀▀ ▄ █▄▄██
86-
> █████▄▀▀▄▄██ ▀ ▀ ▄▄██▄ ▄▄ ▄ █▀█ █ ███
87-
> ███ ▄▀▄█▄▄▄█ ▀██▄▄▄▀▀█▄▀ ▄█▀ ████
88-
> ██▀▀ ▄ ▀▄ ▄▄██▀▄▀▀████▄▄▄ █▄ █ █▀▀██
89-
> ██▀▀▄ ▄▀▄ ▀▀█▄▀▀▄▄▀▀ █▄▄▀█▀ ▀▄ █▄ ▀██
90-
> ██▀▄▀██ ▄▄ ▀█▄█▀ ▀ ▀█▄▀▀ █▄▀▀ █ █ ██
91-
> ███▀█▄▀▄▄ █ █ ██ ██ ▄ █ ▄▄▄ ▄▀▀▄▄ ██
92-
> ██▄█▄▄▄█▄█ ▄ ▄▀█▀▀ ▄▀ █▀ ▄ ▄▄▄ ▀▄▀▄██
93-
> ██ ▄▄▄▄▄ █ ▄█▄▀▀ ▀█ █▄█ █▄█ ▀▀▄▀██
94-
> ██ █ █ █▀ ▄▀█ ██ ▄▄▀██ ▄▄ ▄█ ██
95-
> ██ █▄▄▄█ █▄ ██▀ ▄▄ ▀█ ▄ ▀▄▄█▀██
96-
> ██▄▄▄▄▄▄▄█▄███▄█▄█▄▄▄▄█▄█▄████▄▄█████
97-
> ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
79+
```
80+
81+
Example output:
82+
83+
```text
84+
█████████████████████████████████████
85+
██ ▄▄▄▄▄ █ ▀▄▄█ ██▀▄▄▄▄█ ▀█ ▄▄▄▄▄ ██
86+
██ █ █ █▀▄▀▄ ▄▄█▄█ ██▀█▀▀█ █ █ ██
87+
██ █▄▄▄█ ██ ▄▄█▄▀▀ ▀ ██ ▄ ▄█ █▄▄▄█ ██
88+
██▄▄▄▄▄▄▄█ ▀ ▀ █▄▀ ▀ ▀▄█ █ █▄▄▄▄▄▄▄██
89+
██ █ ▀ ▄▄▀▀▀ █▀ ▄ ▀▀▄▀ ▄█ ▀█ ▀▄▄██
90+
██▀▀▀ ▀▄▄██▄▀▀▄█▀ ▀▄█ ▀▀▀ ▄ █▄▄██
91+
█████▄▀▀▄▄██ ▀ ▀ ▄▄██▄ ▄▄ ▄ █▀█ █ ███
92+
███ ▄▀▄█▄▄▄█ ▀██▄▄▄▀▀█▄▀ ▄█▀ ████
93+
██▀▀ ▄ ▀▄ ▄▄██▀▄▀▀████▄▄▄ █▄ █ █▀▀██
94+
██▀▀▄ ▄▀▄ ▀▀█▄▀▀▄▄▀▀ █▄▄▀█▀ ▀▄ █▄ ▀██
95+
██▀▄▀██ ▄▄ ▀█▄█▀ ▀ ▀█▄▀▀ █▄▀▀ █ █ ██
96+
███▀█▄▀▄▄ █ █ ██ ██ ▄ █ ▄▄▄ ▄▀▀▄▄ ██
97+
██▄█▄▄▄█▄█ ▄ ▄▀█▀▀ ▄▀ █▀ ▄ ▄▄▄ ▀▄▀▄██
98+
██ ▄▄▄▄▄ █ ▄█▄▀▀ ▀█ █▄█ █▄█ ▀▀▄▀██
99+
██ █ █ █▀ ▄▀█ ██ ▄▄▀██ ▄▄ ▄█ ██
100+
██ █▄▄▄█ █▄ ██▀ ▄▄ ▀█ ▄ ▀▄▄█▀██
101+
██▄▄▄▄▄▄▄█▄███▄█▄█▄▄▄▄█▄█▄████▄▄█████
102+
▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
98103
```
99104

100105
## Decoding
@@ -143,21 +148,23 @@ function decodeWithExternal() {
143148
### Decoding options
144149

145150
```ts
146-
export type Point4 = { x: number; y: number }[];
147-
export type Image = {
151+
type Point = { x: number; y: number };
152+
type Pattern = Point & { moduleSize: number; count: number };
153+
type FinderPoints = [Pattern, Pattern, Point, Pattern];
154+
type Image = {
148155
height: number;
149156
width: number;
150157
data: Uint8Array | Uint8ClampedArray | number[];
151158
};
152-
export type DecodeOpts = {
153-
// By default we assume that image has 4 channel per pixel (RGBA). isRGB: true will force to use only one
154-
isRGB?: boolean;
155-
// Returns 4 center (3 finder pattern + 1 alignment pattern) points if detected
156-
detectFn?: (points: Point4) => void;
157-
// Returns RGBA image of detected QR code
158-
qrFn?: (img: Image) => void;
159+
type DecodeOpts = {
160+
cropToSquare?: boolean;
161+
textDecoder?: (bytes: Uint8Array) => string;
162+
pointsOnDetect?: (points: FinderPoints) => void;
163+
imageOnBitmap?: (img: Image) => void;
164+
imageOnDetect?: (img: Image) => void;
165+
imageOnResult?: (img: Image) => void;
159166
};
160-
export default function decodeQR(img: Image, opts: DecodeOpts = {});
167+
declare function decodeQR(img: Image, opts?: DecodeOpts): string;
161168
```
162169

163170
### Decoding algorithm

package-lock.json

Lines changed: 17 additions & 17 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,18 @@
2020
"LICENSE-MIT"
2121
],
2222
"devDependencies": {
23-
"@paulmillr/jsbt": "0.4.5",
24-
"@types/node": "24.2.1",
23+
"@paulmillr/jsbt": "0.5.0",
24+
"@types/node": "25.3.0",
2525
"prettier": "3.6.2",
26-
"typescript": "5.9.2"
26+
"typescript": "6.0.1-rc"
2727
},
2828
"scripts": {
2929
"build": "tsc",
3030
"build:release": "npx --no @paulmillr/jsbt esbuild test/build",
31+
"check": "npm run check:readme && npm run check:treeshake && npm run check:jsdoc",
32+
"check:readme": "npx --no @paulmillr/jsbt readme package.json",
33+
"check:treeshake": "npx --no @paulmillr/jsbt treeshake package.json test/build/out-treeshake",
34+
"check:jsdoc": "npx --no @paulmillr/jsbt tsdoc package.json",
3135
"bench": "cd test/benchmark && npm ci && node index.ts",
3236
"format": "prettier --write src",
3337
"test": "cd test; npm ci; node --experimental-strip-types --no-warnings index.ts",

src/decode.ts

Lines changed: 56 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,6 @@ limitations under the License.
1717
/**
1818
* Methods for decoding (reading) QR code patterns.
1919
* @module
20-
* @example
21-
```js
22-
23-
```
2420
*/
2521

2622
import type { EncodingType, ErrorCorrection, Image, Mask, Point } from './index.ts';
@@ -53,6 +49,7 @@ for (let i = 0; i < SUM16.length; i++) {
5349
const int = (n: number) => n >>> 0;
5450

5551
type Point4 = [Point, Point, Point, Point];
52+
/** Finder and alignment points returned by the detector. */
5653
export type FinderPoints = [Pattern, Pattern, Point, Pattern];
5754
// distance ^ 2
5855
const distance2 = (p1: Point, p2: Point) => {
@@ -1182,12 +1179,35 @@ function decodeBitmap(
11821179
return res;
11831180
}
11841181

1182+
/** QR decoding hooks and image preprocessing options. */
11851183
export type DecodeOpts = {
1184+
/** Crop rectangular inputs to a centered square before decoding. */
11861185
cropToSquare?: boolean;
1186+
/**
1187+
* Custom byte-to-text decoder used for byte segments.
1188+
* @param bytes - Byte segment to decode.
1189+
* @returns Decoded text.
1190+
*/
11871191
textDecoder?: (bytes: Uint8Array) => string;
1192+
/**
1193+
* Callback invoked with finder/alignment points after detection succeeds.
1194+
* @param points - Finder and alignment points returned by the detector.
1195+
*/
11881196
pointsOnDetect?: (points: FinderPoints) => void;
1197+
/**
1198+
* Callback invoked with the grayscale bitmap that the detector sees.
1199+
* @param img - Grayscale image generated during bitmap conversion.
1200+
*/
11891201
imageOnBitmap?: (img: Image) => void;
1202+
/**
1203+
* Callback invoked with the perspective-corrected QR image.
1204+
* @param img - Perspective-corrected QR image.
1205+
*/
11901206
imageOnDetect?: (img: Image) => void;
1207+
/**
1208+
* Callback invoked with the final decoded QR image.
1209+
* @param img - Final QR image used to decode the payload.
1210+
*/
11911211
imageOnResult?: (img: Image) => void;
11921212
};
11931213

@@ -1211,6 +1231,22 @@ function cropToSquare(img: Image) {
12111231
return { offset, img: { height: squareSize, width: squareSize, data: croppedData } };
12121232
}
12131233

1234+
/**
1235+
* Decode text from a QR image.
1236+
* @param img - RGB or RGBA image data that contains a QR code.
1237+
* @param opts - Decoder hooks and image preprocessing options. See {@link DecodeOpts}.
1238+
* @returns Decoded QR payload as a string.
1239+
* @throws If the image, decoder options, or QR contents are invalid. {@link Error}
1240+
* @example
1241+
* Decode text from a QR image.
1242+
* ```ts
1243+
* import encodeQR, { Bitmap } from 'qr';
1244+
* import decodeQR from 'qr/decode.js';
1245+
* const bits = encodeQR('Hello world', 'raw', { scale: 4 });
1246+
* const bm = new Bitmap({ width: bits[0].length, height: bits.length }, bits);
1247+
* const text = decodeQR(bm.toImage());
1248+
* ```
1249+
*/
12141250
export function decodeQR(img: Image, opts: DecodeOpts = {}): string {
12151251
for (const field of ['height', 'width'] as const) {
12161252
if (!Number.isSafeInteger(img[field]) || img[field] <= 0)
@@ -1240,6 +1276,22 @@ export function decodeQR(img: Image, opts: DecodeOpts = {}): string {
12401276
return res;
12411277
}
12421278

1279+
/**
1280+
* Default export alias for {@link decodeQR}.
1281+
* @param img - RGB or RGBA image data that contains a QR code.
1282+
* @param opts - Decoder hooks and image preprocessing options. See {@link DecodeOpts}.
1283+
* @returns Decoded QR payload as a string.
1284+
* @throws If the image, decoder options, or QR contents are invalid. {@link Error}
1285+
* @example
1286+
* Decode a rendered QR image via the default decoder export.
1287+
* ```ts
1288+
* import encodeQR, { Bitmap } from 'qr';
1289+
* import decodeQR from 'qr/decode.js';
1290+
* const bits = encodeQR('Hello world', 'raw', { scale: 4 });
1291+
* const bm = new Bitmap({ width: bits[0].length, height: bits.length }, bits);
1292+
* decodeQR(bm.toImage());
1293+
* ```
1294+
*/
12431295
export default decodeQR;
12441296

12451297
// Unsafe API utils, exported only for tests

0 commit comments

Comments
 (0)