• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * QR Code generator library (Rust, no heap)
3  *
4  * Copyright (c) Project Nayuki. (MIT License)
5  * https://www.nayuki.io/page/qr-code-generator-library
6  *
7  * Permission is hereby granted, free of charge, to any person obtaining a copy of
8  * this software and associated documentation files (the "Software"), to deal in
9  * the Software without restriction, including without limitation the rights to
10  * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
11  * the Software, and to permit persons to whom the Software is furnished to do so,
12  * subject to the following conditions:
13  * - The above copyright notice and this permission notice shall be included in
14  *   all copies or substantial portions of the Software.
15  * - The Software is provided "as is", without warranty of any kind, express or
16  *   implied, including but not limited to the warranties of merchantability,
17  *   fitness for a particular purpose and noninfringement. In no event shall the
18  *   authors or copyright holders be liable for any claim, damages or other
19  *   liability, whether in an action of contract, tort or otherwise, arising from,
20  *   out of or in connection with the Software or the use or other dealings in the
21  *   Software.
22  */
23 
24 
25 //! Generates QR Codes from text strings and byte arrays.
26 //!
27 //! This project aims to be the best, clearest QR Code generator library.
28 //! The primary goals are flexible options and absolute correctness.
29 //! Secondary goals are compact implementation size and good documentation comments.
30 //!
31 //! Home page with live JavaScript demo, extensive descriptions, and competitor comparisons:
32 //! [https://www.nayuki.io/page/qr-code-generator-library](https://www.nayuki.io/page/qr-code-generator-library)
33 //!
34 //! # Features
35 //!
36 //! Core features:
37 //!
38 //! - Significantly shorter code but more documentation comments compared to competing libraries
39 //! - Supports encoding all 40 versions (sizes) and all 4 error correction levels, as per the QR Code Model 2 standard
40 //! - Output format: Raw modules/pixels of the QR symbol
41 //! - Detects finder-like penalty patterns more accurately than other implementations
42 //! - Encodes numeric and special-alphanumeric text in less space than general text
43 //! - Open-source code under the permissive MIT License
44 //!
45 //! Manual parameters:
46 //!
47 //! - User can specify minimum and maximum version numbers allowed, then library will automatically choose smallest version in the range that fits the data
48 //! - User can specify mask pattern manually, otherwise library will automatically evaluate all 8 masks and select the optimal one
49 //! - User can specify absolute error correction level, or allow the library to boost it if it doesn't increase the version number
50 //! - User can create a list of data segments manually and add ECI segments
51 //!
52 //! More information about QR Code technology and this library's design can be found on the project home page.
53 //!
54 //! # Examples
55 //!
56 //! ```
57 //! extern crate qrcodegen;
58 //! use qrcodegen::Mask;
59 //! use qrcodegen::QrCode;
60 //! use qrcodegen::QrCodeEcc;
61 //! use qrcodegen::Version;
62 //! ```
63 //!
64 //! Text data:
65 //!
66 //! ```
67 //! let mut outbuffer  = vec![0u8; Version::MAX.buffer_len()];
68 //! let mut tempbuffer = vec![0u8; Version::MAX.buffer_len()];
69 //! let qr = QrCode::encode_text("Hello, world!", &mut tempbuffer, &mut outbuffer,
70 //!     QrCodeEcc::Medium, Version::MIN, Version:MAX, None, true).unwrap();
71 //! let svg = to_svg_string(&qr, 4);  // See qrcodegen-demo
72 //! ```
73 //!
74 //! Binary data:
75 //!
76 //! ```
77 //! let mut outbuffer   = vec![0u8; Version::MAX.buffer_len()];
78 //! let mut dataandtemp = vec![0u8; Version::MAX.buffer_len()];
79 //! dataandtemp[0] = 0xE3;
80 //! dataandtemp[1] = 0x81;
81 //! dataandtemp[2] = 0x82;
82 //! let qr = QrCode::encode_binary(&mut dataandtemp, 3, &mut outbuffer, QrCodeEcc::High,
83 //!     Version::new(2), Version::new(7), Some(Mask::new(4)), false).unwrap();
84 //! for y in 0 .. qr.size() {
85 //!     for x in 0 .. qr.size() {
86 //!         (... paint qr.get_module(x, y) ...)
87 //!     }
88 //! }
89 //! ```
90 
91 
92 #![no_std]
93 #![forbid(unsafe_code)]
94 use core::convert::TryFrom;
95 
96 
97 /*---- QrCode functionality ----*/
98 
99 /// A QR Code symbol, which is a type of two-dimension barcode.
100 ///
101 /// Invented by Denso Wave and described in the ISO/IEC 18004 standard.
102 ///
103 /// Instances of this struct represent an immutable square grid of dark and light cells.
104 /// The impl provides static factory functions to create a QR Code from text or binary data.
105 /// The struct and impl cover the QR Code Model 2 specification, supporting all versions
106 /// (sizes) from 1 to 40, all 4 error correction levels, and 4 character encoding modes.
107 ///
108 /// Ways to create a QR Code object:
109 ///
110 /// - High level: Take the payload data and call `QrCode::encode_text()` or `QrCode::encode_binary()`.
111 /// - Mid level: Custom-make the list of segments and call
112 ///   `QrCode::encode_segments_to_codewords()` and then `QrCode::encode_codewords()`.
113 /// - Low level: Custom-make the array of data codeword bytes (including segment
114 ///   headers and final padding, excluding error correction codewords), supply the
115 ///   appropriate version number, and call the `QrCode::encode_codewords()` constructor.
116 ///
117 /// (Note that all ways require supplying the desired error correction level and various byte buffers.)
118 pub struct QrCode<'a> {
119 
120 	// The width and height of this QR Code, measured in modules, between
121 	// 21 and 177 (inclusive). This is equal to version * 4 + 17.
122 	size: &'a mut u8,
123 
124 	// The modules of this QR Code (0 = light, 1 = dark), packed bitwise into bytes.
125 	// Immutable after constructor finishes. Accessed through get_module().
126 	modules: &'a mut [u8],
127 
128 }
129 
130 
131 impl<'a> QrCode<'a> {
132 
133 	/*---- Static factory functions (high level) ----*/
134 
135 	/// Encodes the given text string to a QR Code, returning a wrapped `QrCode` if successful.
136 	/// If the data is too long to fit in any version in the given range
137 	/// at the given ECC level, then `Err` is returned.
138 	///
139 	/// The smallest possible QR Code version within the given range is automatically
140 	/// chosen for the output. Iff boostecl is `true`, then the ECC level of the result
141 	/// may be higher than the ecl argument if it can be done without increasing the
142 	/// version. The mask number is either between 0 to 7 (inclusive) to force that
143 	/// mask, or `None` to automatically choose an appropriate mask (which may be slow).
144 	///
145 	/// About the slices, letting len = maxversion.buffer_len():
146 	/// - Before calling the function:
147 	///   - The slices tempbuffer and outbuffer each must have a length of at least len.
148 	///   - If a slice is longer than len, then the function will not
149 	///     read from or write to the suffix array[len .. array.len()].
150 	///   - The initial values of both slices can be arbitrary
151 	///     because the function always writes before reading.
152 	/// - After the function returns, both slices have no guarantee on what values are stored.
153 	///
154 	/// If successful, the resulting QR Code may use numeric,
155 	/// alphanumeric, or byte mode to encode the text.
156 	///
157 	/// In the most optimistic case, a QR Code at version 40 with low ECC
158 	/// can hold any UTF-8 string up to 2953 bytes, or any alphanumeric string
159 	/// up to 4296 characters, or any digit string up to 7089 characters.
160 	/// These numbers represent the hard upper limit of the QR Code standard.
161 	///
162 	/// Please consult the QR Code specification for information on
163 	/// data capacities per version, ECC level, and text encoding mode.
encode_text<'b>(text: &str, tempbuffer: &'b mut [u8], mut outbuffer: &'a mut [u8], ecl: QrCodeEcc, minversion: Version, maxversion: Version, mask: Option<Mask>, boostecl: bool) -> Result<QrCode<'a>,DataTooLong>164 	pub fn encode_text<'b>(text: &str, tempbuffer: &'b mut [u8], mut outbuffer: &'a mut [u8], ecl: QrCodeEcc,
165 			minversion: Version, maxversion: Version, mask: Option<Mask>, boostecl: bool) -> Result<QrCode<'a>,DataTooLong> {
166 
167 		let minlen: usize = outbuffer.len().min(tempbuffer.len());
168 		outbuffer = &mut outbuffer[ .. minlen];
169 
170 		let textlen: usize = text.len();  // In bytes
171 		if textlen == 0 {
172 			let (datacodewordslen, ecl, version) = QrCode::encode_segments_to_codewords(&[], outbuffer, ecl, minversion, maxversion, boostecl)?;
173 			return Ok(Self::encode_codewords(outbuffer, datacodewordslen, tempbuffer, ecl, version, mask));
174 		}
175 
176 		use QrSegmentMode::*;
177 		let buflen: usize = outbuffer.len();
178 		let seg: QrSegment = if QrSegment::is_numeric(text) && QrSegment::calc_buffer_size(Numeric, textlen).map_or(false, |x| x <= buflen) {
179 			QrSegment::make_numeric(text, tempbuffer)
180 		} else if QrSegment::is_alphanumeric(text) && QrSegment::calc_buffer_size(Alphanumeric, textlen).map_or(false, |x| x <= buflen) {
181 			QrSegment::make_alphanumeric(text, tempbuffer)
182 		} else if QrSegment::calc_buffer_size(Byte, textlen).map_or(false, |x| x <= buflen) {
183 			QrSegment::make_bytes(text.as_bytes())
184 		} else {
185 			return Err(DataTooLong::SegmentTooLong);
186 		};
187 		let (datacodewordslen, ecl, version) = QrCode::encode_segments_to_codewords(&[seg], outbuffer, ecl, minversion, maxversion, boostecl)?;
188 		Ok(Self::encode_codewords(outbuffer, datacodewordslen, tempbuffer, ecl, version, mask))
189 	}
190 
191 
192 	/// Encodes the given binary data to a QR Code, returning a wrapped `QrCode` if successful.
193 	/// If the data is too long to fit in any version in the given range
194 	/// at the given ECC level, then `Err` is returned.
195 	///
196 	/// The smallest possible QR Code version within the given range is automatically
197 	/// chosen for the output. Iff boostecl is `true`, then the ECC level of the result
198 	/// may be higher than the ecl argument if it can be done without increasing the
199 	/// version. The mask number is either between 0 to 7 (inclusive) to force that
200 	/// mask, or `None` to automatically choose an appropriate mask (which may be slow).
201 	///
202 	/// About the slices, letting len = maxversion.buffer_len():
203 	/// - Before calling the function:
204 	///   - The slices dataandtempbuffer and outbuffer each must have a length of at least len.
205 	///   - If a slice is longer than len, then the function will not
206 	///     read from or write to the suffix array[len .. array.len()].
207 	///   - The input slice range dataandtempbuffer[0 .. datalen] should normally be
208 	///     valid UTF-8 text, but is not required by the QR Code standard.
209 	///   - The initial values of dataandtempbuffer[datalen .. len] and outbuffer[0 .. len]
210 	///     can be arbitrary because the function always writes before reading.
211 	/// - After the function returns, both slices have no guarantee on what values are stored.
212 	///
213 	/// If successful, the resulting QR Code will use byte mode to encode the data.
214 	///
215 	/// In the most optimistic case, a QR Code at version 40 with low ECC can hold any byte
216 	/// sequence up to length 2953. This is the hard upper limit of the QR Code standard.
217 	///
218 	/// Please consult the QR Code specification for information on
219 	/// data capacities per version, ECC level, and text encoding mode.
encode_binary<'b>(dataandtempbuffer: &'b mut [u8], datalen: usize, mut outbuffer: &'a mut [u8], ecl: QrCodeEcc, minversion: Version, maxversion: Version, mask: Option<Mask>, boostecl: bool) -> Result<QrCode<'a>,DataTooLong>220 	pub fn encode_binary<'b>(dataandtempbuffer: &'b mut [u8], datalen: usize, mut outbuffer: &'a mut [u8], ecl: QrCodeEcc,
221 			minversion: Version, maxversion: Version, mask: Option<Mask>, boostecl: bool) -> Result<QrCode<'a>,DataTooLong> {
222 
223 		assert!(datalen <= dataandtempbuffer.len(), "Invalid data length");
224 		let minlen: usize = outbuffer.len().min(dataandtempbuffer.len());
225 		outbuffer = &mut outbuffer[ .. minlen];
226 
227 		if QrSegment::calc_buffer_size(QrSegmentMode::Byte, datalen).map_or(true, |x| x > outbuffer.len()) {
228 			return Err(DataTooLong::SegmentTooLong);
229 		}
230 		let seg: QrSegment = QrSegment::make_bytes(&dataandtempbuffer[ .. datalen]);
231 		let (datacodewordslen, ecl, version) = QrCode::encode_segments_to_codewords(&[seg], outbuffer, ecl, minversion, maxversion, boostecl)?;
232 		Ok(Self::encode_codewords(outbuffer, datacodewordslen, dataandtempbuffer, ecl, version, mask))
233 	}
234 
235 
236 	/*---- Static factory functions (mid level) ----*/
237 
238 	/// Returns an intermediate state representing the given segments
239 	/// with the given encoding parameters being encoded into codewords.
240 	///
241 	/// The smallest possible QR Code version within the given range is automatically
242 	/// chosen for the output. Iff boostecl is `true`, then the ECC level of the result
243 	/// may be higher than the ecl argument if it can be done without increasing the
244 	/// version. The mask number is either between 0 to 7 (inclusive) to force that
245 	/// mask, or `None` to automatically choose an appropriate mask (which may be slow).
246 	///
247 	/// This function exists to allow segments to use parts of a temporary buffer,
248 	/// then have the segments be encoded to an output buffer, then invalidate all the segments,
249 	/// and finally have the output buffer and temporary buffer be encoded to a QR Code.
encode_segments_to_codewords(segs: &[QrSegment], outbuffer: &'a mut [u8], mut ecl: QrCodeEcc, minversion: Version, maxversion: Version, boostecl: bool) -> Result<(usize,QrCodeEcc,Version),DataTooLong>250 	pub fn encode_segments_to_codewords(segs: &[QrSegment], outbuffer: &'a mut [u8],
251 			mut ecl: QrCodeEcc, minversion: Version, maxversion: Version, boostecl: bool)
252 			-> Result<(usize,QrCodeEcc,Version),DataTooLong> {
253 
254 		assert!(minversion <= maxversion, "Invalid value");
255 		assert!(outbuffer.len() >= QrCode::get_num_data_codewords(maxversion, ecl), "Invalid buffer length");
256 
257 		// Find the minimal version number to use
258 		let mut version: Version = minversion;
259 		let datausedbits: usize = loop {
260 			let datacapacitybits: usize = QrCode::get_num_data_codewords(version, ecl) * 8;  // Number of data bits available
261 			let dataused: Option<usize> = QrSegment::get_total_bits(segs, version);
262 			if dataused.map_or(false, |n| n <= datacapacitybits) {
263 				break dataused.unwrap();  // This version number is found to be suitable
264 			} else if version >= maxversion {  // All versions in the range could not fit the given data
265 				return Err(match dataused {
266 					None => DataTooLong::SegmentTooLong,
267 					Some(n) => DataTooLong::DataOverCapacity(n, datacapacitybits),
268 				});
269 			} else {
270 				version = Version::new(version.value() + 1);
271 			}
272 		};
273 
274 		// Increase the error correction level while the data still fits in the current version number
275 		for &newecl in &[QrCodeEcc::Medium, QrCodeEcc::Quartile, QrCodeEcc::High] {  // From low to high
276 			if boostecl && datausedbits <= QrCode::get_num_data_codewords(version, newecl) * 8 {
277 				ecl = newecl;
278 			}
279 		}
280 
281 		// Concatenate all segments to create the data bit string
282 		let datacapacitybits: usize = QrCode::get_num_data_codewords(version, ecl) * 8;
283 		let mut bb = BitBuffer::new(&mut outbuffer[ .. datacapacitybits/8]);
284 		for seg in segs {
285 			bb.append_bits(seg.mode.mode_bits(), 4);
286 			bb.append_bits(u32::try_from(seg.numchars).unwrap(), seg.mode.num_char_count_bits(version));
287 			for i in 0 .. seg.bitlength {
288 				let bit: u8 = (seg.data[i >> 3] >> (7 - (i & 7))) & 1;
289 				bb.append_bits(bit.into(), 1);
290 			}
291 		}
292 		debug_assert_eq!(bb.length, datausedbits);
293 
294 		// Add terminator and pad up to a byte if applicable
295 		let numzerobits: usize = core::cmp::min(4, datacapacitybits - bb.length);
296 		bb.append_bits(0, u8::try_from(numzerobits).unwrap());
297 		let numzerobits: usize = bb.length.wrapping_neg() & 7;
298 		bb.append_bits(0, u8::try_from(numzerobits).unwrap());
299 		debug_assert_eq!(bb.length % 8, 0);
300 
301 		// Pad with alternating bytes until data capacity is reached
302 		for &padbyte in [0xEC, 0x11].iter().cycle() {
303 			if bb.length >= datacapacitybits {
304 				break;
305 			}
306 			bb.append_bits(padbyte, 8);
307 		}
308 		Ok((bb.length / 8, ecl, version))
309 	}
310 
311 
312 	/*---- Constructor (low level) ----*/
313 
314 	/// Creates a new QR Code with the given version number,
315 	/// error correction level, data codeword bytes, and mask number.
316 	///
317 	/// This is a low-level API that most users should not use directly.
318 	/// A mid-level API is the `encode_segments_to_codewords()` function.
encode_codewords<'b>(mut datacodewordsandoutbuffer: &'a mut [u8], datacodewordslen: usize, mut tempbuffer: &'b mut [u8], ecl: QrCodeEcc, version: Version, mut msk: Option<Mask>) -> QrCode<'a>319 	pub fn encode_codewords<'b>(mut datacodewordsandoutbuffer: &'a mut [u8], datacodewordslen: usize, mut tempbuffer: &'b mut [u8],
320 			ecl: QrCodeEcc, version: Version, mut msk: Option<Mask>) -> QrCode<'a> {
321 
322 		datacodewordsandoutbuffer = &mut datacodewordsandoutbuffer[ .. version.buffer_len()];
323 		tempbuffer                = &mut tempbuffer               [ .. version.buffer_len()];
324 
325 		// Compute ECC
326 		let rawcodewords: usize = QrCode::get_num_raw_data_modules(version) / 8;
327 		assert!(datacodewordslen <= rawcodewords);
328 		let (data, temp) = datacodewordsandoutbuffer.split_at_mut(datacodewordslen);
329 		let allcodewords = Self::add_ecc_and_interleave(data, version, ecl, temp, tempbuffer);
330 
331 		// Draw modules
332 		let mut result: QrCode = QrCode::<'a>::function_modules_marked(datacodewordsandoutbuffer, version);
333 		result.draw_codewords(allcodewords);
334 		result.draw_light_function_modules();
335 		let funcmods: QrCode = QrCode::<'b>::function_modules_marked(tempbuffer, version);  // Just a grid, not a real QR Code
336 
337 		// Do masking
338 		if msk.is_none() {  // Automatically choose best mask
339 			let mut minpenalty = core::i32::MAX;
340 			for i in 0u8 .. 8 {
341 				let i = Mask::new(i);
342 				result.apply_mask(&funcmods, i);
343 				result.draw_format_bits(ecl, i);
344 				let penalty: i32 = result.get_penalty_score();
345 				if penalty < minpenalty {
346 					msk = Some(i);
347 					minpenalty = penalty;
348 				}
349 				result.apply_mask(&funcmods, i);  // Undoes the mask due to XOR
350 			}
351 		}
352 		let msk: Mask = msk.unwrap();
353 		result.apply_mask(&funcmods, msk);  // Apply the final choice of mask
354 		result.draw_format_bits(ecl, msk);  // Overwrite old format bits
355 		result
356 	}
357 
358 
359 	/*---- Public methods ----*/
360 
361 	/// Returns this QR Code's version, in the range [1, 40].
version(&self) -> Version362 	pub fn version(&self) -> Version {
363 		Version::new((*self.size - 17) / 4)
364 	}
365 
366 
367 	/// Returns this QR Code's size, in the range [21, 177].
size(&self) -> i32368 	pub fn size(&self) -> i32 {
369 		i32::from(*self.size)
370 	}
371 
372 
373 	/// Returns this QR Code's error correction level.
error_correction_level(&self) -> QrCodeEcc374 	pub fn error_correction_level(&self) -> QrCodeEcc {
375 		let index =
376 			usize::from(self.get_module_bounded(0, 8)) << 1 |
377 			usize::from(self.get_module_bounded(1, 8)) << 0;
378 		use QrCodeEcc::*;
379 		[Medium, Low, High, Quartile][index]
380 	}
381 
382 
383 	/// Returns this QR Code's mask, in the range [0, 7].
mask(&self) -> Mask384 	pub fn mask(&self) -> Mask {
385 		Mask::new(
386 			u8::from(self.get_module_bounded(2, 8)) << 2 |
387 			u8::from(self.get_module_bounded(3, 8)) << 1 |
388 			u8::from(self.get_module_bounded(4, 8)) << 0)
389 	}
390 
391 
392 	/// Returns the color of the module (pixel) at the given coordinates,
393 	/// which is `false` for light or `true` for dark.
394 	///
395 	/// The top left corner has the coordinates (x=0, y=0). If the given
396 	/// coordinates are out of bounds, then `false` (light) is returned.
get_module(&self, x: i32, y: i32) -> bool397 	pub fn get_module(&self, x: i32, y: i32) -> bool {
398 		let range = 0 .. self.size();
399 		range.contains(&x) && range.contains(&y) && self.get_module_bounded(x as u8, y as u8)
400 	}
401 
402 
403 	// Returns the color of the module at the given coordinates, which must be in bounds.
get_module_bounded(&self, x: u8, y: u8) -> bool404 	fn get_module_bounded(&self, x: u8, y: u8) -> bool {
405 		let range = 0 .. *self.size;
406 		assert!(range.contains(&x) && range.contains(&y));
407 		let index = usize::from(y) * usize::from(*self.size) + usize::from(x);
408 		let byteindex: usize = index >> 3;
409 		let bitindex: usize = index & 7;
410 		get_bit(self.modules[byteindex].into(), bitindex as u8)
411 	}
412 
413 
414 	// Sets the color of the module at the given coordinates, doing nothing if out of bounds.
set_module_unbounded(&mut self, x: i32, y: i32, isdark: bool)415 	fn set_module_unbounded(&mut self, x: i32, y: i32, isdark: bool) {
416 		let range = 0 .. self.size();
417 		if range.contains(&x) && range.contains(&y) {
418 			self.set_module_bounded(x as u8, y as u8, isdark);
419 		}
420 	}
421 
422 
423 	// Sets the color of the module at the given coordinates, which must be in bounds.
set_module_bounded(&mut self, x: u8, y: u8, isdark: bool)424 	fn set_module_bounded(&mut self, x: u8, y: u8, isdark: bool) {
425 		let range = 0 .. *self.size;
426 		assert!(range.contains(&x) && range.contains(&y));
427 		let index = usize::from(y) * usize::from(*self.size) + usize::from(x);
428 		let byteindex: usize = index >> 3;
429 		let bitindex: usize = index & 7;
430 		if isdark {
431 			self.modules[byteindex] |= 1u8 << bitindex;
432 		} else {
433 			self.modules[byteindex] &= !(1u8 << bitindex);
434 		}
435 	}
436 
437 
438 	/*---- Error correction code generation ----*/
439 
440 	// Appends error correction bytes to each block of the given data array, then interleaves
441 	// bytes from the blocks, stores them in the output array, and returns a slice of resultbuf.
442 	// temp is used as a temporary work area and will be clobbered by this function.
add_ecc_and_interleave<'b>(data: &[u8], ver: Version, ecl: QrCodeEcc, temp: &mut [u8], resultbuf: &'b mut [u8]) -> &'b [u8]443 	fn add_ecc_and_interleave<'b>(data: &[u8], ver: Version, ecl: QrCodeEcc, temp: &mut [u8], resultbuf: &'b mut [u8]) -> &'b [u8] {
444 		assert_eq!(data.len(), QrCode::get_num_data_codewords(ver, ecl));
445 
446 		// Calculate parameter numbers
447 		let numblocks: usize = QrCode::table_get(&NUM_ERROR_CORRECTION_BLOCKS, ver, ecl);
448 		let blockecclen: usize = QrCode::table_get(&ECC_CODEWORDS_PER_BLOCK  , ver, ecl);
449 		let rawcodewords: usize = QrCode::get_num_raw_data_modules(ver) / 8;
450 		let numshortblocks: usize = numblocks - rawcodewords % numblocks;
451 		let shortblockdatalen: usize = rawcodewords / numblocks - blockecclen;
452 		let result = &mut resultbuf[ .. rawcodewords];
453 
454 		// Split data into blocks, calculate ECC, and interleave
455 		// (not concatenate) the bytes into a single sequence
456 		let rs = ReedSolomonGenerator::new(blockecclen);
457 		let mut dat: &[u8] = data;
458 		let ecc: &mut [u8] = &mut temp[ .. blockecclen];  // Temporary storage
459 		for i in 0 .. numblocks {
460 			let datlen: usize = shortblockdatalen + usize::from(i >= numshortblocks);
461 			rs.compute_remainder(&dat[ .. datlen], ecc);
462 			let mut k: usize = i;
463 			for j in 0 .. datlen {  // Copy data
464 				if j == shortblockdatalen {
465 					k -= numshortblocks;
466 				}
467 				result[k] = dat[j];
468 				k += numblocks;
469 			}
470 			let mut k: usize = data.len() + i;
471 			for j in 0 .. blockecclen {  // Copy ECC
472 				result[k] = ecc[j];
473 				k += numblocks;
474 			}
475 			dat = &dat[datlen .. ];
476 		}
477 		debug_assert_eq!(dat.len(), 0);
478 		result
479 	}
480 
481 
482 	/*---- Drawing function modules ----*/
483 
484 	// Creates a QR Code grid with light modules for the given
485 	// version's size, then marks every function module as dark.
function_modules_marked(outbuffer: &'a mut [u8], ver: Version) -> Self486 	fn function_modules_marked(outbuffer: &'a mut [u8], ver: Version) -> Self {
487 		assert_eq!(outbuffer.len(), ver.buffer_len());
488 		let parts: (&mut u8, &mut [u8]) = outbuffer.split_first_mut().unwrap();
489 		let mut result = Self {
490 			size: parts.0,
491 			modules: parts.1,
492 		};
493 		let size: u8 = ver.value() * 4 + 17;
494 		*result.size = size;
495 		result.modules.fill(0);
496 
497 		// Fill horizontal and vertical timing patterns
498 		result.fill_rectangle(6, 0, 1, size);
499 		result.fill_rectangle(0, 6, size, 1);
500 
501 		// Fill 3 finder patterns (all corners except bottom right) and format bits
502 		result.fill_rectangle(0, 0, 9, 9);
503 		result.fill_rectangle(size - 8, 0, 8, 9);
504 		result.fill_rectangle(0, size - 8, 9, 8);
505 
506 		// Fill numerous alignment patterns
507 		let mut alignpatposbuf = [0u8; 7];
508 		let alignpatpos: &[u8] = result.get_alignment_pattern_positions(&mut alignpatposbuf);
509 		for (i, pos0) in alignpatpos.iter().enumerate() {
510 			for (j, pos1) in alignpatpos.iter().enumerate() {
511 				// Don't draw on the three finder corners
512 				if !((i == 0 && j == 0) || (i == 0 && j == alignpatpos.len() - 1) || (i == alignpatpos.len() - 1 && j == 0)) {
513 					result.fill_rectangle(pos0 - 2, pos1 - 2, 5, 5);
514 				}
515 			}
516 		}
517 
518 		// Fill version blocks
519 		if ver.value() >= 7 {
520 			result.fill_rectangle(size - 11, 0, 3, 6);
521 			result.fill_rectangle(0, size - 11, 6, 3);
522 		}
523 
524 		result
525 	}
526 
527 
528 	// Draws light function modules and possibly some dark modules onto this QR Code, without changing
529 	// non-function modules. This does not draw the format bits. This requires all function modules to be previously
530 	// marked dark (namely by function_modules_marked()), because this may skip redrawing dark function modules.
draw_light_function_modules(&mut self)531 	fn draw_light_function_modules(&mut self) {
532 		// Draw horizontal and vertical timing patterns
533 		let size: u8 = *self.size;
534 		for i in (7 .. size-7).step_by(2) {
535 			self.set_module_bounded(6, i, false);
536 			self.set_module_bounded(i, 6, false);
537 		}
538 
539 		// Draw 3 finder patterns (all corners except bottom right; overwrites some timing modules)
540 		for dy in -4i32 ..= 4 {
541 			for dx in -4i32 ..= 4 {
542 				let dist: i32 = dx.abs().max(dy.abs());
543 				if dist == 2 || dist == 4 {
544 					self.set_module_unbounded(3 + dx, 3 + dy, false);
545 					self.set_module_unbounded(i32::from(size) - 4 + dx, 3 + dy, false);
546 					self.set_module_unbounded(3 + dx, i32::from(size) - 4 + dy, false);
547 				}
548 			}
549 		}
550 
551 		// Draw numerous alignment patterns
552 		let mut alignpatposbuf = [0u8; 7];
553 		let alignpatpos: &[u8] = self.get_alignment_pattern_positions(&mut alignpatposbuf);
554 		for (i, &pos0) in alignpatpos.iter().enumerate() {
555 			for (j, &pos1) in alignpatpos.iter().enumerate() {
556 				if (i == 0 && j == 0) || (i == 0 && j == alignpatpos.len() - 1) || (i == alignpatpos.len() - 1 && j == 0) {
557 					continue;  // Don't draw on the three finder corners
558 				}
559 				for dy in -1 ..= 1 {
560 					for dx in -1 ..= 1 {
561 						self.set_module_bounded((i32::from(pos0) + dx) as u8, (i32::from(pos1) + dy) as u8, dx == 0 && dy == 0);
562 					}
563 				}
564 			}
565 		}
566 
567 		// Draw version blocks
568 		let ver = u32::from(self.version().value());  // uint6, in the range [7, 40]
569 		if ver >= 7 {
570 			// Calculate error correction code and pack bits
571 			let bits: u32 = {
572 				let mut rem: u32 = ver;
573 				for _ in 0 .. 12 {
574 					rem = (rem << 1) ^ ((rem >> 11) * 0x1F25);
575 				}
576 				ver << 12 | rem  // uint18
577 			};
578 			debug_assert_eq!(bits >> 18, 0);
579 
580 			// Draw two copies
581 			for i in 0u8 .. 18 {
582 				let bit: bool = get_bit(bits, i);
583 				let a: u8 = size - 11 + i % 3;
584 				let b: u8 = i / 3;
585 				self.set_module_bounded(a, b, bit);
586 				self.set_module_bounded(b, a, bit);
587 			}
588 		}
589 	}
590 
591 
592 	// Draws two copies of the format bits (with its own error correction code) based
593 	// on the given mask and error correction level. This always draws all modules of
594 	// the format bits, unlike draw_light_function_modules() which might skip dark modules.
draw_format_bits(&mut self, ecl: QrCodeEcc, mask: Mask)595 	fn draw_format_bits(&mut self, ecl: QrCodeEcc, mask: Mask) {
596 		// Calculate error correction code and pack bits
597 		let bits: u32 = {
598 			// errcorrlvl is uint2, mask is uint3
599 			let data = u32::from(ecl.format_bits() << 3 | mask.value());
600 			let mut rem: u32 = data;
601 			for _ in 0 .. 10 {
602 				rem = (rem << 1) ^ ((rem >> 9) * 0x537);
603 			}
604 			(data << 10 | rem) ^ 0x5412  // uint15
605 		};
606 		debug_assert_eq!(bits >> 15, 0);
607 
608 		// Draw first copy
609 		for i in 0 .. 6 {
610 			self.set_module_bounded(8, i, get_bit(bits, i));
611 		}
612 		self.set_module_bounded(8, 7, get_bit(bits, 6));
613 		self.set_module_bounded(8, 8, get_bit(bits, 7));
614 		self.set_module_bounded(7, 8, get_bit(bits, 8));
615 		for i in 9 .. 15 {
616 			self.set_module_bounded(14 - i, 8, get_bit(bits, i));
617 		}
618 
619 		// Draw second copy
620 		let size: u8 = *self.size;
621 		for i in 0 .. 8 {
622 			self.set_module_bounded(size - 1 - i, 8, get_bit(bits, i));
623 		}
624 		for i in 8 .. 15 {
625 			self.set_module_bounded(8, size - 15 + i, get_bit(bits, i));
626 		}
627 		self.set_module_bounded(8, size - 8, true);  // Always dark
628 	}
629 
630 
631 	// Sets every module in the range [left : left + width] * [top : top + height] to dark.
fill_rectangle(&mut self, left: u8, top: u8, width: u8, height: u8)632 	fn fill_rectangle(&mut self, left: u8, top: u8, width: u8, height: u8) {
633 		for dy in 0 .. height {
634 			for dx in 0 .. width {
635 				self.set_module_bounded(left + dx, top + dy, true);
636 			}
637 		}
638 	}
639 
640 
641 	/*---- Drawing data modules and masking ----*/
642 
643 	// Draws the raw codewords (including data and ECC) onto this QR Code. This requires the initial state of
644 	// the QR Code to be dark at function modules and light at codeword modules (including unused remainder bits).
draw_codewords(&mut self, data: &[u8])645 	fn draw_codewords(&mut self, data: &[u8]) {
646 		assert_eq!(data.len(), QrCode::get_num_raw_data_modules(self.version()) / 8, "Illegal argument");
647 
648 		let size: i32 = self.size();
649 		let mut i: usize = 0;  // Bit index into the data
650 		// Do the funny zigzag scan
651 		let mut right: i32 = size - 1;
652 		while right >= 1 {  // Index of right column in each column pair
653 			if right == 6 {
654 				right = 5;
655 			}
656 			for vert in 0 .. size {  // Vertical counter
657 				for j in 0 .. 2 {
658 					let x = (right - j) as u8;  // Actual x coordinate
659 					let upward: bool = (right + 1) & 2 == 0;
660 					let y = (if upward { size - 1 - vert } else { vert }) as u8;  // Actual y coordinate
661 					if !self.get_module_bounded(x, y) && i < data.len() * 8 {
662 						self.set_module_bounded(x, y, get_bit(data[i >> 3].into(), 7 - ((i as u8) & 7)));
663 						i += 1;
664 					}
665 					// If this QR Code has any remainder bits (0 to 7), they were assigned as
666 					// 0/false/light by the constructor and are left unchanged by this method
667 				}
668 			}
669 			right -= 2;
670 		}
671 		debug_assert_eq!(i, data.len() * 8);
672 	}
673 
674 
675 	// XORs the codeword modules in this QR Code with the given mask pattern
676 	// and given pattern of function modules. The codeword bits must be drawn
677 	// before masking. Due to the arithmetic of XOR, calling apply_mask() with
678 	// the same mask value a second time will undo the mask. A final well-formed
679 	// QR Code needs exactly one (not zero, two, etc.) mask applied.
apply_mask(&mut self, functionmodules: &QrCode, mask: Mask)680 	fn apply_mask(&mut self, functionmodules: &QrCode, mask: Mask) {
681 		for y in 0 .. *self.size {
682 			for x in 0 .. *self.size {
683 				if functionmodules.get_module_bounded(x, y) {
684 					continue;
685 				}
686 				let invert: bool = {
687 					let x = i32::from(x);
688 					let y = i32::from(y);
689 					match mask.value() {
690 						0 => (x + y) % 2 == 0,
691 						1 => y % 2 == 0,
692 						2 => x % 3 == 0,
693 						3 => (x + y) % 3 == 0,
694 						4 => (x / 3 + y / 2) % 2 == 0,
695 						5 => x * y % 2 + x * y % 3 == 0,
696 						6 => (x * y % 2 + x * y % 3) % 2 == 0,
697 						7 => ((x + y) % 2 + x * y % 3) % 2 == 0,
698 						_ => unreachable!(),
699 					}
700 				};
701 				self.set_module_bounded(x, y,
702 					self.get_module_bounded(x, y) ^ invert);
703 			}
704 		}
705 	}
706 
707 
708 	// Calculates and returns the penalty score based on state of this QR Code's current modules.
709 	// This is used by the automatic mask choice algorithm to find the mask pattern that yields the lowest score.
get_penalty_score(&self) -> i32710 	fn get_penalty_score(&self) -> i32 {
711 		let mut result: i32 = 0;
712 		let size: u8 = *self.size;
713 
714 		// Adjacent modules in row having same color, and finder-like patterns
715 		for y in 0 .. size {
716 			let mut runcolor = false;
717 			let mut runx: i32 = 0;
718 			let mut runhistory = FinderPenalty::new(size);
719 			for x in 0 .. size {
720 				if self.get_module_bounded(x, y) == runcolor {
721 					runx += 1;
722 					if runx == 5 {
723 						result += PENALTY_N1;
724 					} else if runx > 5 {
725 						result += 1;
726 					}
727 				} else {
728 					runhistory.add_history(runx);
729 					if !runcolor {
730 						result += runhistory.count_patterns() * PENALTY_N3;
731 					}
732 					runcolor = self.get_module_bounded(x, y);
733 					runx = 1;
734 				}
735 			}
736 			result += runhistory.terminate_and_count(runcolor, runx) * PENALTY_N3;
737 		}
738 		// Adjacent modules in column having same color, and finder-like patterns
739 		for x in 0 .. size {
740 			let mut runcolor = false;
741 			let mut runy: i32 = 0;
742 			let mut runhistory = FinderPenalty::new(size);
743 			for y in 0 .. size {
744 				if self.get_module_bounded(x, y) == runcolor {
745 					runy += 1;
746 					if runy == 5 {
747 						result += PENALTY_N1;
748 					} else if runy > 5 {
749 						result += 1;
750 					}
751 				} else {
752 					runhistory.add_history(runy);
753 					if !runcolor {
754 						result += runhistory.count_patterns() * PENALTY_N3;
755 					}
756 					runcolor = self.get_module_bounded(x, y);
757 					runy = 1;
758 				}
759 			}
760 			result += runhistory.terminate_and_count(runcolor, runy) * PENALTY_N3;
761 		}
762 
763 		// 2*2 blocks of modules having same color
764 		for y in 0 .. size-1 {
765 			for x in 0 .. size-1 {
766 				let color: bool = self.get_module_bounded(x, y);
767 				if color == self.get_module_bounded(x + 1, y) &&
768 				   color == self.get_module_bounded(x, y + 1) &&
769 				   color == self.get_module_bounded(x + 1, y + 1) {
770 					result += PENALTY_N2;
771 				}
772 			}
773 		}
774 
775 		// Balance of dark and light modules
776 		let dark = self.modules.iter().map(|x| x.count_ones()).sum::<u32>() as i32;
777 		let total = i32::from(size) * i32::from(size);  // Note that size is odd, so dark/total != 1/2
778 		// Compute the smallest integer k >= 0 such that (45-5k)% <= dark/total <= (55+5k)%
779 		let k: i32 = ((dark * 20 - total * 10).abs() + total - 1) / total - 1;
780 		debug_assert!(0 <= k && k <= 9);
781 		result += k * PENALTY_N4;
782 		debug_assert!(0 <= result && result <= 2568888);  // Non-tight upper bound based on default values of PENALTY_N1, ..., N4
783 		result
784 	}
785 
786 
787 	/*---- Private helper functions ----*/
788 
789 	// Calculates and stores an ascending list of positions of alignment patterns
790 	// for this version number, returning a slice of resultbuf.
791 	// Each position is in the range [0,177), and are used on both the x and y axes.
792 	// This could be implemented as lookup table of 40 variable-length lists of unsigned bytes.
get_alignment_pattern_positions<'b>(&self, resultbuf: &'b mut [u8; 7]) -> &'b [u8]793 	fn get_alignment_pattern_positions<'b>(&self, resultbuf: &'b mut [u8; 7]) -> &'b [u8] {
794 		let ver: u8 = self.version().value();
795 		if ver == 1 {
796 			&resultbuf[ .. 0]
797 		} else {
798 			let numalign: u8 = ver / 7 + 2;
799 			let step: u8 = if ver == 32 { 26 } else
800 				{(ver * 4 + numalign * 2 + 1) / (numalign * 2 - 2) * 2};
801 			let result = &mut resultbuf[ .. usize::from(numalign)];
802 			for i in 0 .. numalign-1 {
803 				result[usize::from(i)] = *self.size - 7 - i * step;
804 			}
805 			*result.last_mut().unwrap() = 6;
806 			result.reverse();
807 			result
808 		}
809 	}
810 
811 
812 	// Returns the number of data bits that can be stored in a QR Code of the given version number, after
813 	// all function modules are excluded. This includes remainder bits, so it might not be a multiple of 8.
814 	// The result is in the range [208, 29648]. This could be implemented as a 40-entry lookup table.
get_num_raw_data_modules(ver: Version) -> usize815 	fn get_num_raw_data_modules(ver: Version) -> usize {
816 		let ver = usize::from(ver.value());
817 		let mut result: usize = (16 * ver + 128) * ver + 64;
818 		if ver >= 2 {
819 			let numalign: usize = ver / 7 + 2;
820 			result -= (25 * numalign - 10) * numalign - 55;
821 			if ver >= 7 {
822 				result -= 36;
823 			}
824 		}
825 		debug_assert!((208 ..= 29648).contains(&result));
826 		result
827 	}
828 
829 
830 	// Returns the number of 8-bit data (i.e. not error correction) codewords contained in any
831 	// QR Code of the given version number and error correction level, with remainder bits discarded.
832 	// This stateless pure function could be implemented as a (40*4)-cell lookup table.
get_num_data_codewords(ver: Version, ecl: QrCodeEcc) -> usize833 	fn get_num_data_codewords(ver: Version, ecl: QrCodeEcc) -> usize {
834 		QrCode::get_num_raw_data_modules(ver) / 8
835 			- QrCode::table_get(&ECC_CODEWORDS_PER_BLOCK    , ver, ecl)
836 			* QrCode::table_get(&NUM_ERROR_CORRECTION_BLOCKS, ver, ecl)
837 	}
838 
839 
840 	// Returns an entry from the given table based on the given values.
table_get(table: &'static [[i8; 41]; 4], ver: Version, ecl: QrCodeEcc) -> usize841 	fn table_get(table: &'static [[i8; 41]; 4], ver: Version, ecl: QrCodeEcc) -> usize {
842 		table[ecl.ordinal()][usize::from(ver.value())] as usize
843 	}
844 
845 }
846 
847 
848 impl PartialEq for QrCode<'_> {
eq(&self, other: &QrCode<'_>) -> bool849 	fn eq(&self, other: &QrCode<'_>) -> bool{
850 		*self.size    == *other.size    &&
851 		*self.modules == *other.modules
852 	}
853 }
854 
855 impl Eq for QrCode<'_> {}
856 
857 
858 /*---- Helper struct for add_ecc_and_interleave() ----*/
859 
860 struct ReedSolomonGenerator {
861 
862 	// Polynomial coefficients are stored from highest to lowest power, excluding the leading term which is always 1.
863 	// For example the polynomial x^3 + 255x^2 + 8x + 93 is stored as the uint8 array [255, 8, 93].
864 	divisor: [u8; 30],
865 
866 	// The degree of the divisor polynomial, in the range [1, 30].
867 	degree: usize,
868 
869 }
870 
871 
872 impl ReedSolomonGenerator {
873 
874 	// Creates a Reed-Solomon ECC generator polynomial for the given degree. This could be
875 	// implemented as a lookup table over all possible parameter values, instead of as an algorithm.
new(degree: usize) -> Self876 	fn new(degree: usize) -> Self {
877 		let mut result = Self {
878 			divisor: [0u8; 30],
879 			degree: degree,
880 		};
881 		assert!((1 ..= result.divisor.len()).contains(&degree), "Degree out of range");
882 		let divisor: &mut [u8] = &mut result.divisor[ .. degree];
883 		divisor[degree - 1] = 1;  // Start off with the monomial x^0
884 
885 		// Compute the product polynomial (x - r^0) * (x - r^1) * (x - r^2) * ... * (x - r^{degree-1}),
886 		// and drop the highest monomial term which is always 1x^degree.
887 		// Note that r = 0x02, which is a generator element of this field GF(2^8/0x11D).
888 		let mut root: u8 = 1;
889 		for _ in 0 .. degree {  // Unused variable i
890 			// Multiply the current product by (x - r^i)
891 			for j in 0 .. degree {
892 				divisor[j] = Self::multiply(divisor[j], root);
893 				if j + 1 < divisor.len() {
894 					divisor[j] ^= divisor[j + 1];
895 				}
896 			}
897 			root = Self::multiply(root, 0x02);
898 		}
899 		result
900 	}
901 
902 
903 	// Returns the Reed-Solomon error correction codeword for the given data polynomial and this divisor polynomial.
compute_remainder(&self, data: &[u8], result: &mut [u8])904 	fn compute_remainder(&self, data: &[u8], result: &mut [u8]) {
905 		assert_eq!(result.len(), self.degree);
906 		result.fill(0);
907 		for b in data {  // Polynomial division
908 			let factor: u8 = b ^ result[0];
909 			result.copy_within(1 .. , 0);
910 			result[result.len() - 1] = 0;
911 			for (x, &y) in result.iter_mut().zip(self.divisor.iter()) {
912 				*x ^= Self::multiply(y, factor);
913 			}
914 		}
915 	}
916 
917 
918 	// Returns the product of the two given field elements modulo GF(2^8/0x11D).
919 	// All inputs are valid. This could be implemented as a 256*256 lookup table.
multiply(x: u8, y: u8) -> u8920 	fn multiply(x: u8, y: u8) -> u8 {
921 		// Russian peasant multiplication
922 		let mut z: u8 = 0;
923 		for i in (0 .. 8).rev() {
924 			z = (z << 1) ^ ((z >> 7) * 0x1D);
925 			z ^= ((y >> i) & 1) * x;
926 		}
927 		z
928 	}
929 
930 }
931 
932 
933 /*---- Helper struct for get_penalty_score() ----*/
934 
935 struct FinderPenalty {
936 	qr_size: i32,
937 	run_history: [i32; 7],
938 }
939 
940 
941 impl FinderPenalty {
942 
new(size: u8) -> Self943 	pub fn new(size: u8) -> Self {
944 		Self {
945 			qr_size: i32::from(size),
946 			run_history: [0; 7],
947 		}
948 	}
949 
950 
951 	// Pushes the given value to the front and drops the last value.
add_history(&mut self, mut currentrunlength: i32)952 	pub fn add_history(&mut self, mut currentrunlength: i32) {
953 		if self.run_history[0] == 0 {
954 			currentrunlength += self.qr_size;  // Add light border to initial run
955 		}
956 		let len: usize = self.run_history.len();
957 		self.run_history.copy_within(0 .. len-1, 1);
958 		self.run_history[0] = currentrunlength;
959 	}
960 
961 
962 	// Can only be called immediately after a light run is added, and returns either 0, 1, or 2.
count_patterns(&self) -> i32963 	pub fn count_patterns(&self) -> i32 {
964 		let rh = &self.run_history;
965 		let n = rh[1];
966 		debug_assert!(n <= self.qr_size * 3);
967 		let core = n > 0 && rh[2] == n && rh[3] == n * 3 && rh[4] == n && rh[5] == n;
968 		( i32::from(core && rh[0] >= n * 4 && rh[6] >= n)
969 		+ i32::from(core && rh[6] >= n * 4 && rh[0] >= n))
970 	}
971 
972 
973 	// Must be called at the end of a line (row or column) of modules.
terminate_and_count(mut self, currentruncolor: bool, mut currentrunlength: i32) -> i32974 	pub fn terminate_and_count(mut self, currentruncolor: bool, mut currentrunlength: i32) -> i32 {
975 		if currentruncolor {  // Terminate dark run
976 			self.add_history(currentrunlength);
977 			currentrunlength = 0;
978 		}
979 		currentrunlength += self.qr_size;  // Add light border to final run
980 		self.add_history(currentrunlength);
981 		self.count_patterns()
982 	}
983 
984 }
985 
986 
987 /*---- Constants and tables ----*/
988 
989 // For use in get_penalty_score(), when evaluating which mask is best.
990 const PENALTY_N1: i32 =  3;
991 const PENALTY_N2: i32 =  3;
992 const PENALTY_N3: i32 = 40;
993 const PENALTY_N4: i32 = 10;
994 
995 
996 static ECC_CODEWORDS_PER_BLOCK: [[i8; 41]; 4] = [
997 	// Version: (note that index 0 is for padding, and is set to an illegal value)
998 	//0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40    Error correction level
999 	[-1,  7, 10, 15, 20, 26, 18, 20, 24, 30, 18, 20, 24, 26, 30, 22, 24, 28, 30, 28, 28, 28, 28, 30, 30, 26, 28, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30],  // Low
1000 	[-1, 10, 16, 26, 18, 24, 16, 18, 22, 22, 26, 30, 22, 22, 24, 24, 28, 28, 26, 26, 26, 26, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28],  // Medium
1001 	[-1, 13, 22, 18, 26, 18, 24, 18, 22, 20, 24, 28, 26, 24, 20, 30, 24, 28, 28, 26, 30, 28, 30, 30, 30, 30, 28, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30],  // Quartile
1002 	[-1, 17, 28, 22, 16, 22, 28, 26, 26, 24, 28, 24, 28, 22, 24, 24, 30, 28, 28, 26, 28, 30, 24, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30],  // High
1003 ];
1004 
1005 static NUM_ERROR_CORRECTION_BLOCKS: [[i8; 41]; 4] = [
1006 	// Version: (note that index 0 is for padding, and is set to an illegal value)
1007 	//0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40    Error correction level
1008 	[-1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 4,  4,  4,  4,  4,  6,  6,  6,  6,  7,  8,  8,  9,  9, 10, 12, 12, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 24, 25],  // Low
1009 	[-1, 1, 1, 1, 2, 2, 4, 4, 4, 5, 5,  5,  8,  9,  9, 10, 10, 11, 13, 14, 16, 17, 17, 18, 20, 21, 23, 25, 26, 28, 29, 31, 33, 35, 37, 38, 40, 43, 45, 47, 49],  // Medium
1010 	[-1, 1, 1, 2, 2, 4, 4, 6, 6, 8, 8,  8, 10, 12, 16, 12, 17, 16, 18, 21, 20, 23, 23, 25, 27, 29, 34, 34, 35, 38, 40, 43, 45, 48, 51, 53, 56, 59, 62, 65, 68],  // Quartile
1011 	[-1, 1, 1, 2, 4, 4, 4, 5, 6, 8, 8, 11, 11, 16, 16, 18, 16, 19, 21, 25, 25, 25, 34, 30, 32, 35, 37, 40, 42, 45, 48, 51, 54, 57, 60, 63, 66, 70, 74, 77, 81],  // High
1012 ];
1013 
1014 
1015 
1016 /*---- QrCodeEcc functionality ----*/
1017 
1018 /// The error correction level in a QR Code symbol.
1019 #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug)]
1020 pub enum QrCodeEcc {
1021 	/// The QR Code can tolerate about  7% erroneous codewords.
1022 	Low     ,
1023 	/// The QR Code can tolerate about 15% erroneous codewords.
1024 	Medium  ,
1025 	/// The QR Code can tolerate about 25% erroneous codewords.
1026 	Quartile,
1027 	/// The QR Code can tolerate about 30% erroneous codewords.
1028 	High    ,
1029 }
1030 
1031 
1032 impl QrCodeEcc {
1033 
1034 	// Returns an unsigned 2-bit integer (in the range 0 to 3).
ordinal(self) -> usize1035 	fn ordinal(self) -> usize {
1036 		use QrCodeEcc::*;
1037 		match self {
1038 			Low      => 0,
1039 			Medium   => 1,
1040 			Quartile => 2,
1041 			High     => 3,
1042 		}
1043 	}
1044 
1045 
1046 	// Returns an unsigned 2-bit integer (in the range 0 to 3).
format_bits(self) -> u81047 	fn format_bits(self) -> u8 {
1048 		use QrCodeEcc::*;
1049 		match self {
1050 			Low      => 1,
1051 			Medium   => 0,
1052 			Quartile => 3,
1053 			High     => 2,
1054 		}
1055 	}
1056 
1057 }
1058 
1059 
1060 
1061 /*---- QrSegment functionality ----*/
1062 
1063 /// A segment of character/binary/control data in a QR Code symbol.
1064 ///
1065 /// Instances of this struct are immutable.
1066 ///
1067 /// The mid-level way to create a segment is to take the payload data
1068 /// and call a static factory function such as `QrSegment::make_numeric()`.
1069 /// The low-level way to create a segment is to custom-make the bit buffer
1070 /// and call the `QrSegment::new()` constructor with appropriate values.
1071 ///
1072 /// This segment struct imposes no length restrictions, but QR Codes have restrictions.
1073 /// Even in the most favorable conditions, a QR Code can only hold 7089 characters of data.
1074 /// Any segment longer than this is meaningless for the purpose of generating QR Codes.
1075 pub struct QrSegment<'a> {
1076 
1077 	// The mode indicator of this segment. Accessed through mode().
1078 	mode: QrSegmentMode,
1079 
1080 	// The length of this segment's unencoded data. Measured in characters for
1081 	// numeric/alphanumeric/kanji mode, bytes for byte mode, and 0 for ECI mode.
1082 	// Not the same as the data's bit length. Accessed through num_chars().
1083 	numchars: usize,
1084 
1085 	// The data bits of this segment, packed in bitwise big endian.
1086 	data: &'a [u8],
1087 
1088 	// The number of valid data bits used in the buffer. Requires bitlength <= data.len() * 8.
1089 	// The character count (numchars) must agree with the mode and the bit buffer length.
1090 	bitlength: usize,
1091 
1092 }
1093 
1094 
1095 impl<'a> QrSegment<'a> {
1096 
1097 	/*---- Static factory functions (mid level) ----*/
1098 
1099 	/// Returns a segment representing the given binary data encoded in byte mode.
1100 	///
1101 	/// All input byte slices are acceptable.
1102 	///
1103 	/// Any text string can be converted to UTF-8 bytes and encoded as a byte mode segment.
make_bytes(data: &'a [u8]) -> Self1104 	pub fn make_bytes(data: &'a [u8]) -> Self {
1105 		QrSegment::new(QrSegmentMode::Byte, data.len(), data, data.len().checked_mul(8).unwrap())
1106 	}
1107 
1108 
1109 	/// Returns a segment representing the given string of decimal digits encoded in numeric mode.
1110 	///
1111 	/// Panics if the string contains non-digit characters.
make_numeric(text: &str, buf: &'a mut [u8]) -> Self1112 	pub fn make_numeric(text: &str, buf: &'a mut [u8]) -> Self {
1113 		let mut bb = BitBuffer::new(buf);
1114 		let mut accumdata: u32 = 0;
1115 		let mut accumcount: u8 = 0;
1116 		for b in text.bytes() {
1117 			assert!((b'0' ..= b'9').contains(&b), "String contains non-numeric characters");
1118 			accumdata = accumdata * 10 + u32::from(b - b'0');
1119 			accumcount += 1;
1120 			if accumcount == 3 {
1121 				bb.append_bits(accumdata, 10);
1122 				accumdata = 0;
1123 				accumcount = 0;
1124 			}
1125 		}
1126 		if accumcount > 0 {  // 1 or 2 digits remaining
1127 			bb.append_bits(accumdata, accumcount * 3 + 1);
1128 		}
1129 		QrSegment::new(QrSegmentMode::Numeric, text.len(), bb.data, bb.length)
1130 	}
1131 
1132 
1133 	/// Returns a segment representing the given text string encoded in alphanumeric mode.
1134 	///
1135 	/// The characters allowed are: 0 to 9, A to Z (uppercase only), space,
1136 	/// dollar, percent, asterisk, plus, hyphen, period, slash, colon.
1137 	///
1138 	/// Panics if the string contains non-encodable characters.
make_alphanumeric(text: &str, buf: &'a mut [u8]) -> Self1139 	pub fn make_alphanumeric(text: &str, buf: &'a mut [u8]) -> Self {
1140 		let mut bb = BitBuffer::new(buf);
1141 		let mut accumdata: u32 = 0;
1142 		let mut accumcount: u8 = 0;
1143 		for c in text.chars() {
1144 			let i: usize = ALPHANUMERIC_CHARSET.find(c)
1145 				.expect("String contains unencodable characters in alphanumeric mode");
1146 			accumdata = accumdata * 45 + u32::try_from(i).unwrap();
1147 			accumcount += 1;
1148 			if accumcount == 2 {
1149 				bb.append_bits(accumdata, 11);
1150 				accumdata = 0;
1151 				accumcount = 0;
1152 			}
1153 		}
1154 		if accumcount > 0 {  // 1 character remaining
1155 			bb.append_bits(accumdata, 6);
1156 		}
1157 		QrSegment::new(QrSegmentMode::Alphanumeric, text.len(), bb.data, bb.length)
1158 	}
1159 
1160 
1161 	/// Returns a segment representing an Extended Channel Interpretation
1162 	/// (ECI) designator with the given assignment value.
make_eci(assignval: u32, buf: &'a mut [u8]) -> Self1163 	pub fn make_eci(assignval: u32, buf: &'a mut [u8]) -> Self {
1164 		let mut bb = BitBuffer::new(buf);
1165 		if assignval < (1 << 7) {
1166 			bb.append_bits(assignval, 8);
1167 		} else if assignval < (1 << 14) {
1168 			bb.append_bits(0b10, 2);
1169 			bb.append_bits(assignval, 14);
1170 		} else if assignval < 1_000_000 {
1171 			bb.append_bits(0b110, 3);
1172 			bb.append_bits(assignval, 21);
1173 		} else {
1174 			panic!("ECI assignment value out of range");
1175 		}
1176 		QrSegment::new(QrSegmentMode::Eci, 0, bb.data, bb.length)
1177 	}
1178 
1179 
1180 	/*---- Constructor (low level) ----*/
1181 
1182 	/// Creates a new QR Code segment with the given attributes and data.
1183 	///
1184 	/// The character count (numchars) must agree with the mode and
1185 	/// the bit buffer length, but the constraint isn't checked.
new(mode: QrSegmentMode, numchars: usize, data: &'a [u8], bitlength: usize) -> Self1186 	pub fn new(mode: QrSegmentMode, numchars: usize, data: &'a [u8], bitlength: usize) -> Self {
1187 		assert!(bitlength == 0 || (bitlength - 1) / 8 < data.len());
1188 		Self { mode, numchars, data, bitlength }
1189 	}
1190 
1191 
1192 	/*---- Instance field getters ----*/
1193 
1194 	/// Returns the mode indicator of this segment.
mode(&self) -> QrSegmentMode1195 	pub fn mode(&self) -> QrSegmentMode {
1196 		self.mode
1197 	}
1198 
1199 
1200 	/// Returns the character count field of this segment.
num_chars(&self) -> usize1201 	pub fn num_chars(&self) -> usize {
1202 		self.numchars
1203 	}
1204 
1205 
1206 	/*---- Other static functions ----*/
1207 
1208 	/// Returns the number of bytes needed for the data buffer of a segment
1209 	/// containing the given number of characters using the given mode, or None if the
1210 	/// internal calculation of the number of needed bits exceeds usize::MAX. Notes:
1211 	///
1212 	/// - It is okay for the user to allocate more bytes for the buffer than needed.
1213 	/// - For byte mode, numchars measures the number of bytes, not Unicode code points.
1214 	/// - For ECI mode, numchars must be 0, and the worst-case number of bytes is returned.
1215 	///   An actual ECI segment can have shorter data. For non-ECI modes, the result is exact.
calc_buffer_size(mode: QrSegmentMode, numchars: usize) -> Option<usize>1216 	pub fn calc_buffer_size(mode: QrSegmentMode, numchars: usize) -> Option<usize> {
1217 		let temp = Self::calc_bit_length(mode, numchars)?;
1218 		Some(temp / 8 + usize::from(temp % 8 != 0))  // ceil(temp / 8)
1219 	}
1220 
1221 
1222 	// Returns the number of data bits needed to represent a segment
1223 	// containing the given number of characters using the given mode,
1224 	// or None if the the number of needed bits exceeds usize::MAX. Notes:
1225 	// - For byte mode, numchars measures the number of bytes, not Unicode code points.
1226 	// - For ECI mode, numchars must be 0, and the worst-case number of bits is returned.
1227 	//   An actual ECI segment can have shorter data. For non-ECI modes, the result is exact.
calc_bit_length(mode: QrSegmentMode, numchars: usize) -> Option<usize>1228 	fn calc_bit_length(mode: QrSegmentMode, numchars: usize) -> Option<usize> {
1229 		// Returns ceil((numer / denom) * numchars)
1230 		let mul_frac_ceil = |numer: usize, denom: usize|
1231 			Some(numchars)
1232 				.and_then(|x| x.checked_mul(numer))
1233 				.and_then(|x| x.checked_add(denom - 1))
1234 				.map(|x| x / denom);
1235 
1236 		use QrSegmentMode::*;
1237 		match mode {
1238 			Numeric      => mul_frac_ceil(10, 3),
1239 			Alphanumeric => mul_frac_ceil(11, 2),
1240 			Byte         => mul_frac_ceil( 8, 1),
1241 			Kanji        => mul_frac_ceil(13, 1),
1242 			Eci => {
1243 				assert_eq!(numchars, 0);
1244 				Some(3 * 8)
1245 			},
1246 		}
1247 	}
1248 
1249 
1250 	// Calculates and returns the number of bits needed to encode the given
1251 	// segments at the given version. The result is None if a segment has too many
1252 	// characters to fit its length field, or the total bits exceeds usize::MAX.
get_total_bits(segs: &[Self], version: Version) -> Option<usize>1253 	fn get_total_bits(segs: &[Self], version: Version) -> Option<usize> {
1254 		let mut result: usize = 0;
1255 		for seg in segs {
1256 			let ccbits: u8 = seg.mode.num_char_count_bits(version);
1257 			// ccbits can be as large as 16, but usize can be as small as 16
1258 			if let Some(limit) = 1usize.checked_shl(ccbits.into()) {
1259 				if seg.numchars >= limit {
1260 					return None;  // The segment's length doesn't fit the field's bit width
1261 				}
1262 			}
1263 			result = result.checked_add(4 + usize::from(ccbits))?;
1264 			result = result.checked_add(seg.bitlength)?;
1265 		}
1266 		Some(result)
1267 	}
1268 
1269 
1270 	/// Tests whether the given string can be encoded as a segment in numeric mode.
1271 	/// A string is encodable iff each character is in the range 0 to 9.
is_numeric(text: &str) -> bool1272 	pub fn is_numeric(text: &str) -> bool {
1273 		text.chars().all(|c| ('0' ..= '9').contains(&c))
1274 	}
1275 
1276 
1277 	/// Tests whether the given string can be encoded as a segment in alphanumeric mode.
1278 	/// A string is encodable iff each character is in the following set: 0 to 9, A to Z
1279 	/// (uppercase only), space, dollar, percent, asterisk, plus, hyphen, period, slash, colon.
is_alphanumeric(text: &str) -> bool1280 	pub fn is_alphanumeric(text: &str) -> bool {
1281 		text.chars().all(|c| ALPHANUMERIC_CHARSET.contains(c))
1282 	}
1283 
1284 }
1285 
1286 
1287 // The set of all legal characters in alphanumeric mode,
1288 // where each character value maps to the index in the string.
1289 static ALPHANUMERIC_CHARSET: &str = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:";
1290 
1291 
1292 
1293 /*---- QrSegmentMode functionality ----*/
1294 
1295 /// Describes how a segment's data bits are interpreted.
1296 #[derive(Clone, Copy, PartialEq, Eq, Debug)]
1297 pub enum QrSegmentMode {
1298 	Numeric,
1299 	Alphanumeric,
1300 	Byte,
1301 	Kanji,
1302 	Eci,
1303 }
1304 
1305 
1306 impl QrSegmentMode {
1307 
1308 	// Returns an unsigned 4-bit integer value (range 0 to 15)
1309 	// representing the mode indicator bits for this mode object.
mode_bits(self) -> u321310 	fn mode_bits(self) -> u32 {
1311 		use QrSegmentMode::*;
1312 		match self {
1313 			Numeric      => 0x1,
1314 			Alphanumeric => 0x2,
1315 			Byte         => 0x4,
1316 			Kanji        => 0x8,
1317 			Eci          => 0x7,
1318 		}
1319 	}
1320 
1321 
1322 	// Returns the bit width of the character count field for a segment in this mode
1323 	// in a QR Code at the given version number. The result is in the range [0, 16].
num_char_count_bits(self, ver: Version) -> u81324 	fn num_char_count_bits(self, ver: Version) -> u8 {
1325 		use QrSegmentMode::*;
1326 		(match self {
1327 			Numeric      => [10, 12, 14],
1328 			Alphanumeric => [ 9, 11, 13],
1329 			Byte         => [ 8, 16, 16],
1330 			Kanji        => [ 8, 10, 12],
1331 			Eci          => [ 0,  0,  0],
1332 		})[usize::from((ver.value() + 7) / 17)]
1333 	}
1334 
1335 }
1336 
1337 
1338 /*---- BitBuffer functionality ----*/
1339 
1340 /// An appendable sequence of bits (0s and 1s).
1341 ///
1342 /// Mainly used by QrSegment.
1343 pub struct BitBuffer<'a> {
1344 
1345 	data: &'a mut [u8],
1346 
1347 	length: usize,
1348 
1349 }
1350 
1351 
1352 impl<'a> BitBuffer<'a> {
1353 
1354 	// Creates a bit buffer based on the given byte array.
new(buffer: &'a mut [u8]) -> Self1355 	pub fn new(buffer: &'a mut [u8]) -> Self {
1356 		Self {
1357 			data: buffer,
1358 			length: 0,
1359 		}
1360 	}
1361 
1362 
1363 	// Returns the length of this bit buffer, in bits.
len(&self) -> usize1364 	pub fn len(&self) -> usize {
1365 		self.length
1366 	}
1367 
1368 
1369 	// Appends the given number of low-order bits of the given value to this byte-based
1370 	// bit buffer, increasing the bit length. Requires 0 <= numBits <= 31 and val < 2^numBits.
append_bits(&mut self, val: u32, len: u8)1371 	pub fn append_bits(&mut self, val: u32, len: u8) {
1372 		assert!(len <= 31 && val >> len == 0);
1373 		assert!(usize::from(len) <= usize::MAX - self.length);
1374 		for i in (0 .. len).rev() {
1375 			let index: usize = self.length >> 3;
1376 			let shift: u8 = 7 - ((self.length as u8) & 7);
1377 			let bit: u8 = ((val >> i) as u8) & 1;
1378 			if shift == 7 {
1379 				self.data[index] = bit << shift;
1380 			} else {
1381 				self.data[index] |= bit << shift;
1382 			}
1383 			self.length += 1;
1384 		}
1385 	}
1386 
1387 }
1388 
1389 
1390 
1391 /*---- Miscellaneous values ----*/
1392 
1393 /// The error type when the supplied data does not fit any QR Code version.
1394 ///
1395 /// Ways to handle this exception include:
1396 ///
1397 /// - Decrease the error correction level if it was greater than `QrCodeEcc::Low`.
1398 /// - Increase the maxversion argument if it was less than `Version::MAX`.
1399 /// - Split the text data into better or optimal segments in order to reduce the number of bits required.
1400 /// - Change the text or binary data to be shorter.
1401 /// - Change the text to fit the character set of a particular segment mode (e.g. alphanumeric).
1402 /// - Propagate the error upward to the caller/user.
1403 #[derive(Debug, Clone)]
1404 pub enum DataTooLong {
1405 	SegmentTooLong,
1406 	DataOverCapacity(usize, usize),
1407 }
1408 
1409 impl core::fmt::Display for DataTooLong {
fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result1410 	fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
1411 		match *self {
1412 			Self::SegmentTooLong => write!(f, "Segment too long"),
1413 			Self::DataOverCapacity(datalen, maxcapacity) =>
1414 				write!(f, "Data length = {} bits, Max capacity = {} bits", datalen, maxcapacity),
1415 		}
1416 	}
1417 }
1418 
1419 
1420 /// A number between 1 and 40 (inclusive).
1421 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug)]
1422 pub struct Version(u8);
1423 
1424 impl Version {
1425 	/// The minimum version number supported in the QR Code Model 2 standard.
1426 	pub const MIN: Version = Version( 1);
1427 
1428 	/// The maximum version number supported in the QR Code Model 2 standard.
1429 	pub const MAX: Version = Version(40);
1430 
1431 	/// Creates a version object from the given number.
1432 	///
1433 	/// Panics if the number is outside the range [1, 40].
new(ver: u8) -> Self1434 	pub fn new(ver: u8) -> Self {
1435 		assert!((Version::MIN.value() ..= Version::MAX.value()).contains(&ver), "Version number out of range");
1436 		Self(ver)
1437 	}
1438 
1439 	/// Returns the value, which is in the range [1, 40].
value(self) -> u81440 	pub fn value(self) -> u8 {
1441 		self.0
1442 	}
1443 
1444 	/// Returns the minimum length required for the output and temporary
1445 	/// buffers when creating a QR Code of this version number.
buffer_len(self) -> usize1446 	pub const fn buffer_len(self) -> usize {
1447 		let sidelen = (self.0 as usize) * 4 + 17;
1448 		(sidelen * sidelen + 7) / 8 + 1
1449 	}
1450 }
1451 
1452 
1453 /// A number between 0 and 7 (inclusive).
1454 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug)]
1455 pub struct Mask(u8);
1456 
1457 impl Mask {
1458 	/// Creates a mask object from the given number.
1459 	///
1460 	/// Panics if the number is outside the range [0, 7].
new(mask: u8) -> Self1461 	pub fn new(mask: u8) -> Self {
1462 		assert!(mask <= 7, "Mask value out of range");
1463 		Self(mask)
1464 	}
1465 
1466 	/// Returns the value, which is in the range [0, 7].
value(self) -> u81467 	pub fn value(self) -> u8 {
1468 		self.0
1469 	}
1470 }
1471 
1472 
1473 // Returns true iff the i'th bit of x is set to 1.
get_bit(x: u32, i: u8) -> bool1474 fn get_bit(x: u32, i: u8) -> bool {
1475 	(x >> i) & 1 != 0
1476 }
1477