• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * QR Code generator library (Rust)
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 //! - Available in 6 programming languages, all with nearly equal functionality: Java, TypeScript/JavaScript, Python, Rust, C++, C
39 //! - Significantly shorter code but more documentation comments compared to competing libraries
40 //! - Supports encoding all 40 versions (sizes) and all 4 error correction levels, as per the QR Code Model 2 standard
41 //! - Output format: Raw modules/pixels of the QR symbol
42 //! - Detects finder-like penalty patterns more accurately than other implementations
43 //! - Encodes numeric and special-alphanumeric text in less space than general text
44 //! - Open source code under the permissive MIT License
45 //!
46 //! Manual parameters:
47 //!
48 //! - User can specify minimum and maximum version numbers allowed, then library will automatically choose smallest version in the range that fits the data
49 //! - User can specify mask pattern manually, otherwise library will automatically evaluate all 8 masks and select the optimal one
50 //! - User can specify absolute error correction level, or allow the library to boost it if it doesn't increase the version number
51 //! - User can create a list of data segments manually and add ECI segments
52 //!
53 //! # Examples
54 //!
55 //! ```
56 //! extern crate qrcodegen;
57 //! use qrcodegen::Mask;
58 //! use qrcodegen::QrCode;
59 //! use qrcodegen::QrCodeEcc;
60 //! use qrcodegen::QrSegment;
61 //! use qrcodegen::Version;
62 //! ```
63 //!
64 //! Simple operation:
65 //!
66 //! ```
67 //! let qr = QrCode::encode_text("Hello, world!",
68 //!     QrCodeEcc::Medium).unwrap();
69 //! let svg = to_svg_string(&qr, 4);  // See qrcodegen-demo
70 //! ```
71 //!
72 //! Manual operation:
73 //!
74 //! ```
75 //! let chrs: Vec<char> = "3141592653589793238462643383".chars().collect();
76 //! let segs = QrSegment::make_segments(&chrs);
77 //! let qr = QrCode::encode_segments_advanced(&segs, QrCodeEcc::High,
78 //!     Version::new(5), Version::new(5), Some(Mask::new(2)), false).unwrap();
79 //! for y in 0 .. qr.size() {
80 //!     for x in 0 .. qr.size() {
81 //!         (... paint qr.get_module(x, y) ...)
82 //!     }
83 //! }
84 //! ```
85 
86 
87 /*---- QrCode functionality ----*/
88 
89 /// A QR Code symbol, which is a type of two-dimension barcode.
90 ///
91 /// Invented by Denso Wave and described in the ISO/IEC 18004 standard.
92 ///
93 /// Instances of this struct represent an immutable square grid of dark and light cells.
94 /// The impl provides static factory functions to create a QR Code from text or binary data.
95 /// The struct and impl cover the QR Code Model 2 specification, supporting all versions
96 /// (sizes) from 1 to 40, all 4 error correction levels, and 4 character encoding modes.
97 ///
98 /// Ways to create a QR Code object:
99 ///
100 /// - High level: Take the payload data and call `QrCode::encode_text()` or `QrCode::encode_binary()`.
101 /// - Mid level: Custom-make the list of segments and call
102 ///   `QrCode::encode_segments()` or `QrCode::encode_segments_advanced()`.
103 /// - Low level: Custom-make the array of data codeword bytes (including segment
104 ///   headers and final padding, excluding error correction codewords), supply the
105 ///   appropriate version number, and call the `QrCode::encode_codewords()` constructor.
106 ///
107 /// (Note that all ways require supplying the desired error correction level.)
108 #[derive(Clone, PartialEq, Eq)]
109 pub struct QrCode {
110 
111 	// Scalar parameters:
112 
113 	// The version number of this QR Code, which is between 1 and 40 (inclusive).
114 	// This determines the size of this barcode.
115 	version: Version,
116 
117 	// The width and height of this QR Code, measured in modules, between
118 	// 21 and 177 (inclusive). This is equal to version * 4 + 17.
119 	size: i32,
120 
121 	// The error correction level used in this QR Code.
122 	errorcorrectionlevel: QrCodeEcc,
123 
124 	// The index of the mask pattern used in this QR Code, which is between 0 and 7 (inclusive).
125 	// Even if a QR Code is created with automatic masking requested (mask = None),
126 	// the resulting object still has a mask value between 0 and 7.
127 	mask: Mask,
128 
129 	// Grids of modules/pixels, with dimensions of size*size:
130 
131 	// The modules of this QR Code (false = light, true = dark).
132 	// Immutable after constructor finishes. Accessed through get_module().
133 	modules: Vec<bool>,
134 
135 	// Indicates function modules that are not subjected to masking. Discarded when constructor finishes.
136 	isfunction: Vec<bool>,
137 
138 }
139 
140 
141 impl QrCode {
142 
143 	/*---- Static factory functions (high level) ----*/
144 
145 	/// Returns a QR Code representing the given Unicode text string at the given error correction level.
146 	///
147 	/// As a conservative upper bound, this function is guaranteed to succeed for strings that have 738 or fewer Unicode
148 	/// code points (not UTF-8 code units) if the low error correction level is used. The smallest possible
149 	/// QR Code version is automatically chosen for the output. The ECC level of the result may be higher than
150 	/// the ecl argument if it can be done without increasing the version.
151 	///
152 	/// Returns a wrapped `QrCode` if successful, or `Err` if the
153 	/// data is too long to fit in any version at the given ECC level.
encode_text(text: &str, ecl: QrCodeEcc) -> Result<Self,DataTooLong>154 	pub fn encode_text(text: &str, ecl: QrCodeEcc) -> Result<Self,DataTooLong> {
155 		let chrs: Vec<char> = text.chars().collect();
156 		let segs: Vec<QrSegment> = QrSegment::make_segments(&chrs);
157 		QrCode::encode_segments(&segs, ecl)
158 	}
159 
160 
161 	/// Returns a QR Code representing the given binary data at the given error correction level.
162 	///
163 	/// This function always encodes using the binary segment mode, not any text mode. The maximum number of
164 	/// bytes allowed is 2953. The smallest possible QR Code version is automatically chosen for the output.
165 	/// The ECC level of the result may be higher than the ecl argument if it can be done without increasing the version.
166 	///
167 	/// Returns a wrapped `QrCode` if successful, or `Err` if the
168 	/// data is too long to fit in any version at the given ECC level.
encode_binary(data: &[u8], ecl: QrCodeEcc) -> Result<Self,DataTooLong>169 	pub fn encode_binary(data: &[u8], ecl: QrCodeEcc) -> Result<Self,DataTooLong> {
170 		let segs: [QrSegment; 1] = [QrSegment::make_bytes(data)];
171 		QrCode::encode_segments(&segs, ecl)
172 	}
173 
174 
175 	/*---- Static factory functions (mid level) ----*/
176 
177 	/// Returns a QR Code representing the given segments at the given error correction level.
178 	///
179 	/// The smallest possible QR Code version is automatically chosen for the output. The ECC level
180 	/// of the result may be higher than the ecl argument if it can be done without increasing the version.
181 	///
182 	/// This function allows the user to create a custom sequence of segments that switches
183 	/// between modes (such as alphanumeric and byte) to encode text in less space.
184 	/// This is a mid-level API; the high-level API is `encode_text()` and `encode_binary()`.
185 	///
186 	/// Returns a wrapped `QrCode` if successful, or `Err` if the
187 	/// data is too long to fit in any version at the given ECC level.
encode_segments(segs: &[QrSegment], ecl: QrCodeEcc) -> Result<Self,DataTooLong>188 	pub fn encode_segments(segs: &[QrSegment], ecl: QrCodeEcc) -> Result<Self,DataTooLong> {
189 		QrCode::encode_segments_advanced(segs, ecl, Version::MIN, Version::MAX, None, true)
190 	}
191 
192 
193 	/// Returns a QR Code representing the given segments with the given encoding parameters.
194 	///
195 	/// The smallest possible QR Code version within the given range is automatically
196 	/// chosen for the output. Iff boostecl is `true`, then the ECC level of the result
197 	/// may be higher than the ecl argument if it can be done without increasing the
198 	/// version. The mask number is either between 0 to 7 (inclusive) to force that
199 	/// mask, or `None` to automatically choose an appropriate mask (which may be slow).
200 	///
201 	/// This function allows the user to create a custom sequence of segments that switches
202 	/// between modes (such as alphanumeric and byte) to encode text in less space.
203 	/// This is a mid-level API; the high-level API is `encode_text()` and `encode_binary()`.
204 	///
205 	/// Returns a wrapped `QrCode` if successful, or `Err` if the data is too
206 	/// long to fit in any version in the given range at the given ECC level.
encode_segments_advanced(segs: &[QrSegment], mut ecl: QrCodeEcc, minversion: Version, maxversion: Version, mask: Option<Mask>, boostecl: bool) -> Result<Self,DataTooLong>207 	pub fn encode_segments_advanced(segs: &[QrSegment], mut ecl: QrCodeEcc,
208 			minversion: Version, maxversion: Version, mask: Option<Mask>, boostecl: bool) -> Result<Self,DataTooLong> {
209 		assert!(minversion.value() <= maxversion.value(), "Invalid value");
210 
211 		// Find the minimal version number to use
212 		let mut version: Version = minversion;
213 		let datausedbits: usize = loop {
214 			// Number of data bits available
215 			let datacapacitybits: usize = QrCode::get_num_data_codewords(version, ecl) * 8;
216 			let dataused: Option<usize> = QrSegment::get_total_bits(segs, version);
217 			if dataused.map_or(false, |n| n <= datacapacitybits) {
218 				break dataused.unwrap();  // This version number is found to be suitable
219 			} else if version.value() >= maxversion.value() {  // All versions in the range could not fit the given data
220 				let msg: String = match dataused {
221 					None => String::from("Segment too long"),
222 					Some(n) => format!("Data length = {} bits, Max capacity = {} bits",
223 						n, datacapacitybits),
224 				};
225 				return Err(DataTooLong(msg));
226 			} else {
227 				version = Version::new(version.value() + 1);
228 			}
229 		};
230 
231 		// Increase the error correction level while the data still fits in the current version number
232 		for &newecl in &[QrCodeEcc::Medium, QrCodeEcc::Quartile, QrCodeEcc::High] {  // From low to high
233 			if boostecl && datausedbits <= QrCode::get_num_data_codewords(version, newecl) * 8 {
234 				ecl = newecl;
235 			}
236 		}
237 
238 		// Concatenate all segments to create the data bit string
239 		let mut bb = BitBuffer(Vec::new());
240 		for seg in segs {
241 			bb.append_bits(seg.mode.mode_bits(), 4);
242 			bb.append_bits(seg.numchars as u32, seg.mode.num_char_count_bits(version));
243 			bb.0.extend_from_slice(&seg.data);
244 		}
245 		assert_eq!(bb.0.len(), datausedbits);
246 
247 		// Add terminator and pad up to a byte if applicable
248 		let datacapacitybits: usize = QrCode::get_num_data_codewords(version, ecl) * 8;
249 		assert!(bb.0.len() <= datacapacitybits);
250 		let numzerobits: usize = std::cmp::min(4, datacapacitybits - bb.0.len());
251 		bb.append_bits(0, numzerobits as u8);
252 		let numzerobits: usize = bb.0.len().wrapping_neg() & 7;
253 		bb.append_bits(0, numzerobits as u8);
254 		assert_eq!(bb.0.len() % 8, 0, "Assertion error");
255 
256 		// Pad with alternating bytes until data capacity is reached
257 		for &padbyte in [0xEC, 0x11].iter().cycle() {
258 			if bb.0.len() >= datacapacitybits {
259 				break;
260 			}
261 			bb.append_bits(padbyte, 8);
262 		}
263 
264 		// Pack bits into bytes in big endian
265 		let mut datacodewords = vec![0u8; bb.0.len() / 8];
266 		for (i, &bit) in bb.0.iter().enumerate() {
267 			datacodewords[i >> 3] |= u8::from(bit) << (7 - (i & 7));
268 		}
269 
270 		// Create the QR Code object
271 		Ok(QrCode::encode_codewords(version, ecl, &datacodewords, mask))
272 	}
273 
274 
275 	/*---- Constructor (low level) ----*/
276 
277 	/// Creates a new QR Code with the given version number,
278 	/// error correction level, data codeword bytes, and mask number.
279 	///
280 	/// This is a low-level API that most users should not use directly.
281 	/// A mid-level API is the `encode_segments()` function.
encode_codewords(ver: Version, ecl: QrCodeEcc, datacodewords: &[u8], mut mask: Option<Mask>) -> Self282 	pub fn encode_codewords(ver: Version, ecl: QrCodeEcc, datacodewords: &[u8], mut mask: Option<Mask>) -> Self {
283 		// Initialize fields
284 		let size = usize::from(ver.value()) * 4 + 17;
285 		let mut result = Self {
286 			version: ver,
287 			size: size as i32,
288 			mask: Mask::new(0),  // Dummy value
289 			errorcorrectionlevel: ecl,
290 			modules   : vec![false; size * size],  // Initially all light
291 			isfunction: vec![false; size * size],
292 		};
293 
294 		// Compute ECC, draw modules
295 		result.draw_function_patterns();
296 		let allcodewords: Vec<u8> = result.add_ecc_and_interleave(datacodewords);
297 		result.draw_codewords(&allcodewords);
298 
299 		// Do masking
300 		if mask.is_none() {  // Automatically choose best mask
301 			let mut minpenalty = std::i32::MAX;
302 			for i in 0u8 .. 8 {
303 				let newmask = Mask::new(i);
304 				result.apply_mask(newmask);
305 				result.draw_format_bits(newmask);
306 				let penalty: i32 = result.get_penalty_score();
307 				if penalty < minpenalty {
308 					mask = Some(newmask);
309 					minpenalty = penalty;
310 				}
311 				result.apply_mask(newmask);  // Undoes the mask due to XOR
312 			}
313 		}
314 		let mask: Mask = mask.unwrap();
315 		result.mask = mask;
316 		result.apply_mask(mask);  // Apply the final choice of mask
317 		result.draw_format_bits(mask);  // Overwrite old format bits
318 
319 		result.isfunction.clear();
320 		result.isfunction.shrink_to_fit();
321 		result
322 	}
323 
324 
325 	/*---- Public methods ----*/
326 
327 	/// Returns this QR Code's version, in the range [1, 40].
version(&self) -> Version328 	pub fn version(&self) -> Version {
329 		self.version
330 	}
331 
332 
333 	/// Returns this QR Code's size, in the range [21, 177].
size(&self) -> i32334 	pub fn size(&self) -> i32 {
335 		self.size
336 	}
337 
338 
339 	/// Returns this QR Code's error correction level.
error_correction_level(&self) -> QrCodeEcc340 	pub fn error_correction_level(&self) -> QrCodeEcc {
341 		self.errorcorrectionlevel
342 	}
343 
344 
345 	/// Returns this QR Code's mask, in the range [0, 7].
mask(&self) -> Mask346 	pub fn mask(&self) -> Mask {
347 		self.mask
348 	}
349 
350 
351 	/// Returns the color of the module (pixel) at the given coordinates,
352 	/// which is `false` for light or `true` for dark.
353 	///
354 	/// The top left corner has the coordinates (x=0, y=0). If the given
355 	/// coordinates are out of bounds, then `false` (light) is returned.
get_module(&self, x: i32, y: i32) -> bool356 	pub fn get_module(&self, x: i32, y: i32) -> bool {
357 		0 <= x && x < self.size && 0 <= y && y < self.size && self.module(x, y)
358 	}
359 
360 
361 	// Returns the color of the module at the given coordinates, which must be in bounds.
module(&self, x: i32, y: i32) -> bool362 	fn module(&self, x: i32, y: i32) -> bool {
363 		self.modules[(y * self.size + x) as usize]
364 	}
365 
366 
367 	// Returns a mutable reference to the module's color at the given coordinates, which must be in bounds.
module_mut(&mut self, x: i32, y: i32) -> &mut bool368 	fn module_mut(&mut self, x: i32, y: i32) -> &mut bool {
369 		&mut self.modules[(y * self.size + x) as usize]
370 	}
371 
372 
373 	/*---- Private helper methods for constructor: Drawing function modules ----*/
374 
375 	// Reads this object's version field, and draws and marks all function modules.
draw_function_patterns(&mut self)376 	fn draw_function_patterns(&mut self) {
377 		// Draw horizontal and vertical timing patterns
378 		let size: i32 = self.size;
379 		for i in 0 .. size {
380 			self.set_function_module(6, i, i % 2 == 0);
381 			self.set_function_module(i, 6, i % 2 == 0);
382 		}
383 
384 		// Draw 3 finder patterns (all corners except bottom right; overwrites some timing modules)
385 		self.draw_finder_pattern(3, 3);
386 		self.draw_finder_pattern(size - 4, 3);
387 		self.draw_finder_pattern(3, size - 4);
388 
389 		// Draw numerous alignment patterns
390 		let alignpatpos: Vec<i32> = self.get_alignment_pattern_positions();
391 		let numalign: usize = alignpatpos.len();
392 		for i in 0 .. numalign {
393 			for j in 0 .. numalign {
394 				// Don't draw on the three finder corners
395 				if !(i == 0 && j == 0 || i == 0 && j == numalign - 1 || i == numalign - 1 && j == 0) {
396 					self.draw_alignment_pattern(alignpatpos[i], alignpatpos[j]);
397 				}
398 			}
399 		}
400 
401 		// Draw configuration data
402 		self.draw_format_bits(Mask::new(0));  // Dummy mask value; overwritten later in the constructor
403 		self.draw_version();
404 	}
405 
406 
407 	// Draws two copies of the format bits (with its own error correction code)
408 	// based on the given mask and this object's error correction level field.
draw_format_bits(&mut self, mask: Mask)409 	fn draw_format_bits(&mut self, mask: Mask) {
410 		// Calculate error correction code and pack bits
411 		let bits: u32 = {
412 			// errcorrlvl is uint2, mask is uint3
413 			let data: u32 = u32::from(self.errorcorrectionlevel.format_bits() << 3 | mask.value());
414 			let mut rem: u32 = data;
415 			for _ in 0 .. 10 {
416 				rem = (rem << 1) ^ ((rem >> 9) * 0x537);
417 			}
418 			(data << 10 | rem) ^ 0x5412  // uint15
419 		};
420 		assert_eq!(bits >> 15, 0, "Assertion error");
421 
422 		// Draw first copy
423 		for i in 0 .. 6 {
424 			self.set_function_module(8, i, get_bit(bits, i));
425 		}
426 		self.set_function_module(8, 7, get_bit(bits, 6));
427 		self.set_function_module(8, 8, get_bit(bits, 7));
428 		self.set_function_module(7, 8, get_bit(bits, 8));
429 		for i in 9 .. 15 {
430 			self.set_function_module(14 - i, 8, get_bit(bits, i));
431 		}
432 
433 		// Draw second copy
434 		let size: i32 = self.size;
435 		for i in 0 .. 8 {
436 			self.set_function_module(size - 1 - i, 8, get_bit(bits, i));
437 		}
438 		for i in 8 .. 15 {
439 			self.set_function_module(8, size - 15 + i, get_bit(bits, i));
440 		}
441 		self.set_function_module(8, size - 8, true);  // Always dark
442 	}
443 
444 
445 	// Draws two copies of the version bits (with its own error correction code),
446 	// based on this object's version field, iff 7 <= version <= 40.
draw_version(&mut self)447 	fn draw_version(&mut self) {
448 		if self.version.value() < 7 {
449 			return;
450 		}
451 
452 		// Calculate error correction code and pack bits
453 		let bits: u32 = {
454 			let data = u32::from(self.version.value());  // uint6, in the range [7, 40]
455 			let mut rem: u32 = data;
456 			for _ in 0 .. 12 {
457 				rem = (rem << 1) ^ ((rem >> 11) * 0x1F25);
458 			}
459 			data << 12 | rem  // uint18
460 		};
461 		assert!(bits >> 18 == 0, "Assertion error");
462 
463 		// Draw two copies
464 		for i in 0 .. 18 {
465 			let bit: bool = get_bit(bits, i);
466 			let a: i32 = self.size - 11 + i % 3;
467 			let b: i32 = i / 3;
468 			self.set_function_module(a, b, bit);
469 			self.set_function_module(b, a, bit);
470 		}
471 	}
472 
473 
474 	// Draws a 9*9 finder pattern including the border separator,
475 	// with the center module at (x, y). Modules can be out of bounds.
draw_finder_pattern(&mut self, x: i32, y: i32)476 	fn draw_finder_pattern(&mut self, x: i32, y: i32) {
477 		for dy in -4 ..= 4 {
478 			for dx in -4 ..= 4 {
479 				let xx: i32 = x + dx;
480 				let yy: i32 = y + dy;
481 				if 0 <= xx && xx < self.size && 0 <= yy && yy < self.size {
482 					let dist: i32 = std::cmp::max(dx.abs(), dy.abs());  // Chebyshev/infinity norm
483 					self.set_function_module(xx, yy, dist != 2 && dist != 4);
484 				}
485 			}
486 		}
487 	}
488 
489 
490 	// Draws a 5*5 alignment pattern, with the center module
491 	// at (x, y). All modules must be in bounds.
draw_alignment_pattern(&mut self, x: i32, y: i32)492 	fn draw_alignment_pattern(&mut self, x: i32, y: i32) {
493 		for dy in -2 ..= 2 {
494 			for dx in -2 ..= 2 {
495 				self.set_function_module(x + dx, y + dy, std::cmp::max(dx.abs(), dy.abs()) != 1);
496 			}
497 		}
498 	}
499 
500 
501 	// Sets the color of a module and marks it as a function module.
502 	// Only used by the constructor. Coordinates must be in bounds.
set_function_module(&mut self, x: i32, y: i32, isdark: bool)503 	fn set_function_module(&mut self, x: i32, y: i32, isdark: bool) {
504 		*self.module_mut(x, y) = isdark;
505 		self.isfunction[(y * self.size + x) as usize] = true;
506 	}
507 
508 
509 	/*---- Private helper methods for constructor: Codewords and masking ----*/
510 
511 	// Returns a new byte string representing the given data with the appropriate error correction
512 	// codewords appended to it, based on this object's version and error correction level.
add_ecc_and_interleave(&self, data: &[u8]) -> Vec<u8>513 	fn add_ecc_and_interleave(&self, data: &[u8]) -> Vec<u8> {
514 		let ver: Version = self.version;
515 		let ecl: QrCodeEcc = self.errorcorrectionlevel;
516 		assert_eq!(data.len(), QrCode::get_num_data_codewords(ver, ecl), "Illegal argument");
517 
518 		// Calculate parameter numbers
519 		let numblocks: usize = QrCode::table_get(&NUM_ERROR_CORRECTION_BLOCKS, ver, ecl);
520 		let blockecclen: usize = QrCode::table_get(&ECC_CODEWORDS_PER_BLOCK  , ver, ecl);
521 		let rawcodewords: usize = QrCode::get_num_raw_data_modules(ver) / 8;
522 		let numshortblocks: usize = numblocks - rawcodewords % numblocks;
523 		let shortblocklen: usize = rawcodewords / numblocks;
524 
525 		// Split data into blocks and append ECC to each block
526 		let mut blocks = Vec::<Vec<u8>>::with_capacity(numblocks);
527 		let rsdiv: Vec<u8> = QrCode::reed_solomon_compute_divisor(blockecclen);
528 		let mut k: usize = 0;
529 		for i in 0 .. numblocks {
530 			let datlen: usize = shortblocklen - blockecclen + usize::from(i >= numshortblocks);
531 			let mut dat = data[k .. k + datlen].to_vec();
532 			k += datlen;
533 			let ecc: Vec<u8> = QrCode::reed_solomon_compute_remainder(&dat, &rsdiv);
534 			if i < numshortblocks {
535 				dat.push(0);
536 			}
537 			dat.extend_from_slice(&ecc);
538 			blocks.push(dat);
539 		}
540 
541 		// Interleave (not concatenate) the bytes from every block into a single sequence
542 		let mut result = Vec::<u8>::with_capacity(rawcodewords);
543 		for i in 0 ..= shortblocklen {
544 			for (j, block) in blocks.iter().enumerate() {
545 				// Skip the padding byte in short blocks
546 				if i != shortblocklen - blockecclen || j >= numshortblocks {
547 					result.push(block[i]);
548 				}
549 			}
550 		}
551 		result
552 	}
553 
554 
555 	// Draws the given sequence of 8-bit codewords (data and error correction) onto the entire
556 	// data area of this QR Code. Function modules need to be marked off before this is called.
draw_codewords(&mut self, data: &[u8])557 	fn draw_codewords(&mut self, data: &[u8]) {
558 		assert_eq!(data.len(), QrCode::get_num_raw_data_modules(self.version) / 8, "Illegal argument");
559 
560 		let mut i: usize = 0;  // Bit index into the data
561 		// Do the funny zigzag scan
562 		let mut right: i32 = self.size - 1;
563 		while right >= 1 {  // Index of right column in each column pair
564 			if right == 6 {
565 				right = 5;
566 			}
567 			for vert in 0 .. self.size {  // Vertical counter
568 				for j in 0 .. 2 {
569 					let x: i32 = right - j;  // Actual x coordinate
570 					let upward: bool = (right + 1) & 2 == 0;
571 					let y: i32 = if upward { self.size - 1 - vert } else { vert };  // Actual y coordinate
572 					if !self.isfunction[(y * self.size + x) as usize] && i < data.len() * 8 {
573 						*self.module_mut(x, y) = get_bit(u32::from(data[i >> 3]), 7 - ((i & 7) as i32));
574 						i += 1;
575 					}
576 					// If this QR Code has any remainder bits (0 to 7), they were assigned as
577 					// 0/false/light by the constructor and are left unchanged by this method
578 				}
579 			}
580 			right -= 2;
581 		}
582 		assert_eq!(i, data.len() * 8, "Assertion error");
583 	}
584 
585 
586 	// XORs the codeword modules in this QR Code with the given mask pattern.
587 	// The function modules must be marked and the codeword bits must be drawn
588 	// before masking. Due to the arithmetic of XOR, calling apply_mask() with
589 	// the same mask value a second time will undo the mask. A final well-formed
590 	// QR Code needs exactly one (not zero, two, etc.) mask applied.
apply_mask(&mut self, mask: Mask)591 	fn apply_mask(&mut self, mask: Mask) {
592 		for y in 0 .. self.size {
593 			for x in 0 .. self.size {
594 				let invert: bool = match mask.value() {
595 					0 => (x + y) % 2 == 0,
596 					1 => y % 2 == 0,
597 					2 => x % 3 == 0,
598 					3 => (x + y) % 3 == 0,
599 					4 => (x / 3 + y / 2) % 2 == 0,
600 					5 => x * y % 2 + x * y % 3 == 0,
601 					6 => (x * y % 2 + x * y % 3) % 2 == 0,
602 					7 => ((x + y) % 2 + x * y % 3) % 2 == 0,
603 					_ => unreachable!(),
604 				};
605 				*self.module_mut(x, y) ^= invert & !self.isfunction[(y * self.size + x) as usize];
606 			}
607 		}
608 	}
609 
610 
611 	// Calculates and returns the penalty score based on state of this QR Code's current modules.
612 	// This is used by the automatic mask choice algorithm to find the mask pattern that yields the lowest score.
get_penalty_score(&self) -> i32613 	fn get_penalty_score(&self) -> i32 {
614 		let mut result: i32 = 0;
615 		let size: i32 = self.size;
616 
617 		// Adjacent modules in row having same color, and finder-like patterns
618 		for y in 0 .. size {
619 			let mut runcolor = false;
620 			let mut runx: i32 = 0;
621 			let mut runhistory = FinderPenalty::new(size);
622 			for x in 0 .. size {
623 				if self.module(x, y) == runcolor {
624 					runx += 1;
625 					if runx == 5 {
626 						result += PENALTY_N1;
627 					} else if runx > 5 {
628 						result += 1;
629 					}
630 				} else {
631 					runhistory.add_history(runx);
632 					if !runcolor {
633 						result += runhistory.count_patterns() * PENALTY_N3;
634 					}
635 					runcolor = self.module(x, y);
636 					runx = 1;
637 				}
638 			}
639 			result += runhistory.terminate_and_count(runcolor, runx) * PENALTY_N3;
640 		}
641 		// Adjacent modules in column having same color, and finder-like patterns
642 		for x in 0 .. size {
643 			let mut runcolor = false;
644 			let mut runy: i32 = 0;
645 			let mut runhistory = FinderPenalty::new(size);
646 			for y in 0 .. size {
647 				if self.module(x, y) == runcolor {
648 					runy += 1;
649 					if runy == 5 {
650 						result += PENALTY_N1;
651 					} else if runy > 5 {
652 						result += 1;
653 					}
654 				} else {
655 					runhistory.add_history(runy);
656 					if !runcolor {
657 						result += runhistory.count_patterns() * PENALTY_N3;
658 					}
659 					runcolor = self.module(x, y);
660 					runy = 1;
661 				}
662 			}
663 			result += runhistory.terminate_and_count(runcolor, runy) * PENALTY_N3;
664 		}
665 
666 		// 2*2 blocks of modules having same color
667 		for y in 0 .. size - 1 {
668 			for x in 0 .. size - 1 {
669 				let color: bool = self.module(x, y);
670 				if color == self.module(x + 1, y) &&
671 				   color == self.module(x, y + 1) &&
672 				   color == self.module(x + 1, y + 1) {
673 					result += PENALTY_N2;
674 				}
675 			}
676 		}
677 
678 		// Balance of dark and light modules
679 		let dark: i32 = self.modules.iter().copied().map(i32::from).sum();
680 		let total: i32 = size * size;  // Note that size is odd, so dark/total != 1/2
681 		// Compute the smallest integer k >= 0 such that (45-5k)% <= dark/total <= (55+5k)%
682 		let k: i32 = ((dark * 20 - total * 10).abs() + total - 1) / total - 1;
683 		result += k * PENALTY_N4;
684 		result
685 	}
686 
687 
688 	/*---- Private helper functions ----*/
689 
690 	// Returns an ascending list of positions of alignment patterns for this version number.
691 	// Each position is in the range [0,177), and are used on both the x and y axes.
692 	// This could be implemented as lookup table of 40 variable-length lists of unsigned bytes.
get_alignment_pattern_positions(&self) -> Vec<i32>693 	fn get_alignment_pattern_positions(&self) -> Vec<i32> {
694 		let ver: u8 = self.version.value();
695 		if ver == 1 {
696 			vec![]
697 		} else {
698 			let numalign = i32::from(ver) / 7 + 2;
699 			let step: i32 = if ver == 32 { 26 } else
700 				{(i32::from(ver) * 4 + numalign * 2 + 1) / (numalign * 2 - 2) * 2};
701 			let mut result: Vec<i32> = (0 .. numalign - 1).map(
702 				|i| self.size - 7 - i * step).collect();
703 			result.push(6);
704 			result.reverse();
705 			result
706 		}
707 	}
708 
709 
710 	// Returns the number of data bits that can be stored in a QR Code of the given version number, after
711 	// all function modules are excluded. This includes remainder bits, so it might not be a multiple of 8.
712 	// 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) -> usize713 	fn get_num_raw_data_modules(ver: Version) -> usize {
714 		let ver = usize::from(ver.value());
715 		let mut result: usize = (16 * ver + 128) * ver + 64;
716 		if ver >= 2 {
717 			let numalign: usize = ver / 7 + 2;
718 			result -= (25 * numalign - 10) * numalign - 55;
719 			if ver >= 7 {
720 				result -= 36;
721 			}
722 		}
723 		assert!(208 <= result && result <= 29648);
724 		result
725 	}
726 
727 
728 	// Returns the number of 8-bit data (i.e. not error correction) codewords contained in any
729 	// QR Code of the given version number and error correction level, with remainder bits discarded.
730 	// This stateless pure function could be implemented as a (40*4)-cell lookup table.
get_num_data_codewords(ver: Version, ecl: QrCodeEcc) -> usize731 	fn get_num_data_codewords(ver: Version, ecl: QrCodeEcc) -> usize {
732 		QrCode::get_num_raw_data_modules(ver) / 8
733 			- QrCode::table_get(&ECC_CODEWORDS_PER_BLOCK    , ver, ecl)
734 			* QrCode::table_get(&NUM_ERROR_CORRECTION_BLOCKS, ver, ecl)
735 	}
736 
737 
738 	// Returns an entry from the given table based on the given values.
table_get(table: &'static [[i8; 41]; 4], ver: Version, ecl: QrCodeEcc) -> usize739 	fn table_get(table: &'static [[i8; 41]; 4], ver: Version, ecl: QrCodeEcc) -> usize {
740 		table[ecl.ordinal()][usize::from(ver.value())] as usize
741 	}
742 
743 
744 	// Returns a Reed-Solomon ECC generator polynomial for the given degree. This could be
745 	// implemented as a lookup table over all possible parameter values, instead of as an algorithm.
reed_solomon_compute_divisor(degree: usize) -> Vec<u8>746 	fn reed_solomon_compute_divisor(degree: usize) -> Vec<u8> {
747 		assert!(1 <= degree && degree <= 255, "Degree out of range");
748 		// Polynomial coefficients are stored from highest to lowest power, excluding the leading term which is always 1.
749 		// For example the polynomial x^3 + 255x^2 + 8x + 93 is stored as the uint8 array [255, 8, 93].
750 		let mut result = vec![0u8; degree - 1];
751 		result.push(1);  // Start off with the monomial x^0
752 
753 		// Compute the product polynomial (x - r^0) * (x - r^1) * (x - r^2) * ... * (x - r^{degree-1}),
754 		// and drop the highest monomial term which is always 1x^degree.
755 		// Note that r = 0x02, which is a generator element of this field GF(2^8/0x11D).
756 		let mut root: u8 = 1;
757 		for _ in 0 .. degree {  // Unused variable i
758 			// Multiply the current product by (x - r^i)
759 			for j in 0 .. degree {
760 				result[j] = QrCode::reed_solomon_multiply(result[j], root);
761 				if j + 1 < result.len() {
762 					result[j] ^= result[j + 1];
763 				}
764 			}
765 			root = QrCode::reed_solomon_multiply(root, 0x02);
766 		}
767 		result
768 	}
769 
770 
771 	// Returns the Reed-Solomon error correction codeword for the given data and divisor polynomials.
reed_solomon_compute_remainder(data: &[u8], divisor: &[u8]) -> Vec<u8>772 	fn reed_solomon_compute_remainder(data: &[u8], divisor: &[u8]) -> Vec<u8> {
773 		let mut result = vec![0u8; divisor.len()];
774 		for b in data {  // Polynomial division
775 			let factor: u8 = b ^ result.remove(0);
776 			result.push(0);
777 			for (x, &y) in result.iter_mut().zip(divisor.iter()) {
778 				*x ^= QrCode::reed_solomon_multiply(y, factor);
779 			}
780 		}
781 		result
782 	}
783 
784 
785 	// Returns the product of the two given field elements modulo GF(2^8/0x11D).
786 	// All inputs are valid. This could be implemented as a 256*256 lookup table.
reed_solomon_multiply(x: u8, y: u8) -> u8787 	fn reed_solomon_multiply(x: u8, y: u8) -> u8 {
788 		// Russian peasant multiplication
789 		let mut z: u8 = 0;
790 		for i in (0 .. 8).rev() {
791 			z = (z << 1) ^ ((z >> 7) * 0x1D);
792 			z ^= ((y >> i) & 1) * x;
793 		}
794 		z
795 	}
796 
797 }
798 
799 
800 /*---- Helper struct for get_penalty_score() ----*/
801 
802 struct FinderPenalty {
803 	qr_size: i32,
804 	run_history: [i32; 7],
805 }
806 
807 
808 impl FinderPenalty {
809 
new(size: i32) -> Self810 	pub fn new(size: i32) -> Self {
811 		Self {
812 			qr_size: size,
813 			run_history: [0i32; 7],
814 		}
815 	}
816 
817 
818 	// Pushes the given value to the front and drops the last value.
add_history(&mut self, mut currentrunlength: i32)819 	pub fn add_history(&mut self, mut currentrunlength: i32) {
820 		if self.run_history[0] == 0 {
821 			currentrunlength += self.qr_size;  // Add light border to initial run
822 		}
823 		let rh = &mut self.run_history;
824 		for i in (0 .. rh.len()-1).rev() {
825 			rh[i + 1] = rh[i];
826 		}
827 		rh[0] = currentrunlength;
828 	}
829 
830 
831 	// Can only be called immediately after a light run is added, and returns either 0, 1, or 2.
count_patterns(&self) -> i32832 	pub fn count_patterns(&self) -> i32 {
833 		let rh = &self.run_history;
834 		let n = rh[1];
835 		assert!(n <= self.qr_size * 3);
836 		let core = n > 0 && rh[2] == n && rh[3] == n * 3 && rh[4] == n && rh[5] == n;
837 		( i32::from(core && rh[0] >= n * 4 && rh[6] >= n)
838 		+ i32::from(core && rh[6] >= n * 4 && rh[0] >= n))
839 	}
840 
841 
842 	// Must be called at the end of a line (row or column) of modules.
terminate_and_count(mut self, currentruncolor: bool, mut currentrunlength: i32) -> i32843 	pub fn terminate_and_count(mut self, currentruncolor: bool, mut currentrunlength: i32) -> i32 {
844 		if currentruncolor {  // Terminate dark run
845 			self.add_history(currentrunlength);
846 			currentrunlength = 0;
847 		}
848 		currentrunlength += self.qr_size;  // Add light border to final run
849 		self.add_history(currentrunlength);
850 		self.count_patterns()
851 	}
852 
853 }
854 
855 
856 /*---- Constants and tables ----*/
857 
858 // For use in get_penalty_score(), when evaluating which mask is best.
859 const PENALTY_N1: i32 =  3;
860 const PENALTY_N2: i32 =  3;
861 const PENALTY_N3: i32 = 40;
862 const PENALTY_N4: i32 = 10;
863 
864 
865 static ECC_CODEWORDS_PER_BLOCK: [[i8; 41]; 4] = [
866 	// Version: (note that index 0 is for padding, and is set to an illegal value)
867 	//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
868 	[-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
869 	[-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
870 	[-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
871 	[-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
872 ];
873 
874 static NUM_ERROR_CORRECTION_BLOCKS: [[i8; 41]; 4] = [
875 	// Version: (note that index 0 is for padding, and is set to an illegal value)
876 	//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
877 	[-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
878 	[-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
879 	[-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
880 	[-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
881 ];
882 
883 
884 
885 /*---- QrCodeEcc functionality ----*/
886 
887 /// The error correction level in a QR Code symbol.
888 #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug)]
889 pub enum QrCodeEcc {
890 	/// The QR Code can tolerate about  7% erroneous codewords.
891 	Low     ,
892 	/// The QR Code can tolerate about 15% erroneous codewords.
893 	Medium  ,
894 	/// The QR Code can tolerate about 25% erroneous codewords.
895 	Quartile,
896 	/// The QR Code can tolerate about 30% erroneous codewords.
897 	High    ,
898 }
899 
900 
901 impl QrCodeEcc {
902 
903 	// Returns an unsigned 2-bit integer (in the range 0 to 3).
ordinal(self) -> usize904 	fn ordinal(self) -> usize {
905 		use QrCodeEcc::*;
906 		match self {
907 			Low      => 0,
908 			Medium   => 1,
909 			Quartile => 2,
910 			High     => 3,
911 		}
912 	}
913 
914 
915 	// Returns an unsigned 2-bit integer (in the range 0 to 3).
format_bits(self) -> u8916 	fn format_bits(self) -> u8 {
917 		use QrCodeEcc::*;
918 		match self {
919 			Low      => 1,
920 			Medium   => 0,
921 			Quartile => 3,
922 			High     => 2,
923 		}
924 	}
925 
926 }
927 
928 
929 
930 /*---- QrSegment functionality ----*/
931 
932 /// A segment of character/binary/control data in a QR Code symbol.
933 ///
934 /// Instances of this struct are immutable.
935 ///
936 /// The mid-level way to create a segment is to take the payload data
937 /// and call a static factory function such as `QrSegment::make_numeric()`.
938 /// The low-level way to create a segment is to custom-make the bit buffer
939 /// and call the `QrSegment::new()` constructor with appropriate values.
940 ///
941 /// This segment struct imposes no length restrictions, but QR Codes have restrictions.
942 /// Even in the most favorable conditions, a QR Code can only hold 7089 characters of data.
943 /// Any segment longer than this is meaningless for the purpose of generating QR Codes.
944 #[derive(Clone, PartialEq, Eq)]
945 pub struct QrSegment {
946 
947 	// The mode indicator of this segment. Accessed through mode().
948 	mode: QrSegmentMode,
949 
950 	// The length of this segment's unencoded data. Measured in characters for
951 	// numeric/alphanumeric/kanji mode, bytes for byte mode, and 0 for ECI mode.
952 	// Not the same as the data's bit length. Accessed through num_chars().
953 	numchars: usize,
954 
955 	// The data bits of this segment. Accessed through data().
956 	data: Vec<bool>,
957 
958 }
959 
960 
961 impl QrSegment {
962 
963 	/*---- Static factory functions (mid level) ----*/
964 
965 	/// Returns a segment representing the given binary data encoded in byte mode.
966 	///
967 	/// All input byte slices are acceptable.
968 	///
969 	/// Any text string can be converted to UTF-8 bytes and encoded as a byte mode segment.
make_bytes(data: &[u8]) -> Self970 	pub fn make_bytes(data: &[u8]) -> Self {
971 		let mut bb = BitBuffer(Vec::with_capacity(data.len() * 8));
972 		for &b in data {
973 			bb.append_bits(u32::from(b), 8);
974 		}
975 		QrSegment::new(QrSegmentMode::Byte, data.len(), bb.0)
976 	}
977 
978 
979 	/// Returns a segment representing the given string of decimal digits encoded in numeric mode.
980 	///
981 	/// Panics if the string contains non-digit characters.
make_numeric(text: &[char]) -> Self982 	pub fn make_numeric(text: &[char]) -> Self {
983 		let mut bb = BitBuffer(Vec::with_capacity(text.len() * 3 + (text.len() + 2) / 3));
984 		let mut accumdata: u32 = 0;
985 		let mut accumcount: u8 = 0;
986 		for &c in text {
987 			assert!('0' <= c && c <= '9', "String contains non-numeric characters");
988 			accumdata = accumdata * 10 + (u32::from(c) - u32::from('0'));
989 			accumcount += 1;
990 			if accumcount == 3 {
991 				bb.append_bits(accumdata, 10);
992 				accumdata = 0;
993 				accumcount = 0;
994 			}
995 		}
996 		if accumcount > 0 {  // 1 or 2 digits remaining
997 			bb.append_bits(accumdata, accumcount * 3 + 1);
998 		}
999 		QrSegment::new(QrSegmentMode::Numeric, text.len(), bb.0)
1000 	}
1001 
1002 
1003 	/// Returns a segment representing the given text string encoded in alphanumeric mode.
1004 	///
1005 	/// The characters allowed are: 0 to 9, A to Z (uppercase only), space,
1006 	/// dollar, percent, asterisk, plus, hyphen, period, slash, colon.
1007 	///
1008 	/// Panics if the string contains non-encodable characters.
make_alphanumeric(text: &[char]) -> Self1009 	pub fn make_alphanumeric(text: &[char]) -> Self {
1010 		let mut bb = BitBuffer(Vec::with_capacity(text.len() * 5 + (text.len() + 1) / 2));
1011 		let mut accumdata: u32 = 0;
1012 		let mut accumcount: u32 = 0;
1013 		for &c in text {
1014 			let i: usize = ALPHANUMERIC_CHARSET.iter().position(|&x| x == c)
1015 				.expect("String contains unencodable characters in alphanumeric mode");
1016 			accumdata = accumdata * 45 + (i as u32);
1017 			accumcount += 1;
1018 			if accumcount == 2 {
1019 				bb.append_bits(accumdata, 11);
1020 				accumdata = 0;
1021 				accumcount = 0;
1022 			}
1023 		}
1024 		if accumcount > 0 {  // 1 character remaining
1025 			bb.append_bits(accumdata, 6);
1026 		}
1027 		QrSegment::new(QrSegmentMode::Alphanumeric, text.len(), bb.0)
1028 	}
1029 
1030 
1031 	/// Returns a list of zero or more segments to represent the given Unicode text string.
1032 	///
1033 	/// The result may use various segment modes and switch
1034 	/// modes to optimize the length of the bit stream.
make_segments(text: &[char]) -> Vec<Self>1035 	pub fn make_segments(text: &[char]) -> Vec<Self> {
1036 		if text.is_empty() {
1037 			vec![]
1038 		} else if QrSegment::is_numeric(text) {
1039 			vec![QrSegment::make_numeric(text)]
1040 		} else if QrSegment::is_alphanumeric(text) {
1041 			vec![QrSegment::make_alphanumeric(text)]
1042 		} else {
1043 			let s: String = text.iter().cloned().collect();
1044 			vec![QrSegment::make_bytes(s.as_bytes())]
1045 		}
1046 	}
1047 
1048 
1049 	/// Returns a segment representing an Extended Channel Interpretation
1050 	/// (ECI) designator with the given assignment value.
make_eci(assignval: u32) -> Self1051 	pub fn make_eci(assignval: u32) -> Self {
1052 		let mut bb = BitBuffer(Vec::with_capacity(24));
1053 		if assignval < (1 << 7) {
1054 			bb.append_bits(assignval, 8);
1055 		} else if assignval < (1 << 14) {
1056 			bb.append_bits(2, 2);
1057 			bb.append_bits(assignval, 14);
1058 		} else if assignval < 1_000_000 {
1059 			bb.append_bits(6, 3);
1060 			bb.append_bits(assignval, 21);
1061 		} else {
1062 			panic!("ECI assignment value out of range");
1063 		}
1064 		QrSegment::new(QrSegmentMode::Eci, 0, bb.0)
1065 	}
1066 
1067 
1068 	/*---- Constructor (low level) ----*/
1069 
1070 	/// Creates a new QR Code segment with the given attributes and data.
1071 	///
1072 	/// The character count (numchars) must agree with the mode and
1073 	/// the bit buffer length, but the constraint isn't checked.
new(mode: QrSegmentMode, numchars: usize, data: Vec<bool>) -> Self1074 	pub fn new(mode: QrSegmentMode, numchars: usize, data: Vec<bool>) -> Self {
1075 		Self { mode, numchars, data }
1076 	}
1077 
1078 
1079 	/*---- Instance field getters ----*/
1080 
1081 	/// Returns the mode indicator of this segment.
mode(&self) -> QrSegmentMode1082 	pub fn mode(&self) -> QrSegmentMode {
1083 		self.mode
1084 	}
1085 
1086 
1087 	/// Returns the character count field of this segment.
num_chars(&self) -> usize1088 	pub fn num_chars(&self) -> usize {
1089 		self.numchars
1090 	}
1091 
1092 
1093 	/// Returns the data bits of this segment.
data(&self) -> &Vec<bool>1094 	pub fn data(&self) -> &Vec<bool> {
1095 		&self.data
1096 	}
1097 
1098 
1099 	/*---- Other static functions ----*/
1100 
1101 	// Calculates and returns the number of bits needed to encode the given
1102 	// segments at the given version. The result is None if a segment has too many
1103 	// characters to fit its length field, or the total bits exceeds usize::MAX.
get_total_bits(segs: &[Self], version: Version) -> Option<usize>1104 	fn get_total_bits(segs: &[Self], version: Version) -> Option<usize> {
1105 		let mut result: usize = 0;
1106 		for seg in segs {
1107 			let ccbits: u8 = seg.mode.num_char_count_bits(version);
1108 			// ccbits can be as large as 16, but usize can be as small as 16
1109 			if let Some(limit) = 1usize.checked_shl(u32::from(ccbits)) {
1110 				if seg.numchars >= limit {
1111 					return None;  // The segment's length doesn't fit the field's bit width
1112 				}
1113 			}
1114 			result = result.checked_add(4 + usize::from(ccbits))?;
1115 			result = result.checked_add(seg.data.len())?;
1116 		}
1117 		Some(result)
1118 	}
1119 
1120 
1121 	/// Tests whether the given string can be encoded as a segment in numeric mode.
1122 	///
1123 	/// A string is encodable iff each character is in the range 0 to 9.
is_numeric(text: &[char]) -> bool1124 	pub fn is_numeric(text: &[char]) -> bool {
1125 		text.iter().all(|&c| '0' <= c && c <= '9')
1126 	}
1127 
1128 
1129 	/// Tests whether the given string can be encoded as a segment in alphanumeric mode.
1130 	///
1131 	/// A string is encodable iff each character is in the following set: 0 to 9, A to Z
1132 	/// (uppercase only), space, dollar, percent, asterisk, plus, hyphen, period, slash, colon.
is_alphanumeric(text: &[char]) -> bool1133 	pub fn is_alphanumeric(text: &[char]) -> bool {
1134 		text.iter().all(|c| ALPHANUMERIC_CHARSET.contains(c))
1135 	}
1136 
1137 }
1138 
1139 
1140 // The set of all legal characters in alphanumeric mode,
1141 // where each character value maps to the index in the string.
1142 static ALPHANUMERIC_CHARSET: [char; 45] = ['0','1','2','3','4','5','6','7','8','9',
1143 	'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z',
1144 	' ','$','%','*','+','-','.','/',':'];
1145 
1146 
1147 
1148 /*---- QrSegmentMode functionality ----*/
1149 
1150 /// Describes how a segment's data bits are interpreted.
1151 #[derive(Clone, Copy, PartialEq, Eq, Debug)]
1152 pub enum QrSegmentMode {
1153 	Numeric,
1154 	Alphanumeric,
1155 	Byte,
1156 	Kanji,
1157 	Eci,
1158 }
1159 
1160 
1161 impl QrSegmentMode {
1162 
1163 	// Returns an unsigned 4-bit integer value (range 0 to 15)
1164 	// representing the mode indicator bits for this mode object.
mode_bits(self) -> u321165 	fn mode_bits(self) -> u32 {
1166 		use QrSegmentMode::*;
1167 		match self {
1168 			Numeric      => 0x1,
1169 			Alphanumeric => 0x2,
1170 			Byte         => 0x4,
1171 			Kanji        => 0x8,
1172 			Eci          => 0x7,
1173 		}
1174 	}
1175 
1176 
1177 	// Returns the bit width of the character count field for a segment in this mode
1178 	// in a QR Code at the given version number. The result is in the range [0, 16].
num_char_count_bits(self, ver: Version) -> u81179 	fn num_char_count_bits(self, ver: Version) -> u8 {
1180 		use QrSegmentMode::*;
1181 		(match self {
1182 			Numeric      => [10, 12, 14],
1183 			Alphanumeric => [ 9, 11, 13],
1184 			Byte         => [ 8, 16, 16],
1185 			Kanji        => [ 8, 10, 12],
1186 			Eci          => [ 0,  0,  0],
1187 		})[usize::from((ver.value() + 7) / 17)]
1188 	}
1189 
1190 }
1191 
1192 
1193 
1194 /*---- Bit buffer functionality ----*/
1195 
1196 /// An appendable sequence of bits (0s and 1s).
1197 ///
1198 /// Mainly used by QrSegment.
1199 pub struct BitBuffer(pub Vec<bool>);
1200 
1201 
1202 impl BitBuffer {
1203 	/// Appends the given number of low-order bits of the given value to this buffer.
1204 	///
1205 	/// Requires len &#x2264; 31 and val &lt; 2<sup>len</sup>.
append_bits(&mut self, val: u32, len: u8)1206 	pub fn append_bits(&mut self, val: u32, len: u8) {
1207 		assert!(len <= 31 && (val >> len) == 0, "Value out of range");
1208 		self.0.extend((0 .. i32::from(len)).rev().map(|i| get_bit(val, i)));  // Append bit by bit
1209 	}
1210 }
1211 
1212 
1213 
1214 /*---- Miscellaneous values ----*/
1215 
1216 /// The error type when the supplied data does not fit any QR Code version.
1217 ///
1218 /// Ways to handle this exception include:
1219 ///
1220 /// - Decrease the error correction level if it was greater than `QrCodeEcc::Low`.
1221 /// - If the `encode_segments_advanced()` function was called, then increase the maxversion
1222 ///   argument if it was less than `Version::MAX`. (This advice does not apply to the
1223 ///   other factory functions because they search all versions up to `Version::MAX`.)
1224 /// - Split the text data into better or optimal segments in order to reduce the number of bits required.
1225 /// - Change the text or binary data to be shorter.
1226 /// - Change the text to fit the character set of a particular segment mode (e.g. alphanumeric).
1227 /// - Propagate the error upward to the caller/user.
1228 #[derive(Debug, Clone)]
1229 pub struct DataTooLong(String);
1230 
1231 impl std::error::Error for DataTooLong {
description(&self) -> &str1232 	fn description(&self) -> &str {
1233 		&self.0
1234 	}
1235 }
1236 
1237 impl std::fmt::Display for DataTooLong {
fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result1238 	fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
1239 		f.write_str(&self.0)
1240 	}
1241 }
1242 
1243 
1244 /// A number between 1 and 40 (inclusive).
1245 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug)]
1246 pub struct Version(u8);
1247 
1248 impl Version {
1249 	/// The minimum version number supported in the QR Code Model 2 standard.
1250 	pub const MIN: Version = Version( 1);
1251 
1252 	/// The maximum version number supported in the QR Code Model 2 standard.
1253 	pub const MAX: Version = Version(40);
1254 
1255 	/// Creates a version object from the given number.
1256 	///
1257 	/// Panics if the number is outside the range [1, 40].
new(ver: u8) -> Self1258 	pub fn new(ver: u8) -> Self {
1259 		assert!(Version::MIN.value() <= ver && ver <= Version::MAX.value(), "Version number out of range");
1260 		Self(ver)
1261 	}
1262 
1263 	/// Returns the value, which is in the range [1, 40].
value(self) -> u81264 	pub fn value(self) -> u8 {
1265 		self.0
1266 	}
1267 }
1268 
1269 
1270 /// A number between 0 and 7 (inclusive).
1271 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug)]
1272 pub struct Mask(u8);
1273 
1274 impl Mask {
1275 	/// Creates a mask object from the given number.
1276 	///
1277 	/// Panics if the number is outside the range [0, 7].
new(mask: u8) -> Self1278 	pub fn new(mask: u8) -> Self {
1279 		assert!(mask <= 7, "Mask value out of range");
1280 		Self(mask)
1281 	}
1282 
1283 	/// Returns the value, which is in the range [0, 7].
value(self) -> u81284 	pub fn value(self) -> u8 {
1285 		self.0
1286 	}
1287 }
1288 
1289 
1290 // Returns true iff the i'th bit of x is set to 1.
get_bit(x: u32, i: i32) -> bool1291 fn get_bit(x: u32, i: i32) -> bool {
1292 	(x >> i) & 1 != 0
1293 }
1294