anyd/codes/qr/mod.rs
1//! QR Code (ISO/IEC 18004) encoder and structural decoder.
2//!
3//! Layout:
4//! - [`gf`] — GF(256) arithmetic and Reed–Solomon encode/decode.
5//! - `tables` — the spec's per-version capacity, EC-block and alignment tables.
6//! - `matrix` — module placement, masking and format/version information.
7//! - `encode` — [`Symbol`] → [`BitMatrix`].
8//! - `decode` — [`BitMatrix`] → [`Symbol`].
9//!
10//! [`Symbol`]: crate::Symbol
11//! [`BitMatrix`]: crate::output::BitMatrix
12
13mod decode;
14mod encode;
15pub mod gf;
16mod matrix;
17mod sample;
18mod tables;
19
20pub use decode::QrDecoder;
21pub use encode::QrEncoder;
22pub use sample::{QrScanner, sample_grid, scan};
23
24/// QR error-correction level, in ascending order of recovery capacity.
25#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
26pub enum EcLevel {
27 /// ~7% recovery.
28 L,
29 /// ~15% recovery.
30 M,
31 /// ~25% recovery.
32 Q,
33 /// ~30% recovery.
34 H,
35}
36
37impl EcLevel {
38 /// The 2-bit field value used in the format information.
39 pub fn format_bits(self) -> u8 {
40 match self {
41 EcLevel::L => 0b01,
42 EcLevel::M => 0b00,
43 EcLevel::Q => 0b11,
44 EcLevel::H => 0b10,
45 }
46 }
47
48 /// Recover an EC level from its 2-bit format field.
49 pub fn from_format_bits(bits: u8) -> Self {
50 match bits & 0b11 {
51 0b01 => EcLevel::L,
52 0b00 => EcLevel::M,
53 0b11 => EcLevel::Q,
54 _ => EcLevel::H,
55 }
56 }
57}
58
59/// A QR symbol version, 1–40. The module grid is `21 + 4 * (version - 1)` on a side.
60#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
61pub struct Version(u8);
62
63impl Version {
64 /// Construct a version, validating the `1..=40` range.
65 pub fn new(v: u8) -> Option<Self> {
66 (1..=40).contains(&v).then_some(Version(v))
67 }
68
69 /// The version number, 1–40.
70 pub fn number(self) -> u8 {
71 self.0
72 }
73
74 /// Side length of the module grid.
75 pub fn size(self) -> usize {
76 21 + 4 * (self.0 as usize - 1)
77 }
78}
79
80/// The data mask pattern applied to the encoding region, 0–7.
81#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
82pub struct Mask(u8);
83
84impl Mask {
85 /// Construct a mask, validating the `0..=7` range.
86 pub fn new(m: u8) -> Option<Self> {
87 (m <= 7).then_some(Mask(m))
88 }
89
90 /// The mask pattern index, 0–7.
91 pub fn index(self) -> u8 {
92 self.0
93 }
94}
95
96/// QR-specific parameters needed to re-encode a symbol identically.
97#[derive(Debug, Clone, PartialEq, Eq)]
98pub struct QrMeta {
99 /// Symbol version (size).
100 pub version: Version,
101 /// Error-correction level.
102 pub ec_level: EcLevel,
103 /// Applied data mask pattern.
104 pub mask: Mask,
105}