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