Conversation
Encoder: spec-recommended text/byte/numeric switching, four text submodes, ECI for non-Latin-1 text, GF(929) Reed-Solomon at all nine levels from a generated polynomial, automatic level and dimensions, compact symbols, and the raw/ascii/term/svg/gif/data-url renderers. Verified byte-for-byte against zxing-cpp on 22 encodings. Reader: start or stop pattern located on middle-out scan lines, the edge tracked and fitted through every line, rays sampled along the true row direction with sub-pixel edges, codewords by edge-to-similar-edge lookup with a width fallback, cells voted into rows by indicator and cluster, errors-and-erasures Reed-Solomon, and text/byte/numeric/ECI/ macro decompaction. Reads 54 of the 58 ZXing blackbox images in sets 1-3 at 0, 90, 180 and 270 degrees, in single-digit milliseconds. The scan-line samplers move from code128.rip to image.rip and the ECI decoders from qr.rip to eci.rip so both readers share them.
The reader measures its own row-direction error from the cluster drift along each ray and resamples with the corrected direction, which reads wide, short symbols and lifts the ZXing blackbox sets 1-3 to 57 of 58. A missed cell advances by the nominal pitch so repeated codewords cannot be read two runs out of phase. Rays run one row past each end. Tests: codeword vectors including the specification's worked examples, Reed-Solomon at the capacity boundary, layout, pinned symbols verified with zxing-cpp, renderer agreement, round trips over scales, row heights, rotations, inversion, shapes, shear, corners, cropped and torn start patterns, holes, and the decompaction paths.
The reader keeps one set of buffers sized to the largest image side seen, so a camera loop allocates once. Ray sampling clips the in-image span analytically and fills the rest as paper, with per-format inner loops free of bounds checks. Each scan line's end pattern bounds the ray length to the symbol's width instead of the widest symbol possible. The edge hysteresis is a third of the ray's range, which keeps the blurred corpus image 2/06 decoding once rays no longer run past the image edge. The start-pattern search keeps a sliding window sum and skips windows narrower than a module per run before comparing. Bun 1.4.0, Apple M5, best of three, synthetic RGBA frames: decode 300x100 raster, 9 rows x 2 cols 192 us -> 69 us decode 1280x720 frame, one symbol 850 us -> 178 us decode 1920x1080 frame, 192 bytes 1060 us -> 289 us decode 1920x1080 noise, no symbol 806 us -> 295 us read 2390x2220 corpus image 1/12, warm 11000 us -> 7800 us ZXing blackbox sets 1-3 stay at 57/58 at 0, 90, 180 and 270 degrees; the debug state and unused test exports are gone from the reader.
The README gains a PDF417 section (compaction, options, outputs, reader result, limits, corpus figures), encode and decode timings, and credits for the zxing-cpp and ZXing corpus oracles. BarcodeDetector reports pdf417 alongside qr_code, trying QR first and then readPDF417, with the symbol corners as cornerPoints. The scan demo feeds each frame to readPDF417 after readCode128.
A row fit whose rows run against the walk along the tracked edge marks a mirror image; the stack is then walked from its other end instead of the fit being clamped. Tests cover a reflected symbol, whole rows torn off the top and bottom, rows one pixel tall, and the aspect option, so every reader claim in the README has a test behind it. The ascii and term outputs are described as drawing each row rowHeight modules tall, aspect as an integer, and the credits and pin comment no longer narrate history. The pixel position in readFrom and the paint helper is pos and at rather than a shadow of p, and the assignment runs the review found are aligned.
…ches An odd text tail padded in the punctuation submode is a latch to alpha, not a shift, so the encoder continues from alpha after a byte shift as every decoder does; 'AB1;;\x01ABCDE' decoded as 'AB1;;\x01;BCDE' before. A symbol holds at most 928 codewords whatever its shape: the automatic layout skips larger pairs (needs 921..928 chose 20x47) and explicit columns or rows past the cap raise RangeError. A punctuation run from alpha or lower latches through mixed when the latch and the way back out cost fewer symbols than a shift per character, and the mixed-submode latch uses the same accounting. Pins changed by the latch rule, each decoded byte-exact by zxing-cpp: ';;;;;;;;;' 86x18 -> 86x15, hash 4889440228876649914 'line one\nline two\r\n\ttabbed' hash 3017900233706190855, same size Two new codeword vectors, 'AB1;;\x01;;;;;' and 'AB1;;\x01ABCDE', parse back to their text and decode byte-exact with zxing-cpp.
In mirror mode the tracked edge is the stop pattern, so the far corners lie on the anchor's other side; they were projected a symbol width past it. Metadata claiming more than 928 cells is rejected before the vote, since the codeword buffers hold 928 and reads past them made every syndrome NaN and the correction report a clean block. A stream that corrects but does not parse is a miss, not an exception out of readPDF417. The run buffer has room for the extra run a ray of alternating pixels produces. The cropped-start test now checks the stop edge and the width from the corners.
A photograph taken from the side leans the start and stop edges while the rows stay level, so rays square to the start edge crossed more than a row per codeword and the one such image in ZXing's corpus never got a readable cell. The pattern at the row's other end is tracked as an edge of its own when the scan line found it, and the row direction runs from the leading edge to that one, averaged over the two ends; a tail edge that holds fewer than half the lines, or that points away, leaves the rows square to the edge as before. ZXing blackbox sets 1-3 go from 57/58 to 58/58 at 0, 90, 180 and 270 degrees. Bun 1.4.0, Apple M5, best of three, the second track's cost: decode 300x100 raster, 9 rows x 2 cols 69 us -> 83 us decode 1280x720 frame, one symbol 176 us -> 232 us decode 1920x1080 frame, 192 bytes 285 us -> 343 us decode 1920x1080 noise, no symbol 290 us -> 302 us
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
Adds PDF417 (ISO/IEC 15438) to
rip/barcodesaspackages/barcodes/pdf417.rip, a cleanroom encoder and reader alongside QR and Code 128, with the ECI table moved toeci.ripand the scan-line samplers toimage.ripfor sharing.Encoder: text (four submodes with cost-based latches and shifts), byte and numeric compaction switching where the specification's rules say a switch pays, UTF-8 behind ECI 26 for text beyond Latin-1, GF(929) parity at nine levels with the recommended automatic level, automatic layout by aspect ratio or explicit columns and rows, compact symbols, and the six outputs (
raw,ascii,term,svg,gif,data-url).Reader: middle-out scan lines find a start pattern forward or reversed in both polarities, or a stop pattern read backward when the start is cropped. Both the anchor edge and the edge at the row's other end are tracked up and down the stack with least-squares fits, rays are sampled across every row along the direction between them (right for rotations and for side-on perspective alike) with a drift-corrected second pass, run lengths come from midpoint crossings between local extrema, codewords are looked up by an edge-to-similar-edge key and a 2^17 width table, each cell is voted into the row and column its indicators and cluster name, and errors and erasures are corrected together with one parity codeword held back so damage misses rather than misdecoding. Macro PDF417 segment metadata is parsed.
BarcodeDetectorreportspdf417, and the scan demo reads PDF417 after Code 128.Verification
bun run test:all26 lanes, 9,904 tests green.Performance
Bun 1.4.0, Apple M5, best of three, synthetic RGBA frames:
Hello PDF417Corpus photographs decode in 0.4 to 8 ms warm.