quadqr-js 1.2.0 → 1.3.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/docs/API.md CHANGED
@@ -11,12 +11,15 @@ import { encodeText } from "quadqr-js";
11
11
 
12
12
  const code = encodeText("Hello", {
13
13
  ecc: "M",
14
- version: 5
14
+ version: 5,
15
+ highDensity: true // optional experimental 4-bit cells
15
16
  });
16
17
  ```
17
18
 
18
19
  If `version` is omitted, QuadQR selects the smallest version that fits.
19
20
 
21
+ `highDensity` is a boolean. It defaults to `false`. Set `highDensity: true` to enable the experimental Triangle16 layout with two RGBW triangles, 16 states, and 4 raw bits per body cell. The protected header remains solid-color in High Density Mode. Image and camera scanners auto-detect it.
22
+
20
23
  ### `encodeBytes(bytes, options?)`
21
24
 
22
25
  Encodes arbitrary bytes.
@@ -176,7 +179,7 @@ const svg = renderToSVG(code, {
176
179
 
177
180
  ### `scanImageData(imageData, options?)`
178
181
 
179
- Scans an ImageData-like RGBA object. Clean frames use the normal observed-RGB path first. Difficult frames then get bounded fallback attempts using per-channel white balancing, spatial black/white normalization, tighter centre sampling, module-grid Auto Tone / Auto Contrast / Auto Color recovery, a rectified QR-region pixel enhancement pass, and sub-module geometry micro-refinement before the scan is rejected.
182
+ Scans an ImageData-like RGBA object. The scanner automatically attempts both normal RGBW center sampling and Triangle16 dual-region sampling when geometry is found. When normal projective geometry is locatable but too coarse for half-cell Triangle16 regions, one bounded precise-alignment recovery pass refines the alignment center at sub-module resolution. Clean frames use the normal observed-RGB path first. Difficult frames then get bounded fallback attempts using per-channel white balancing, spatial black/white normalization, tighter centre sampling, module-grid Auto Tone / Auto Contrast / Auto Color recovery, a rectified QR-region pixel enhancement pass, and sub-module geometry micro-refinement before the scan is rejected. Dense versions also use their distributed alignment markers to refine a noisy four-point projective solution when the initial alignment-grid score is plausible but imperfect. If exactly two strong finder patterns survive a steep angle, a bounded perspective-tolerant third-finder recovery pass is attempted before heavier color recovery.
180
183
 
181
184
  ```js
182
185
  const result = scanImageData({
@@ -186,7 +189,7 @@ const result = scanImageData({
186
189
  });
187
190
  ```
188
191
 
189
- Useful scanner options include `sampleRadius`, `robustSampleRadius`, `adaptiveSampling`, `spatialColorNormalization`, `autoEnhanceRecovery`, `rectifiedAutoEnhanceRecovery`, `rectifiedRecoveryModuleSize`, `autoEnhanceBlackClip`, `autoEnhanceWhiteClip`, `autoEnhanceSaturation`, `geometryRefinement`, `refinementOffset`, `structureTolerance`, and `maxErasureConfidence`. Auto enhancement and geometry refinement are enabled by default, but only run after the normal scan path fails.
192
+ Useful scanner options include `sampleRadius`, `robustSampleRadius`, `adaptiveSampling`, `spatialColorNormalization`, `autoEnhanceRecovery`, `rectifiedAutoEnhanceRecovery`, `rectifiedRecoveryModuleSize`, `autoEnhanceBlackClip`, `autoEnhanceWhiteClip`, `autoEnhanceSaturation`, `geometryRefinement`, `alignmentRefinement`, `alignmentRefinePatternThreshold`, `refinementOffset`, `structureTolerance`, and `maxErasureConfidence`. Auto enhancement and geometry refinement are enabled by default, but bounded recovery work only runs when the normal scan path or initial geometry needs it.
190
193
 
191
194
  ### Browser `scanFile(file, options?)`
192
195
 
@@ -206,7 +209,7 @@ const result = scanVideoFrame(video);
206
209
 
207
210
  ### `startCameraScanner(video, options?)`
208
211
 
209
- Starts live camera scanning. On browsers that expose camera controls, QuadQR requests continuous autofocus, exposure, and white balance. It scans the CSS-visible preview region by default. Finder detection uses a QuadQR-specific RGB value channel (`max(R,G,B)`) on the fast pass so saturated blue/red/green data cells are not mistaken for structural black. If that fast pass fails, the **same captured frame** is retried through code-centric Auto Color recovery before finder detection. The default recovery sequence crops 8%, 16%, and 22% from the camera-frame edges, then falls back to the full frame. This prevents dark room pixels, browser UI, or monitor bezels outside the guide from controlling Auto Color and Otsu thresholds. Each crop uses the Photoshop-style per-channel shadow/highlight correction with a neutral mid-high highlight target (190 by default). Finder-only recovery also tries multiple center-weighted Auto Color histogram windows before raw threshold bracketing. The normal fast path is untouched; these extra passes run only after a miss. If geometry is found but color decoding fails, the captured ROI is retried with the stronger color/geometry recovery, and consecutive failed frames can still be combined with confidence-weighted module voting.
212
+ Starts live camera scanning. On browsers that expose camera controls, QuadQR requests continuous autofocus, exposure, and white balance. It scans the CSS-visible preview region by default. Finder detection uses a QuadQR-specific RGB value channel (`max(R,G,B)`) on the fast pass so saturated blue/red/green data cells are not mistaken for structural black. If a miss still contains at least two strong finder patterns, the scanner can retry the visible ROI at up to 1600 px before heavier recovery, which preserves more pixels per module for dense versions. If that does not decode, the **same captured frame** is retried through code-centric Auto Color recovery. The default recovery sequence crops 8%, 16%, and 22% from the camera-frame edges, then falls back to the full frame. This prevents dark room pixels, browser UI, or monitor bezels outside the guide from controlling Auto Color and Otsu thresholds. Each crop uses the Photoshop-style per-channel shadow/highlight correction with a neutral mid-high highlight target (190 by default). Finder-only recovery also tries multiple center-weighted Auto Color histogram windows before raw threshold bracketing. The normal fast path is untouched; these extra passes run only after a miss. If geometry is found but color decoding fails, the captured ROI is retried with the stronger color/geometry recovery, and consecutive failed frames can still be combined with confidence-weighted module voting.
210
213
 
211
214
  ```js
212
215
  const scanner = await startCameraScanner(video, {
@@ -220,6 +223,9 @@ const scanner = await startCameraScanner(video, {
220
223
  cameraAutoColorAnalysisInset: 0.10,
221
224
  cameraAutoEnhanceEvery: 2,
222
225
  cameraFinderRecoveryEvery: 2,
226
+ cameraHighResolutionRecovery: true,
227
+ cameraHighResolutionMaxDimension: 1600,
228
+ cameraHighResolutionEvery: 2,
223
229
  onResult(result) {
224
230
  console.log(result);
225
231
  },
package/docs/CLI.md CHANGED
@@ -134,6 +134,7 @@ npx quadqr-js decode secure-key.png --key <64-hex-key>
134
134
  | `--ecc <L|M|Q|H>` | QuadQR ECC profile. Default: `M` |
135
135
  | `--version <auto|1..40>` | Symbol version. Default: `auto` |
136
136
  | `--compression <mode>` | `none`, `auto`, or `lz`. Default: `auto` |
137
+ | `--high-density` | Enable experimental Triangle16 High Density Mode |
137
138
  | `--sign-key <file>` | Sign using a key bundle generated by `signkeygen` |
138
139
  | `--key-id <id>` | Override the signing key ID stored in the symbol |
139
140
  | `--embed-public-key` | Explicit compatibility mode that embeds the public key |
@@ -148,3 +149,8 @@ npx quadqr-js decode secure-key.png --key <64-hex-key>
148
149
  | `-h, --help` | Show CLI help |
149
150
 
150
151
  Password mode and raw-key mode are mutually exclusive for a single operation.
152
+
153
+
154
+ ## High Density Mode (Experimental)
155
+
156
+ Use `--high-density` to enable the experimental Triangle16 layout with 16 states and 4 raw bits per body cell. Decode is automatic; no matching decode flag is required.
@@ -0,0 +1,100 @@
1
+ # High Density Mode (Experimental)
2
+
3
+ High Density Mode is an experimental QuadQR option implemented with the Triangle16 cell layout. It keeps the existing QuadQR geometry, finder patterns, timing pattern, alignment patterns, calibration, Spectrum ECC, CRC, security envelope, compression, and signing behavior, but changes how payload data cells are represented.
4
+
5
+ ## Physical cell
6
+
7
+ A Triangle16 payload cell is split by one fixed `/` diagonal:
8
+
9
+ ```text
10
+ +---------+
11
+ | AAAAAA /|
12
+ | AAAAA /B|
13
+ | AAAA /BB|
14
+ | AAA /BBB|
15
+ | AA /BBBB|
16
+ | A /BBBBB|
17
+ | /BBBBBBB|
18
+ +---------+
19
+ ```
20
+
21
+ `A` is the upper-left triangle and `B` is the lower-right triangle. Each triangle independently uses the existing RGBW alphabet:
22
+
23
+ ```text
24
+ R = 00
25
+ G = 01
26
+ B = 10
27
+ W = 11
28
+ ```
29
+
30
+ The pair therefore has 16 states:
31
+
32
+ ```text
33
+ R/R R/G R/B R/W
34
+ G/R G/G G/B G/W
35
+ B/R B/G B/B B/W
36
+ W/R W/G W/B W/W
37
+ ```
38
+
39
+ The first triangle carries the high 2 bits and the second triangle carries the low 2 bits. One Triangle16 body cell therefore carries 4 raw bits, so one byte occupies two body cells instead of four RGBW cells.
40
+
41
+ ## Protected header stays solid
42
+
43
+ The protected bootstrap/header intentionally does not use mixed-color triangles. Its normal RGBW header cells are represented as same-color pairs such as `R/R`, `G/G`, `B/B`, and `W/W`.
44
+
45
+ This uses four cells per protected header byte, exactly like RGBW, but makes it much easier for the decoder to recover the mode flag when the image is blurred, skewed, resized, or color-shifted. Header flag bit 6 declares Triangle16 for the ECC-protected body.
46
+
47
+ ## Scanner sampling
48
+
49
+ The scanner does not sample the diagonal or the exact module center. For each data cell it samples two small regions well inside the triangles, approximately around `(0.28, 0.28)` and `(0.72, 0.72)` in normalized module coordinates.
50
+
51
+ Each triangle is classified independently against the calibrated RGBW palette. The cell confidence is the weaker of the two triangle confidences. That confidence feeds the existing confidence-aware Spectrum ECC path, allowing an ambiguous triangle pair to become a useful erasure candidate instead of an arbitrary hard error.
52
+
53
+ The normal image and camera scanner automatically detects High Density Mode and attempts Triangle16 dual-region sampling when needed. No separate scan mode is required. If ordinary finder/alignment geometry is good enough to locate the symbol but not precise enough to decode the half-cell regions, the scanner performs one bounded **precise-alignment recovery** pass. That pass uses denser alignment-pattern probes and a finer sub-module search, then retries the same dual-triangle classifier.
54
+
55
+ ## Rendering rules
56
+
57
+ High Density Mode uses exact hard-edged Triangle16 payload cells. Decorative payload styles are intentionally bypassed in this experimental mode because rounded, inset, soft, or depth effects can reduce the usable sampling area or contaminate the diagonal boundary. Structural modules keep the normal QuadQR rendering behavior.
58
+
59
+ PNG/ImageData, Canvas, SVG, browser, and Node rendering all support Triangle16.
60
+
61
+ ## API
62
+
63
+ ```js
64
+ import { encodeText } from "quadqr-js";
65
+
66
+ const code = encodeText("High-density QuadQR", {
67
+ ecc: "M",
68
+ highDensity: true
69
+ });
70
+ ```
71
+
72
+ High Density Mode is disabled by default. Existing callers remain on normal RGBW mode unless `highDensity: true` is explicitly supplied.
73
+
74
+ ## Capacity
75
+
76
+ Raw body density is:
77
+
78
+ ```text
79
+ RGBW 4 states 2 bits/body cell
80
+ Triangle16 16 states 4 bits/body cell
81
+ ```
82
+
83
+ The protected header remains RGBW-equivalent, and ECC/CRC overhead is unchanged at the byte level, so usable payload capacity is close to but not exactly 2x for a fixed matrix version.
84
+
85
+ Use `getVersionInfo(version, { ecc, highDensity: true })` or the demo capacity calculator for the exact value.
86
+
87
+ ## Reliability caveat
88
+
89
+ Triangle16 doubles raw body bits per cell, but it also halves the spatial area available to each independently classified color. Its meaningful real-world metric is not only bits per matrix cell. It is reliable payload bytes at a fixed physical size, camera distance, angle, lighting condition, resize/compression pipeline, and print quality.
90
+
91
+ The branch should therefore be stress-tested before treating High Density Mode as stable. Important cases include:
92
+
93
+ - perspective and partial finder degradation;
94
+ - defocus and motion blur;
95
+ - low camera pixel coverage per module;
96
+ - JPEG compression and repeated image resizing;
97
+ - shadows, glare, white-balance shifts, and saturation changes;
98
+ - cheap printing, ink spread, paper tint, and camera recapture.
99
+
100
+ If full 16-state reliability becomes the limiting factor, a restricted triangle alphabet can be explored later without changing the basic physical-cell experiment.
package/docs/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # QuadQR Documentation
2
2
 
3
- QuadQR is an experimental four-state RGBW matrix symbology. Each data cell carries exactly two bits using red, green, blue, or white. The JavaScript library supports encoding, canvas/RGBA/SVG rendering, adjustable quiet zones, optional centered logos with transparent or cleared backgrounds, matrix decoding, image and camera scanning, Spectrum ECC, optional authenticated encryption, Node.js PNG/SVG workflows, CDN usage, a CLI, TypeScript declarations, and optional prebuilt WebAssembly acceleration.
3
+ QuadQR is an experimental RGBW matrix symbology. Default RGBW cells carry two bits using red, green, blue, or white. The experimental High Density Mode splits payload cells into two RGBW triangles and carries four raw bits per body data cell. The JavaScript library supports encoding, canvas/RGBA/SVG rendering, adjustable quiet zones, optional centered logos with transparent or cleared backgrounds, matrix decoding, image and camera scanning, Spectrum ECC, optional authenticated encryption, Node.js PNG/SVG workflows, CDN usage, a CLI, TypeScript declarations, and optional prebuilt WebAssembly acceleration.
4
4
 
5
5
  ## Live links
6
6
 
@@ -13,6 +13,7 @@ QuadQR is an experimental four-state RGBW matrix symbology. Each data cell carri
13
13
 
14
14
  - [Getting Started](./GETTING_STARTED.md)
15
15
  - [API Reference](./API.md)
16
+ - [High Density Mode (Experimental)](./HIGH_DENSITY_MODE.md)
16
17
  - [Browser and CDN](./BROWSER_CDN.md)
17
18
  - [Node.js](./NODE.md)
18
19
  - [CLI](./CLI.md)
@@ -0,0 +1,108 @@
1
+ # Triangle16 experimental data-cell profile
2
+
3
+ Triangle16 is an experimental QuadQR data-cell encoding for the high-density branch. It keeps the existing QuadQR geometry, finder patterns, timing pattern, alignment patterns, calibration, Spectrum ECC, CRC, security envelope, compression, and signing behavior, but changes how payload data cells are represented.
4
+
5
+ ## Physical cell
6
+
7
+ A Triangle16 payload cell is split by one fixed `/` diagonal:
8
+
9
+ ```text
10
+ +---------+
11
+ | AAAAAA /|
12
+ | AAAAA /B|
13
+ | AAAA /BB|
14
+ | AAA /BBB|
15
+ | AA /BBBB|
16
+ | A /BBBBB|
17
+ | /BBBBBBB|
18
+ +---------+
19
+ ```
20
+
21
+ `A` is the upper-left triangle and `B` is the lower-right triangle. Each triangle independently uses the existing RGBW alphabet:
22
+
23
+ ```text
24
+ R = 00
25
+ G = 01
26
+ B = 10
27
+ W = 11
28
+ ```
29
+
30
+ The pair therefore has 16 states:
31
+
32
+ ```text
33
+ R/R R/G R/B R/W
34
+ G/R G/G G/B G/W
35
+ B/R B/G B/B B/W
36
+ W/R W/G W/B W/W
37
+ ```
38
+
39
+ The first triangle carries the high 2 bits and the second triangle carries the low 2 bits. One Triangle16 body cell therefore carries 4 raw bits, so one byte occupies two body cells instead of four RGBW cells.
40
+
41
+ ## Protected header stays solid
42
+
43
+ The protected bootstrap/header intentionally does not use mixed-color triangles. Its normal RGBW header cells are represented as same-color pairs such as `R/R`, `G/G`, `B/B`, and `W/W`.
44
+
45
+ This uses four cells per protected header byte, exactly like RGBW, but makes it much easier for the decoder to recover the mode flag when the image is blurred, skewed, resized, or color-shifted. Header flag bit 6 declares Triangle16 for the ECC-protected body.
46
+
47
+ ## Scanner sampling
48
+
49
+ The scanner does not sample the diagonal or the exact module center. For each data cell it samples two small regions well inside the triangles, approximately around `(0.28, 0.28)` and `(0.72, 0.72)` in normalized module coordinates.
50
+
51
+ Each triangle is classified independently against the calibrated RGBW palette. The cell confidence is the weaker of the two triangle confidences. That confidence feeds the existing confidence-aware Spectrum ECC path, allowing an ambiguous triangle pair to become a useful erasure candidate instead of an arbitrary hard error.
52
+
53
+ The normal image and camera scanner automatically attempts Triangle16 sampling. No separate scan mode is required. If ordinary finder/alignment geometry is good enough to locate the symbol but not precise enough to decode the half-cell regions, the scanner performs one bounded **precise-alignment recovery** pass. That pass uses denser alignment-pattern probes and a finer sub-module search, then retries the same dual-triangle classifier.
54
+
55
+ ## Rendering rules
56
+
57
+ Triangle16 uses exact hard-edged triangular payload cells. Decorative payload styles are intentionally bypassed in this profile because rounded, inset, soft, or depth effects can reduce the usable sampling area or contaminate the diagonal boundary. Structural modules keep the normal QuadQR rendering behavior.
58
+
59
+ PNG/ImageData, Canvas, SVG, browser, and Node rendering all support Triangle16.
60
+
61
+ ## API
62
+
63
+ ```js
64
+ import { encodeText, CELL_ENCODINGS } from "quadqr-js";
65
+
66
+ const code = encodeText("High-density QuadQR", {
67
+ ecc: "M",
68
+ cellEncoding: CELL_ENCODINGS.TRIANGLE16
69
+ });
70
+ ```
71
+
72
+ The string form is also accepted:
73
+
74
+ ```js
75
+ const code = encodeText("High-density QuadQR", {
76
+ cellEncoding: "triangle16"
77
+ });
78
+ ```
79
+
80
+ `rgbw` remains the library default so existing callers are not silently moved to an experimental physical format.
81
+
82
+ ## Capacity
83
+
84
+ Raw body density is:
85
+
86
+ ```text
87
+ RGBW 4 states 2 bits/body cell
88
+ Triangle16 16 states 4 bits/body cell
89
+ ```
90
+
91
+ The protected header remains RGBW-equivalent, and ECC/CRC overhead is unchanged at the byte level, so usable payload capacity is close to but not exactly 2x for a fixed matrix version.
92
+
93
+ Use `getVersionInfo(version, { ecc, cellEncoding: "triangle16" })` or the demo capacity calculator for the exact value.
94
+
95
+ ## Reliability caveat
96
+
97
+ Triangle16 doubles raw body bits per cell, but it also halves the spatial area available to each independently classified color. Its meaningful real-world metric is not only bits per matrix cell. It is reliable payload bytes at a fixed physical size, camera distance, angle, lighting condition, resize/compression pipeline, and print quality.
98
+
99
+ The branch should therefore be stress-tested before treating Triangle16 as a stable format. Important cases include:
100
+
101
+ - perspective and partial finder degradation;
102
+ - defocus and motion blur;
103
+ - low camera pixel coverage per module;
104
+ - JPEG compression and repeated image resizing;
105
+ - shadows, glare, white-balance shifts, and saturation changes;
106
+ - cheap printing, ink spread, paper tint, and camera recapture.
107
+
108
+ If full 16-state reliability becomes the limiting factor, a restricted triangle alphabet can be explored later without changing the basic physical-cell experiment.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "quadqr-js",
3
- "version": "1.2.0",
4
- "description": "QuadQR: experimental four-state RGBW matrix code with Spectrum ECC, compression, Ed25519 signing, browser/Node scanning, diagnostics, stress testing, and optional AES-256-GCM security.",
3
+ "version": "1.3.0",
4
+ "description": "QuadQR: experimental RGBW matrix code with optional experimental High Density Mode, Spectrum ECC, browser/Node scanning, compression, signing, diagnostics, stress testing, and AES-256-GCM security.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
7
7
  "module": "./dist/index.js",
@@ -82,6 +82,8 @@
82
82
  "qr",
83
83
  "rgb",
84
84
  "rgbw",
85
+ "high-density",
86
+ "triangle16",
85
87
  "matrix-code",
86
88
  "barcode",
87
89
  "reed-solomon",
@@ -1,8 +1,8 @@
1
1
  import type { EccLevel } from "./index.js";
2
2
  export const STANDARD_QR_BYTE_CAPACITY: Readonly<Record<EccLevel, readonly number[]>>;
3
3
  export function getStandardQrByteCapacity(version: number, ecc?: EccLevel): number;
4
- export function compareCapacity(version: number, ecc?: EccLevel): Record<string, number | string | null>;
5
- export function calculateCapacityPlan(options?: { payload?: string | Uint8Array; payloadBytes?: number; ecc?: EccLevel; compression?: "none" | "auto" | "lz"; signed?: boolean; keyId?: string; embedPublicKey?: boolean }): Record<string, unknown>;
6
- export function buildCapacityComparison(options?: { ecc?: EccLevel; versions?: number[] }): Array<Record<string, number | string | null>>;
4
+ export function compareCapacity(version: number, ecc?: EccLevel, options?: { highDensity?: boolean }): Record<string, number | string | null>;
5
+ export function calculateCapacityPlan(options?: { payload?: string | Uint8Array; payloadBytes?: number; ecc?: EccLevel; highDensity?: boolean; compression?: "none" | "auto" | "lz"; signed?: boolean; keyId?: string; embedPublicKey?: boolean }): Record<string, unknown>;
6
+ export function buildCapacityComparison(options?: { ecc?: EccLevel; highDensity?: boolean; versions?: number[] }): Array<Record<string, number | string | null>>;
7
7
  export function benchmarkCodec(options?: Record<string, unknown>): Record<string, unknown>;
8
8
  export function benchmarkReport(options?: Record<string, unknown>): Record<string, unknown>;
package/types/index.d.ts CHANGED
@@ -17,6 +17,8 @@ export interface EncodeOptions {
17
17
  minVersion?: number;
18
18
  maxVersion?: number;
19
19
  ecc?: EccLevel;
20
+ /** Enable the experimental High Density Mode. Default: false. Uses Triangle16 payload cells at 4 raw bits/body cell. */
21
+ highDensity?: boolean;
20
22
  maskId?: number;
21
23
  text?: boolean;
22
24
  compression?: CompressionMode;
@@ -59,6 +61,9 @@ export interface QuadQRCode {
59
61
  size: number;
60
62
  formatVersion: number;
61
63
  eccLevel: EccLevel;
64
+ highDensity?: boolean;
65
+ bitsPerDataCell?: 2 | 4;
66
+ statesPerDataCell?: 4 | 16;
62
67
  payloadBytes: number;
63
68
  capacityBytes: number;
64
69
  secure?: boolean;
@@ -106,6 +111,9 @@ export interface DecodeResult {
106
111
  size: number;
107
112
  formatVersion: number;
108
113
  eccLevel: EccLevel;
114
+ highDensity?: boolean;
115
+ bitsPerDataCell?: 2 | 4;
116
+ statesPerDataCell?: 4 | 16;
109
117
  secure: boolean;
110
118
  requiresDecryption?: boolean;
111
119
  decrypted?: boolean;
@@ -230,12 +238,27 @@ export interface ScanOptions {
230
238
  maxDimension?: number;
231
239
  sampleRadius?: number;
232
240
  robustSampleRadius?: number;
241
+ /** Disable automatic High Density Mode dual-region sampling. Default: enabled. */
242
+ highDensitySampling?: boolean;
243
+ /** Position of the two High Density Mode samples inside each module. Default: 0.28. */
244
+ highDensitySampleInset?: number;
245
+ /** Radius used around each High Density Mode sample point. */
246
+ highDensitySampleRadius?: number;
247
+ /** Retry failed perspective scans with finer alignment localization. Default: true. */
248
+ preciseAlignmentRecovery?: boolean;
233
249
  adaptiveSampling?: boolean;
234
250
  spatialColorNormalization?: boolean;
235
251
  structureTolerance?: number;
236
252
  maxErasureConfidence?: number;
237
253
  geometryRefinement?: boolean;
238
254
  finderRecovery?: boolean;
255
+ /** Refine a valid projective solution with reliable secondary alignment markers on dense versions. */
256
+ alignmentRefinement?: boolean;
257
+ alignmentRefinePatternThreshold?: number;
258
+ alignmentRefineMaxPoints?: number;
259
+ alignmentRefineMaxDisplacement?: number;
260
+ alignmentRefineCandidateMargin?: number;
261
+ alignmentRefineSkipScore?: number;
239
262
  finderAutoColorBlackClip?: number;
240
263
  finderAutoColorWhiteClip?: number;
241
264
  finderAutoColorHighlightPercentile?: number;
@@ -300,6 +323,11 @@ export interface CameraScanOptions extends ScanOptions {
300
323
  cameraAutoColorTargetSamples?: number;
301
324
  cameraAutoEnhanceEvery?: number;
302
325
  cameraFinderRecoveryEvery?: number;
326
+ /** Retry a dense/partial geometry frame at higher resolution after at least two finders are detected. */
327
+ cameraHighResolutionRecovery?: boolean;
328
+ cameraHighResolutionMaxDimension?: number;
329
+ cameraHighResolutionEvery?: number;
330
+ cameraHighResolutionMinFinders?: number;
303
331
  constraints?: MediaStreamConstraints;
304
332
  onResult?: (result: DecodeResult, frame?: CameraFrameMeta | null) => void | Promise<void>;
305
333
  onDecode?: (result: DecodeResult, frame?: CameraFrameMeta | null) => void | Promise<void>;
@@ -361,7 +389,7 @@ export function runImageStressTest(imageData: ImageDataLike, expected?: { versio
361
389
  export function assessScanability(code: QuadQRCode, renderOptions?: RenderOptions, options?: Record<string, unknown>): Record<string, unknown>;
362
390
  export function rectifyDetectedCode(imageData: ImageDataLike, options?: Record<string, unknown>): ImageDataLike;
363
391
  export function rotateMatrix(matrix: number[][], quarterTurns?: number): number[][];
364
- export function getVersionInfo(version: number, options?: { ecc?: EccLevel }): Record<string, unknown>;
392
+ export function getVersionInfo(version: number, options?: { ecc?: EccLevel; highDensity?: boolean }): Record<string, unknown>;
365
393
  export function crc32(bytes: Uint8Array): number;
366
394
  export function installCrc32Accelerator(accelerator?: ((bytes: Uint8Array) => number) | null): void;
367
395
  export function generateRaw256Key(): Uint8Array;