Conversation
Port of paulmillr/qr 0.7.0 (MIT OR Apache-2.0, ZXing-derived) as packages/barcodes: spec.rip (ISO/IEC 18004 tables, GF(2^8), BCH and Golay words), barcodes.rip (encodeQR, packed-bitmap encoder with the word-parallel mask race), decode.rip (decodeQR, decodeQRBatch, QRScanner with the zero-allocation frame path) and dom.rip (QRCanvas, QRCamera, frameLoop, svgToPng, gifToPng, BarcodeDetector). Labeled blocks became named methods and delegated generators; the shared scratch arena became named arrays. Encoder output is byte-identical to the reference on 1452 checks across every version, level, mask and output; the decoder matches on 192 synthetic checks. Under Bun the encoder is equal or faster and the decoder within noise. test.rip pins spec tables, codewords, every version and mask against vectors generated from the reference, then round-trips the decoder over rotations, inverted symbols, input formats, batch decoding and scanner reuse.
Add code128.rip with both sides of ISO/IEC 15417 in one file: an encoder that picks the shortest codeword sequence over subsets A, B and C by dynamic programming, with GS1-128 FNC1 and the six QR outputs, and a scan-line reader that matches each eleven-module group to its nearest codeword in both directions, on both axes and in both polarities, then verifies stop, termination bar and the mod-103 check. Lift the GIF87a writer into gif.rip and the image validation and luma conversion into image.rip so both symbologies share them. Re-export the Code 128 entry points from the encoder and decoder entries. Replace every def declaration with the standard name =! (args) -> form; void procedures ending in a loop return explicitly so the arrow form does not collect. Emitted JS, parity oracles and benchmarks are unchanged. Tests: 33 passing, with a Code 128 section pinning the published vector, subset choices, every output, and round trips across scales, rotations, inversion, luma input and GS1-128.
Merge the QR encoder and decoder into qr.rip beside code128.rip, and reduce barcodes.rip to the root entry that re-exports both symbologies. Subpaths are ./qr, ./code128 and ./dom. Every module-level helper in qr.rip is a const binding: the merge exposed an encoder local silently overwriting the decoder's plain-assigned GF multiply, and a const turns any such collision into a compile error. Code 128 validates its arguments through the same asString, asObject and asInt helpers the QR encoder uses. Tests 33/33, parity oracles unchanged, bench unchanged.
Read packed four-byte pixels as whole words in the luma conversion, one load per pixel unrolled four wide; the (r + 2g + b) / 4 weights are symmetric in r and b, so every RGBA/BGRA/X layout takes the path. Sum the 2x2 pyramid box filter in two 16-bit lanes per word. Both gate on little endian and alignment and keep the byte loops as fallback. Create payload byte views on first use instead of one per possible length at construction, and test the finder ratio in the scan loop before calling recordFinder. Decoder results are unchanged: parity oracles report zero mismatches. Against the reference implementation under Bun the decoder now runs 33% faster at 1080p, 35% at 720p and 66% on a small raster.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
A new
packages/barcodespackage: a pure-Rip port of Paul Miller'sqr0.7.0 (encoder, camera-budgeted decoder, canvas and camera plumbing) plus a Code 128 encoder and reader, zero dependencies, browser-safe.qr.ripholds the QR encoder, decoder andQRScanner. The encoder is byte-identical to the reference on 1452 checks across every version, level, mask and output; the decoder is identical on 192 synthetic checks across rotations, inversion, input formats and batch decoding.code128.ripholds both sides of ISO/IEC 15417: shortest-sequence subset selection by dynamic programming, GS1-128 FNC1, the same six outputs, and a scan-line reader that handles both directions, both axes and inverted symbols.barcodes.ripis the root entry re-exporting both symbologies;gif.ripandimage.ripare the writer and image-input helpers they share;dom.ripis the canvas, camera andBarcodeDetectorlayer.Performance
Under Bun against the reference TypeScript, best of three:
The decoder wins come from reading packed pixels as whole words in the luma conversion and the pyramid box filter, and from creating payload views on first use instead of one per possible length at construction. Decoder output is unchanged.
Test
bun run testinpackages/barcodes: 33 tests pinning spec tables, codewords, every output, every version and mask, decoder round trips, Code 128 vectors and round trips, and the package surface including browser safety.