dqr/
quirc.rs

1use num_derive::{FromPrimitive, ToPrimitive};
2
3pub type Pixel = u16;
4
5#[derive(Debug, Clone)]
6pub struct Quirc {
7	pub pixels: Vec<Pixel>,
8	pub w: usize,
9	pub h: usize,
10	pub regions: Vec<Region>,
11	pub capstones: Vec<Capstone>,
12	pub grids: Vec<Grid>,
13}
14
15impl Default for Quirc {
16	fn default() -> Self {
17		Self {
18			pixels: Vec::new(),
19			w: 0,
20			h: 0,
21			regions: Vec::with_capacity(254),
22			capstones: Vec::with_capacity(32),
23			grids: Vec::with_capacity(8),
24		}
25	}
26}
27
28impl Quirc {
29	/// Construct a new QR-code recognizer.
30	pub fn new() -> Self {
31		Self::default()
32	}
33
34	/// Resize the QR-code recognizer. The size of an image must be
35	/// specified before codes can be analyzed.
36	///
37	/// This function returns 0 on success, or -1 if sufficient memory could  not be allocated.
38	pub fn resize(&mut self, width: usize, height: usize) {
39		if self.w == width && self.h == height {
40			return;
41		}
42
43		let newdim = width * height;
44		self.pixels.resize(newdim, 0);
45		self.w = width;
46		self.h = height;
47	}
48
49	pub fn num_regions(&self) -> usize {
50		self.regions.len()
51	}
52
53	pub fn num_capstones(&self) -> usize {
54		self.capstones.len()
55	}
56
57	/// Return the number of QR-codes identified in the last processed image.
58	pub fn count(&self) -> usize {
59		self.grids.len()
60	}
61
62	/// Resets all internal state.
63	pub fn reset(&mut self) {
64		self.regions.clear();
65		self.capstones.clear();
66		self.grids.clear();
67	}
68}
69
70#[derive(Debug, Copy, Clone, Default)]
71pub struct Grid {
72	pub caps: [usize; 3],
73	pub align_region: Option<Pixel>,
74	pub align: Point,
75	pub tpep: [Point; 3],
76	pub hscan: i32,
77	pub vscan: i32,
78	pub grid_size: i32,
79	pub c: [f64; 8],
80}
81
82#[derive(Debug, Copy, Clone, Default)]
83pub struct Point {
84	pub x: i32,
85	pub y: i32,
86}
87
88impl Point {
89	pub fn clear(&mut self) {
90		self.x = 0;
91		self.y = 0;
92	}
93}
94
95#[derive(Debug, Copy, Clone, Default)]
96pub struct Capstone {
97	pub ring: i32,
98	pub stone: i32,
99	pub corners: [Point; 4],
100	pub center: Point,
101	pub c: [f64; 8],
102	pub qr_grid: i32,
103}
104
105#[derive(Debug, Copy, Clone, Default)]
106pub struct Region {
107	pub seed: Point,
108	pub count: i32,
109	pub capstone: i32,
110}
111
112/// This structure is used to return information about detected QR codes
113/// in the input image.
114#[derive(Copy, Clone, Debug)]
115pub struct Code {
116	/// The four corners of the QR-code, from top left, clockwise
117	pub corners: [Point; 4],
118	/// The number of cells across in the QR-code. The cell bitmap
119	/// is a bitmask giving the actual values of cells. If the cell
120	/// at (x, y) is black, then the following bit is set:
121	/// ```ignore
122	///     cell_bitmap[i >> 3] & (1 << (i & 7))
123	///     // where i = (y * size) + x.
124	/// ```
125	pub size: i32,
126	pub cell_bitmap: [u8; 3917],
127}
128
129impl Default for Code {
130	fn default() -> Self {
131		Self { corners: [Point::default(); 4], size: 0, cell_bitmap: [0; 3917] }
132	}
133}
134
135impl Code {
136	pub fn clear(&mut self) {
137		for val in self.corners.iter_mut() {
138			val.clear();
139		}
140		self.size = 0;
141		for val in self.cell_bitmap.iter_mut() {
142			*val = 0;
143		}
144	}
145}
146
147/// This structure holds the decoded QR-code data
148#[derive(Clone, Default)]
149pub struct Data {
150	///  Various parameters of the QR-code. These can mostly be  ignored
151	/// if you only care about the data.
152	pub version: usize,
153	pub ecc_level: EccLevel,
154	pub mask: i32,
155	/// This field is the highest-valued data type found in the QR code.
156	pub data_type: Option<DataType>,
157	/// Data payload. For the Kanji datatype, payload is encoded as Shift-JIS.
158	/// For all other datatypes, payload is ASCII text.
159	pub payload: Vec<u8>,
160	/// ECI assignment number
161	pub eci: Option<Eci>,
162}
163
164/// Obtain the library version string.
165pub fn version() -> String {
166	env!("CARGO_PKG_VERSION").to_string()
167}
168
169/// QR-code ECC types
170#[derive(Debug, Copy, Clone, FromPrimitive, ToPrimitive, PartialEq, Eq, Hash)]
171pub enum EccLevel {
172	M = 0,
173	L = 1,
174	H = 2,
175	Q = 3,
176}
177
178#[allow(clippy::derivable_impls)]
179impl Default for EccLevel {
180	fn default() -> Self {
181		EccLevel::M
182	}
183}
184
185/// QR-code data types
186#[derive(Debug, Copy, Clone, FromPrimitive, ToPrimitive, PartialEq, Eq, Hash)]
187#[repr(i32)]
188pub enum DataType {
189	Numeric = 1,
190	Alpha = 2,
191	Byte = 4,
192	Eci = 7,
193	Kanji = 8,
194}
195
196impl std::fmt::Display for DataType {
197	fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
198		let x = match self {
199			DataType::Numeric => "numeric",
200			DataType::Alpha => "alpha",
201			DataType::Byte => "byte",
202			DataType::Eci => "eci",
203			DataType::Kanji => "kanji",
204		};
205		f.write_str(x)
206	}
207}
208
209/// Common character encodings
210#[derive(Debug, Copy, Clone, FromPrimitive, ToPrimitive, PartialEq, Eq, Hash)]
211pub enum Eci {
212	Iso8859_1 = 1,
213	Ibm437 = 2,
214	Iso8859_2 = 4,
215	Iso8859_3 = 5,
216	Iso8859_4 = 6,
217	Iso8859_5 = 7,
218	Iso8859_6 = 8,
219	Iso8859_7 = 9,
220	Iso8859_8 = 10,
221	Iso8859_9 = 11,
222	Windows874 = 13,
223	Iso8859_13 = 15,
224	Iso8859_15 = 17,
225	ShiftJis = 20,
226	Utf8 = 26,
227}