@forgesworn/qr 0.0.0-stage → 0.2.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/CHANGELOG.md ADDED
@@ -0,0 +1,120 @@
1
+ # Changelog
2
+
3
+ ## 0.2.0
4
+
5
+ - CI downloads and verifies the real-photograph set for both TypeScript
6
+ and Kotlin, and runs the WebAssembly result, option, encoder, module-grid
7
+ and memory checks, plus native renderer comparisons. Local tests use at
8
+ most two workers, and the damage suites inherit the shared timeout.
9
+
10
+ - Text without a `mode` is split into the numeric, alphanumeric and byte
11
+ segments with the fewest bits, so payment URIs with an uppercase body fit
12
+ smaller versions. `QrCode` gains `segments`. Symbols for text that one
13
+ mode already covers are unchanged.
14
+ - The decoder reports `structuredAppend` and `fnc1`, reads kanji segments
15
+ and the other ECI character sets as text, and reads Shift_JIS byte data
16
+ that carries no ECI. Windows 1252 (ECI 23) is read by hand, because one
17
+ supported Node release reads that set as Latin-1.
18
+ - A test set of 184 real photographs, fetched by hash at test time and not
19
+ committed, with a floor on how many are read and a rule that none may
20
+ decode to the wrong text.
21
+ - The decoder reads steeply tilted codes: finders stretched by perspective,
22
+ triples whose far side is much narrower, and an alignment search placed
23
+ by a projective map. A symbol of version 7 or above whose two version
24
+ blocks are both unreadable is read from its size.
25
+ - When the ordinary search reads nothing, the decoder looks once more at
26
+ up to four placements whose two format copies agree, moving module
27
+ centres onto the timing patterns and edges the picture shows and sampling
28
+ grey. It reads codes on curved or warped surfaces that were missed
29
+ before; tests of damaged symbols require nothing or the original text.
30
+ - From version 7 that second look first bends the placement onto the
31
+ alignment patterns it can find, so large symbols photographed through a
32
+ lens or on paper that is not flat read. It makes no more reads than
33
+ before, and a placement whose version information names another size no
34
+ longer takes one of the four places.
35
+ - Fixed: a version 40 symbol whose size estimate came out just past 177
36
+ modules was given up on without trying 177.
37
+ - Fixed: a texture matching a mask pattern beside finder patterns (a
38
+ checkerboard, stripes, a screen's moire) could be returned as a read with
39
+ empty text. A symbol whose data codewords are all zero now reads as
40
+ nothing; an empty payload as `encode('')` writes it still reads.
41
+ - The decoder refuses a block that needed more corrections than Table 9
42
+ allows it. That changes versions 1-L, 1-M and 2-L only, where the standard
43
+ holds back check codewords to catch a misdecode and Reed-Solomon alone
44
+ would correct one error more (3, 5 and 5 against 2, 4 and 4). A damaged
45
+ symbol at those three sizes that was read on its last correctable error
46
+ now reads as nothing; one photograph of the test set is lost to it, so
47
+ the floor is 177.
48
+ - When nothing reads at full size, the decoder searches the picture again
49
+ shrunk by 8, 4 and 2, so close-ups whose large modules carry scan lines,
50
+ a screen's moire or grain read. The reduced sizes share the frame's caps
51
+ on maps and second looks, and a read there counts only if both format
52
+ copies agree with its level and mask. The caps are unchanged, but a frame
53
+ with no code in it now costs more on average. Two more photographs of the
54
+ test set read, so the floor is 179.
55
+ - A conformance pack for ports in other languages, `vectors/conformance.json`
56
+ with `vectors/README.md`: greyscale conversion, module grids, and for 58
57
+ pictures the binarised image, the reduced sizes, the finder candidates,
58
+ the triples, sizes and sampling maps, the result and the work counted.
59
+ Both ports are held to it.
60
+ - A Rust port in `rust/`, with no dependencies: the encoder, SVG and
61
+ terminal renderers and the whole decoder, held to the same vectors and
62
+ giving the same reads, locations and counted work as the TypeScript on
63
+ 603 pictures at four turns each, from sets kept outside the repository.
64
+ It builds to WebAssembly and decodes in about half the TypeScript's time
65
+ there. It bundles no character tables, so its text can differ from the
66
+ other ports', and it refuses hanzi symbols. Not published as a package
67
+ yet.
68
+ - SPEC.md states every stage of the decoder exactly, and the details of
69
+ the encoder that were left to the code; lengths are a square root of
70
+ squares so that ports agree to the last place.
71
+ - Text under an ECI the platform cannot read, or one that names no set the
72
+ decoder knows, is no longer guessed as UTF-8 or Latin-1: what cannot be
73
+ read is U+FFFD, with ASCII kept under the single-byte sets. `bytes` and
74
+ `eci` are unchanged. Greek under ECI 9, read where there is no decoder
75
+ for it, used to come back as accented Latin letters.
76
+ - The decoder reads hanzi segments (GB2312).
77
+ - Decoding is faster with no change to what is read or to the work counted.
78
+ The row scans for finder and alignment patterns walk each row's changes
79
+ of colour, found once and shared by both polarities, and the three
80
+ reduced sizes come from one pass over the picture. Measured in Node on
81
+ one arm64 machine, on the photographs used in development (about 4
82
+ megapixels on average): the median frame that read took 6.7 ms against
83
+ 10.6, the median frame that did not 11.3 ms against 28.2, and the totals
84
+ over the set, which the slowest frames dominate, fell to about 40% and
85
+ 30%. A clean code that reads at the first try gains little, and a frame
86
+ of pure noise about a fifth. The Kotlin port's total was roughly half on
87
+ a desktop JVM. The rows' changes of colour are kept while a frame is
88
+ searched: up to 4 bytes a pixel more on a picture that is all fine
89
+ texture, and 6 to 10 MB more at the peak on 12-megapixel photographs.
90
+ - The locator's work on a frame full of finder-like patterns is bounded.
91
+ - `encode` takes only a string or a `Uint8Array` and says what it was given
92
+ otherwise; input no version can hold is refused before anything is built
93
+ from it, so a named mode with over-long text now throws `QrCapacityError`
94
+ first. `decode` takes only `Uint8Array` or `Uint8ClampedArray` data,
95
+ refuses a buffer of three bytes a pixel unless `channels` is named, and
96
+ checks `inversion`. `null` options mean none in both.
97
+ - The tests read every version at every level, filled to the last byte,
98
+ back with an independent decoder; one vector added, version 23 at
99
+ level L.
100
+ - Fixed: `decode` checks the data length when `channels` is given; `isDark`
101
+ is false outside the symbol; a fixed `version` below `minVersion` throws;
102
+ `toSvg` output always parses as XML, and an empty `title` adds no image
103
+ role.
104
+ - Kotlin port of the encoder and decoder in `kotlin/`, pure JVM 17, checked
105
+ against the shared encode vectors and decode frames, with an independent
106
+ library as a test-only oracle; a `kotlin` job in CI.
107
+
108
+ ## 0.1.0
109
+
110
+ - First release: encoder (versions 1-40, levels L/M/Q/H, numeric,
111
+ alphanumeric and byte modes, UTF-8 ECI) with SVG, canvas and terminal
112
+ renderers.
113
+ - Decoder: RGBA or greyscale frames, local-threshold binarisation, finder
114
+ and alignment search, perspective sampling, Reed-Solomon correction,
115
+ inverted and mirrored codes, numeric, alphanumeric, byte, kanji (as
116
+ bytes), ECI, structured append and FNC1 segments. `decodeModules` for a
117
+ module grid.
118
+ - Encode vectors from an independent encoder; round-trip tests through an
119
+ independent decoder; decoder tests on synthetic distorted frames with that
120
+ decoder as the bar.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 TheCryptoDonkey
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.