anyd 0.1.0

From-scratch encoding and decoding of 1D and 2D barcodes with lossless round-trip and live-video detection
Documentation
  • Coverage
  • 100%
    622 out of 622 items documented1 out of 319 items with examples
  • Size
  • Source code size: 1.11 MB This is the summed size of all the files inside the crates.io package for this release.
  • Documentation size: 11.47 MB This is the summed size of all files generated by rustdoc for all configured targets
  • Ø build duration
  • this release: 4s Average build duration of successful builds.
  • all releases: 5s Average build duration of successful builds in releases after 2024-10-23.
  • Links
  • KarpelesLab/anydcode
    0 0 0
  • crates.io
  • Dependencies
  • Versions
  • Owners
  • MagicalTux

AnyDCode

A from-scratch Rust library for decoding and encoding 1D and 2D barcodes, aiming for the widest possible symbology coverage while preserving every variation of a code.

Goals

  • Lossless round-trip. A decoded [Symbol] carries not just its payload but the exact encoding decisions β€” segmentation, version/size, error-correction level, mask. Feeding a decoded symbol straight back into the encoder reproduces the original symbol byte-for-byte.
  • Live-video ready. A cheap per-frame detection pass (locate + classify) is separated from a heavier analysis/decode pass, and previous-frame hints let the pipeline skip re-analyzing codes it already knows.
  • Portable input. The video boundary is a borrowed luminance buffer (GrayFrame); the caller owns capture and color conversion, so the core has no media dependencies.

Status

The full symbology catalog is modeled in the Symbology enum, but implementations land incrementally. Query Symbology::is_implemented() at runtime. Legend: βœ… done Β· 🚧 in progress Β· ⬜ planned.

2D β€” matrix

Symbology Encode Decode Detect
QR Code (v1–40, all EC levels & masks) βœ… βœ… βœ…ΒΉ
Data Matrix (ECC 200, square sizes, ASCII+Base256) βœ… βœ… βœ…Β³
Aztec (compact + full range, all modes) βœ… βœ… ⬜
Aztec Runes ⬜ ⬜ ⬜
Micro QR Code (M1–M4) βœ… βœ… ⬜
Rectangular Micro QR (rMQR, all 32 sizes) βœ… βœ… ⬜
MaxiCode (modes 2–6) βœ… βœ… ⬜
Han Xin · Grid Matrix · DotCode ⬜ ⬜ ⬜

2D β€” stacked

Symbology Encode Decode Detect
PDF417 (Text/Byte/Numeric, EC 0–8) βœ… βœ… βœ…β΄
MicroPDF417 ⬜ ⬜ ⬜
Code 16K · Code 49 · Codablock F ⬜ ⬜ ⬜
GS1 DataBar Stacked / Stacked Omni / Expanded Stacked ⬜ ⬜ ⬜

1D β€” linear

Symbology Encode Decode Detect
EAN-13 Β· EAN-8 Β· UPC-A Β· UPC-E βœ… βœ… βœ…Β²
UPC/EAN add-ons: EAN-2 Β· EAN-5 βœ… βœ… βœ…Β²
Code 128 Β· GS1-128 βœ… βœ… βœ…Β²
Code 39 Β· Code 93 Β· Code 11 βœ… βœ… βœ…Β²
ITF Β· Standard / IATA / Matrix 2 of 5 βœ… βœ… βœ…Β²
Codabar Β· MSI Plessey Β· Plessey βœ… βœ… βœ…Β²
Telepen βœ… βœ… βœ…Β²
Pharmacode (1- & 2-track) βœ… βœ… ⬜
GS1 DataBar Omni (RSS-14) Β· Limited Β· Expanded βœ… βœ… ⬜
DX Film Edge ⬜ ⬜ ⬜

Postal (height-modulated)

Symbology Encode Decode Detect
POSTNET Β· PLANET Β· Intelligent Mail (IMb) βœ… βœ… ⬜
Royal Mail (RM4SCC) Β· Dutch KIX βœ… βœ… ⬜
Mailmark · Australia Post · Japan Post ⬜ ⬜ ⬜

ΒΉ QR ships a full image sampler: Otsu binarization β†’ finder-pattern detection β†’ perspective recovery (via the bottom-right alignment pattern) β†’ sub-pixel grid sampling β†’ decode. Robust to any-angle rotation, moderate tilt, blur and noise (envelope documented in tests/harness_image.rs).

² 1D detection is the shared scan1d luminance front-end (edge detection → run-length → normalized LinearPattern), feeding each symbology's decoder. The end-to-end pixel→symbol path is verified for Code 128, Code 39 and EAN-13 in tests/scan1d_pipeline.rs; it applies to any standard bar/space linear code. DataBar (finder-pattern based) and Pharmacode need dedicated samplers.

Β³ Data Matrix ships an image sampler: Otsu binarization β†’ largest-component isolation β†’ solid-L finder + timing-edge line fitting β†’ perspective corners β†’ imgproc grid sampling, with symbol size and grid chirality confirmed by Reed–Solomon. Robust to any-angle rotation, scale, blur/noise and (size-graded) tilt; envelope in tests/datamatrix_image.rs.

⁴ PDF417 (finder-less) is located by its start/stop guard columns β†’ RANSAC edge fit β†’ affine grid sampling β†’ RS-corrected decode. Handles upright, rotation ≀±10Β°, scale, blur and noise; perspective keystoning is out of scope (no interior anchor). Envelope in tests/pdf417_image.rs.

Naming note. GS1 DataBar was formerly "RSS": DataBar Omnidirectional = RSS-14, DataBar Limited = RSS Limited, DataBar Expanded = RSS Expanded. Codabar is sometimes called "Coda"/NW-7. These are aliases for the same Symbology variants above.

Example: QR round-trip

use anyd::codes::qr::{EcLevel, QrDecoder, QrEncoder};
use anyd::traits::{Decode, Encode};

let encoder = QrEncoder::new();
let symbol = encoder.build_text("HELLO WORLD", EcLevel::Q).unwrap();
let encoding = encoder.encode(&symbol).unwrap();

let decoded = QrDecoder::new().decode(&encoding).unwrap();
assert_eq!(decoded.text().as_deref(), Some("HELLO WORLD"));
// Re-encoding the decoded symbol yields the identical matrix.
assert_eq!(encoder.encode(&decoded).unwrap(), encoding);

Command-line tool (anyd)

An optional binary is bundled behind the cli feature, so the library itself stays dependency-free. It reads/writes PNG via oxideav-png (with default features off β€” no codec-registry dependency) and can also emit Unicode (for the terminal) or SVG (raw XML).

$ cargo build --release --features cli      # builds target/release/anyd

# Encode β†’ PNG / SVG / terminal
$ anyd encode qr "https://example.com" --format png --out qr.png --scale 8
$ anyd encode ean13 5901234123457 --format svg --out barcode.svg
$ anyd encode qr "HELLO" --format unicode          # half-block art in the terminal

# Decode a PNG (tries QR, Data Matrix, PDF417, and the 1D front-end)
$ anyd decode qr.png
QR Code: https://example.com

$ anyd list                                        # encodable symbology names

Options: --format png|unicode|svg, --out FILE, --scale N (px/module), --ec L|M|Q|H (QR/Micro QR) or --ec 0-8 (PDF417), --invert (terminal colours).

Architecture

Symbol  ─── the lossless currency: segments + symbology-specific meta
  β”‚
  β”œβ”€ Encode ──▢ Encoding (BitMatrix for 2D, LinearPattern for 1D)
  └─ Decode ◀── Encoding

Image pipeline (pixels β†’ symbol):
  GrayFrame ─▢ [ imgproc: binarize Β· homography Β· grid-sample ]  ─▢ BitMatrix ─▢ Decode   (2D)
  GrayFrame ─▢ [ scan1d: edge-detect Β· run-length Β· quantize   ]  ─▢ LinearPattern ─▢ Decode (1D)

Live video:  GrayFrame ──▢ Detect ──▢ Candidate ──▢ Analyze ──▢ Symbol
                              β–²                          β”‚
                              └────── Hints β—€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  (skip known codes)

Supporting modules: imgproc (Otsu/adaptive binarization, connected components, 4-point homography, sub-pixel grid sampling β€” the 2D sampler toolkit), scan1d (generic 1D luminance front-end), render (Encoding β†’ grayscale) and transform (rotation/perspective/blur/noise) for the test harness.

Correctness is anchored to independent reference vectors, not self-consistency: the ISO/IEC 18004 QR example, the ISO/IEC 16022 Data Matrix example, ISO/IEC 15438 + ZXing vectors for PDF417, BWIPP-rendered patterns for DataBar, and documented check-digit/pattern references for the 1D codes — plus exhaustive encode→decode→ re-encode identity tests, and full image-pipeline tests (encode → render → transform → sample → decode) for QR and the 1D front-end.

License

MIT © Karpelès Lab Inc.