quadqr-js 1.4.2 → 1.5.2
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/FORMAT.md +5 -5
- package/README.md +19 -8
- package/SPECIFICATION.md +12 -12
- package/dist/camera-scanner-worker.js +793 -0
- package/dist/esm/camera-scanner-worker.js +793 -0
- package/dist/esm/geometry.js +25 -10
- package/dist/esm/quadqr.js +843 -62
- package/dist/esm/vision.js +887 -122
- package/dist/esm/wasm.js +85 -12
- package/dist/quadqr.js +1803 -198
- package/dist/quadqr.min.js +2032 -274
- package/dist/wasm/quadqr-core.wasm +0 -0
- package/docs/API.md +13 -5
- package/docs/BROWSER_CDN.md +5 -5
- package/docs/CLI.md +167 -167
- package/docs/COMPRESSION.md +170 -170
- package/docs/GETTING_STARTED.md +1 -1
- package/docs/HIGH_DENSITY_MODE.md +100 -100
- package/docs/NODE.md +159 -159
- package/docs/README.md +62 -62
- package/docs/RELIABILITY_LAB.md +64 -64
- package/docs/TRIANGLE16.md +98 -98
- package/docs/WASM.md +30 -4
- package/package.json +5 -3
package/FORMAT.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# QuadQR Format
|
|
1
|
+
# QuadQR Format v6
|
|
2
2
|
|
|
3
3
|
## Status
|
|
4
4
|
|
|
@@ -50,7 +50,7 @@ Three 7×7 black/white finder structures are placed at top-left, top-right, and
|
|
|
50
50
|
|
|
51
51
|
## Alignment patterns
|
|
52
52
|
|
|
53
|
-
QuadQR always keeps exactly three primary 7×7 finder patterns. Larger versions do **not** add more primary finders. Instead, versions 2 through 40 use distributed black/white alignment markers following the same center-position schedule used by standard QR Code versions.
|
|
53
|
+
QuadQR always keeps exactly three primary 7×7 finder patterns. Larger versions do **not** add more primary finders. Instead, versions 2 through 40 use distributed black/white alignment markers following the same center-position schedule used by standard QR Code versions. **Format v6 uses a full 5×5 nested black/white/black alignment eye at every scheduled alignment position**, matching the strong structural signature used by proven QR detectors.
|
|
54
54
|
|
|
55
55
|
The three alignment positions that would overlap the primary finder corners are omitted. This produces progressively more alignment references as the matrix grows. Examples:
|
|
56
56
|
|
|
@@ -64,7 +64,7 @@ v40 -> 46 alignment patterns
|
|
|
64
64
|
|
|
65
65
|
Version 1 is a QuadQR-specific exception. Standard QR v1 has no alignment pattern, but QuadQR keeps one legacy 5×5 bottom-right bootstrap alignment marker with a one-cell white separator so the camera scanner still has a fourth projective reference point.
|
|
66
66
|
|
|
67
|
-
For versions 2 through 40, the scanner uses the 5×5
|
|
67
|
+
For versions 2 through 40, the scanner uses the bottom-right 5×5 member of the distributed alignment grid as the primary fourth homography reference, then scores and refines against the full 5×5 alignment grid. A fast nested-eye locator is attempted before broader template recovery so perspective geometry can be established as soon as the three primary finder eyes are visible.
|
|
68
68
|
|
|
69
69
|
## Timing structures
|
|
70
70
|
|
|
@@ -411,7 +411,7 @@ Matrix decoding tries 0°, 90°, 180°, and 270° rotations.
|
|
|
411
411
|
|
|
412
412
|
## Compatibility
|
|
413
413
|
|
|
414
|
-
Format
|
|
414
|
+
Format v6 is intentionally incompatible with standard QR scanners and with the project's older ternary prototypes. The current encoder writes codeword cells using spectral-spatial placement and uses 5×5 nested alignment eyes at every scheduled alignment position. Format v5 used compact 3×3 secondary alignment markers while retaining the bottom-right primary marker at 5×5. The current decoder keeps a legacy Format v5 alignment-profile fallback, so existing v5 RGBW QuadQR symbols remain readable. The decoder also retains the pre-interleaver physical-order fallback for older RGBW matrices.
|
|
415
415
|
|
|
416
416
|
## Rendering profiles are not part of the wire format
|
|
417
417
|
|
|
@@ -419,7 +419,7 @@ The canonical QuadQR matrix is independent of presentation style. Renderers may
|
|
|
419
419
|
|
|
420
420
|
## Compression and signature flags
|
|
421
421
|
|
|
422
|
-
Format
|
|
422
|
+
Format v6 keeps the physical matrix and ECC framing unchanged while reserving two protected-header flags for optional internal payload metadata:
|
|
423
423
|
|
|
424
424
|
```text
|
|
425
425
|
bit 4 = internal payload-extension metadata present
|
package/README.md
CHANGED
|
@@ -440,7 +440,7 @@ QuadQR currently uses:
|
|
|
440
440
|
- square modules;
|
|
441
441
|
- three 7×7 black-and-white finder patterns;
|
|
442
442
|
- black-and-white timing structures;
|
|
443
|
-
-
|
|
443
|
+
- distributed 5×5 nested alignment eyes on versions that use alignment patterns;
|
|
444
444
|
- RGB calibration swatches;
|
|
445
445
|
- structural black/white references;
|
|
446
446
|
- a two-column zig-zag physical data-position path;
|
|
@@ -453,7 +453,7 @@ QuadQR currently uses:
|
|
|
453
453
|
|
|
454
454
|
White is a valid data state.
|
|
455
455
|
|
|
456
|
-
QuadQR still uses exactly three large finder patterns, just like standard QR. Starting at version 2, alignment markers follow the standard QR version-dependent center schedule
|
|
456
|
+
QuadQR still uses exactly three large finder patterns, just like standard QR. Starting at version 2, Format v6 alignment markers follow the standard QR version-dependent center schedule and every scheduled alignment marker is a full 5×5 nested black/white/black eye. These distributed references give the detector stronger anchors for high-version and projectively distorted symbols. Version 1 keeps one QuadQR-specific 5×5 bottom-right bootstrap marker because it otherwise would have no fourth projective reference. The decoder retains the compact 3×3 secondary-marker profile used by Format v5 so existing v5 symbols remain readable.
|
|
457
457
|
|
|
458
458
|
The decoder does not treat a white-looking area as automatically empty. It reconstructs the matrix geometry first and then determines whether a sampled position is structural or data.
|
|
459
459
|
|
|
@@ -481,7 +481,7 @@ White → (255, 255, 255)
|
|
|
481
481
|
|
|
482
482
|
Real camera input is not expected to match those exact values.
|
|
483
483
|
|
|
484
|
-
QuadQR includes calibration and nearest-color classification so the scanner can work with observed colors after lighting, camera processing, perspective changes, and other image transformations. The clean-frame path
|
|
484
|
+
QuadQR includes calibration and nearest-color classification so the scanner can work with observed colors after lighting, camera processing, perspective changes, and other image transformations. The clean-frame path starts with a streaming 1:1:3:1:1 finder detector on the RGB value channel, direct cross-checks, local-threshold fallback, and directional module-size/version estimation. Once the three finder eyes form a valid geometry, QuadQR immediately tries the highest-ranked perspective candidate instead of waiting for every lower-ranked geometry. Near-front-facing symbols can use a three-finder affine fast path, while projectively distorted symbols continue through the full homography/alignment solver. Format v6 distributed 5×5 alignment eyes provide stronger local perspective anchors, and a cheap nested-eye locator is tried before the broader alignment search. If a steep angle leaves exactly two strong finder patterns, the bounded looser third-finder pass still runs before heavier color recovery. Only after geometry/color decoding still fails does QuadQR progressively try the existing stronger recovery, including white balancing, a 3×4 affine color-calibration model learned from the known black/white/R/G/B references, spatial normalization, Auto Tone / Auto Contrast / QuadQR Auto Color-style enhancement, soft-decision ECC, and bounded sub-module geometry refinement. For live video, normal detection works from the CSS-visible `object-fit: cover` camera region at a 640 px working dimension. A bounded 960 px retry is reserved for difficult dense frames that already show useful finder evidence, rather than being part of the ordinary camera loop. If finder geometry is already strong but color decoding fails, a QR-only rectified pixel enhancement retry is performed immediately; whole-frame enhancement remains reserved for harder locator failures.
|
|
485
485
|
|
|
486
486
|
---
|
|
487
487
|
|
|
@@ -782,7 +782,7 @@ console.log(result.text);
|
|
|
782
782
|
The `quadqr-js` package can be loaded directly from npm-backed CDNs:
|
|
783
783
|
|
|
784
784
|
```html
|
|
785
|
-
<script src="https://cdn.jsdelivr.net/npm/quadqr-js@1.
|
|
785
|
+
<script src="https://cdn.jsdelivr.net/npm/quadqr-js@1.5.1/dist/quadqr.min.js"></script>
|
|
786
786
|
<script>
|
|
787
787
|
const code = QuadQR.encodeText("Hello from a script tag");
|
|
788
788
|
</script>
|
|
@@ -838,6 +838,16 @@ Build the distributable browser, Node.js, CDN, and WASM files:
|
|
|
838
838
|
npm run build
|
|
839
839
|
```
|
|
840
840
|
|
|
841
|
+
`npm run build` verifies the checked-in WASM binary against `wasm-src/quadqr_core.c`, the WASM compiler flags, and the recorded binary hash. If everything matches, the verified prebuilt binary is reused. If the C source or build flags changed, the build automatically recompiles WASM with LLVM/Clang. If WASM is stale and `clang` is unavailable, the build fails instead of silently shipping an old binary.
|
|
842
|
+
|
|
843
|
+
To force only the WASM rebuild:
|
|
844
|
+
|
|
845
|
+
```bash
|
|
846
|
+
npm run build:wasm
|
|
847
|
+
```
|
|
848
|
+
|
|
849
|
+
A forced WASM rebuild requires `clang` in `PATH`. No Rust, Cargo, or Emscripten toolchain is required. The build records its verification data in `wasm/quadqr-core.build.json`.
|
|
850
|
+
|
|
841
851
|
Start the interactive demo:
|
|
842
852
|
|
|
843
853
|
```bash
|
|
@@ -858,7 +868,7 @@ npm run benchmark
|
|
|
858
868
|
|
|
859
869
|
### Optional WASM acceleration
|
|
860
870
|
|
|
861
|
-
The package ships a prebuilt WASM helper but never requires it.
|
|
871
|
+
The package ships a prebuilt WASM helper but never requires it. It accelerates CRC-32 plus the scanner's RGBA-to-grayscale, Otsu-threshold, and binary finder preprocessing hot path.
|
|
862
872
|
|
|
863
873
|
```js
|
|
864
874
|
import { initWasm } from "quadqr-js";
|
|
@@ -866,7 +876,7 @@ import { initWasm } from "quadqr-js";
|
|
|
866
876
|
await initWasm();
|
|
867
877
|
```
|
|
868
878
|
|
|
869
|
-
If WASM cannot load, the normal JavaScript codec remains available.
|
|
879
|
+
If WASM cannot load, the normal JavaScript codec/scanner remains available. For camera or repeated image scanning, initialize WASM once during application startup.
|
|
870
880
|
|
|
871
881
|
---
|
|
872
882
|
|
|
@@ -901,7 +911,8 @@ wasm-src/
|
|
|
901
911
|
quadqr_core.c Small portable WASM accelerator source
|
|
902
912
|
|
|
903
913
|
wasm/
|
|
904
|
-
quadqr-core.wasm
|
|
914
|
+
quadqr-core.wasm Source-tree WASM build output
|
|
915
|
+
quadqr-core.build.json Source/build/binary verification metadata
|
|
905
916
|
|
|
906
917
|
dist/
|
|
907
918
|
index.js ESM package entry
|
|
@@ -1093,7 +1104,7 @@ Scans one frame from an HTML video element. By default, if the video is displaye
|
|
|
1093
1104
|
|
|
1094
1105
|
### `startCameraScanner(video, options?)`
|
|
1095
1106
|
|
|
1096
|
-
Starts a reusable live-camera scanning loop. On supported browsers it requests continuous focus/exposure/white-balance camera modes and scans the CSS-visible preview crop.
|
|
1107
|
+
Starts a reusable live-camera scanning loop. On supported browsers it requests continuous focus/exposure/white-balance camera modes and scans the CSS-visible preview crop. Modern browsers use a **dual-worker camera engine**: a lightweight fresh-frame worker continuously runs normal finder/geometry/decode attempts, while an independent recovery worker retains the complete high-resolution, Auto Color, precise-alignment, perspective, multi-frame, ECC, and damaged-code recovery stack. A slow recovery attempt therefore cannot prevent the fast worker from inspecting a newer camera frame. Finder detection remains JavaScript; optional WASM accelerates grayscale/binary preprocessing and CRC beneath the same detector. The scheduler uses `requestVideoFrameCallback()` when available and does not queue stale fast-path frames. Normal camera acquisition requests an environment camera around 1280×720 and crops/resizes the visible preview to a 640 px working bitmap **before** transferring it to the worker. Once a candidate validates structure, Spectrum ECC, and CRC, scanning returns immediately. If the fast worker misses, full recovery runs concurrently on a fresh frame at up to 960 px. Strong finder evidence dispatches recovery quickly; finder-less frames still receive periodic full recovery so severe color casts or damaged locators retain the same rescue paths. QuadQR Auto Color crop profiles, center-weighted histograms, threshold bracketing, precise alignment, projective recovery, QR-region enhancement, multi-frame confidence fusion, and soft-decision Spectrum ECC are unchanged. `cameraHighResolutionMaxDimension` defaults to 960. The optional `onDiagnostic(event)` callback exposes whether an event came from the fast or recovery worker, finder candidates, active locator method, crop/geometry/version hypothesis, recovery method, timing, and scan dimensions. `onResult(result, frame)` receives the exact frame that decoded, including enhanced recovery pixels when applicable, so UIs can keep the frozen frame and finder overlay aligned.
|
|
1097
1108
|
|
|
1098
1109
|
### `getVersionInfo(version, options?)`
|
|
1099
1110
|
|
package/SPECIFICATION.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
QuadQR is an experimental RGBW matrix symbology. Normal mode uses 4-state RGBW cells, while the optional **High Density Mode** is experimental and uses the 16-state Triangle16 physical layout. It is not ISO/IEC QR Code and is not intended to be decoded by standard QR readers.
|
|
6
6
|
|
|
7
|
-
The physical matrix format remains **QuadQR Format
|
|
7
|
+
The physical matrix format remains **QuadQR Format v6**. Normal application data is always treated simply as UTF-8 text or arbitrary bytes. Compression, signatures, encryption, rendering, and diagnostics are optional features layered around that stable matrix codec.
|
|
8
8
|
|
|
9
9
|
For exact matrix geometry and Reed-Solomon framing, see [`FORMAT.md`](./FORMAT.md).
|
|
10
10
|
|
|
@@ -17,7 +17,7 @@ Application bytes / UTF-8 text
|
|
|
17
17
|
├─ optional Ed25519 signature metadata (internal)
|
|
18
18
|
├─ optional Secure Payload v1 (AES-256-GCM)
|
|
19
19
|
│
|
|
20
|
-
└─ QuadQR Format
|
|
20
|
+
└─ QuadQR Format v6
|
|
21
21
|
├─ protected header
|
|
22
22
|
├─ CRC-32
|
|
23
23
|
├─ GF(256) Reed-Solomon Spectrum ECC
|
|
@@ -53,9 +53,9 @@ version = 1..40
|
|
|
53
53
|
|
|
54
54
|
Three 7×7 finder patterns are always present. Version 1 has the legacy QuadQR 5×5 bottom-right alignment marker. Versions 2–40 use the distributed alignment schedule defined in `FORMAT.md`.
|
|
55
55
|
|
|
56
|
-
## 4. Format
|
|
56
|
+
## 4. Format v6 header flags
|
|
57
57
|
|
|
58
|
-
The protected Format
|
|
58
|
+
The protected Format v6 header uses:
|
|
59
59
|
|
|
60
60
|
```text
|
|
61
61
|
bit 0 UTF-8 text flag
|
|
@@ -128,7 +128,7 @@ bit 1 compressed
|
|
|
128
128
|
bit 2 public key embedded
|
|
129
129
|
```
|
|
130
130
|
|
|
131
|
-
The envelope contains no semantic content type. The Format
|
|
131
|
+
The envelope contains no semantic content type. The Format v6 text flag still determines whether the recovered application payload should be decoded as UTF-8 text.
|
|
132
132
|
|
|
133
133
|
## 7. Compression
|
|
134
134
|
|
|
@@ -167,11 +167,11 @@ lz
|
|
|
167
167
|
|
|
168
168
|
`compression: "auto"` is the fast balanced policy. It evaluates LZ level 6, DEFLATE level 6, and Brotli quality 6 exactly once and chooses the smallest complete stored representation. For unsigned payloads that comparison includes the 16-byte extension-envelope cost, so Auto remains zero-overhead when compression is not useful.
|
|
169
169
|
|
|
170
|
-
`compression: "smart"` is the opt-in CPU-heavy policy. It begins with the Auto candidates, computes the resulting Format
|
|
170
|
+
`compression: "smart"` is the opt-in CPU-heavy policy. It begins with the Auto candidates, computes the resulting Format v6 QuadQR version using the selected ECC/profile/version bounds, and only escalates when the next smaller matrix is plausibly reachable. The strong stage tests DEFLATE 8 and Brotli 9. If the symbol remains close to a smaller-version boundary, the maximum stage tests DEFLATE 9 and Brotli 11. With an explicitly requested fixed version, Smart does not chase a smaller matrix, but it may escalate when the balanced result does not fit and stronger compression can plausibly make that requested version fit. Signed and secure pipelines include their fixed envelope overhead when evaluating those version boundaries.
|
|
171
171
|
|
|
172
172
|
Explicit `compression: "lz"` and `compression: "deflate"` accept `compressionLevel` `1..9` and default to 6. Explicit `compression: "brotli"` accepts `compressionLevel` `0..11` and defaults to 11. Compression levels are encoder-only parameters and are intentionally not stored in the extension envelope because LZ, RFC 1951, and Brotli decoders do not require them. Auto and Smart use LZ level 6; Smart's staged escalation remains focused on DEFLATE/Brotli.
|
|
173
173
|
|
|
174
|
-
Compression occurs before signing, encryption, and Format
|
|
174
|
+
Compression occurs before signing, encryption, and Format v6 ECC.
|
|
175
175
|
|
|
176
176
|
## 8. Signed QuadQR
|
|
177
177
|
|
|
@@ -211,13 +211,13 @@ application payload
|
|
|
211
211
|
→ optional compression
|
|
212
212
|
→ optional Ed25519 signature metadata
|
|
213
213
|
→ AES-256-GCM Secure Payload v1
|
|
214
|
-
→ Format
|
|
214
|
+
→ Format v6 ECC/matrix
|
|
215
215
|
```
|
|
216
216
|
|
|
217
217
|
After scanning:
|
|
218
218
|
|
|
219
219
|
```text
|
|
220
|
-
Format
|
|
220
|
+
Format v6 decode
|
|
221
221
|
→ AES-GCM authentication/decryption
|
|
222
222
|
→ internal compression/signature metadata processing
|
|
223
223
|
→ application payload
|
|
@@ -264,7 +264,7 @@ Recommended general-purpose starting module size is **0.40 mm/module**. Real pri
|
|
|
264
264
|
|
|
265
265
|
## 12. Logo safety
|
|
266
266
|
|
|
267
|
-
Logos are rendering overlays and never modify Format
|
|
267
|
+
Logos are rendering overlays and never modify Format v6 data structures.
|
|
268
268
|
|
|
269
269
|
`size: "auto"` estimates a conservative logo ratio from:
|
|
270
270
|
|
|
@@ -320,7 +320,7 @@ These scores are regression/testing aids. They do not replace validation with re
|
|
|
320
320
|
|
|
321
321
|
## 15. Capacity planning
|
|
322
322
|
|
|
323
|
-
Capacity is determined from the actual Format
|
|
323
|
+
Capacity is determined from the actual Format v6 layout, protected header, CRC, and Spectrum ECC plan. Compression can reduce stored payload bytes, while signatures and encryption add metadata bytes before the matrix codec.
|
|
324
324
|
|
|
325
325
|
The benchmark helper can report:
|
|
326
326
|
|
|
@@ -340,7 +340,7 @@ Implementations should follow these rules:
|
|
|
340
340
|
|
|
341
341
|
1. Keep RGBW mapping exactly `R=00, G=01, B=10, W=11`.
|
|
342
342
|
2. Keep GF(256) Spectrum ECC and its errors+erasures behavior.
|
|
343
|
-
3. Preserve Format v5 decoding
|
|
343
|
+
3. Preserve Format v5 decoding as a legacy compatibility path while encoding new symbols as Format v6.
|
|
344
344
|
4. Keep application semantics outside the QuadQR codec. Do not require a growing content-type registry.
|
|
345
345
|
5. Treat compression/signature metadata as internal transport metadata, not a separate user payload mode.
|
|
346
346
|
6. Treat `keyId` only as an identifier. Signer trust comes from an external trusted public-key binding.
|