qrcodegen/
lib.rs

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)]
89use 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)]
114pub 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
146impl 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.
159	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.
173	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.
192	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.
211	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.
285	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].
331	pub fn version(&self) -> Version {
332		self.version
333	}
334	
335	
336	/// Returns this QR Code's size, in the range [21, 177].
337	pub fn size(&self) -> i32 {
338		self.size
339	}
340	
341	
342	/// Returns this QR Code's error correction level.
343	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].
349	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.
359	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.
365	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.
371	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.
379	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.
412	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.
450	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.
479	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.
495	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.
506	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.
516	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.
560	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.
594	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.
616	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.
698	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.
718	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.
736	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.
744	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.
777	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.
792	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
807struct FinderPenalty {
808	qr_size: i32,
809	run_history: [i32; 7],
810}
811
812
813impl FinderPenalty {
814	
815	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.
824	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.
837	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.
848	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.
864const PENALTY_N1: i32 =  3;
865const PENALTY_N2: i32 =  3;
866const PENALTY_N3: i32 = 40;
867const PENALTY_N4: i32 = 10;
868
869
870static 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
879static 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)]
894pub 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
906impl QrCodeEcc {
907	
908	// Returns an unsigned 2-bit integer (in the range 0 to 3).
909	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).
921	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)]
950pub 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
966impl 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.
975	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.
987	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.
1014	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.
1040	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.
1059	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.
1082	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.
1090	pub fn mode(&self) -> QrSegmentMode {
1091		self.mode
1092	}
1093	
1094	
1095	/// Returns the character count field of this segment.
1096	pub fn num_chars(&self) -> usize {
1097		self.numchars
1098	}
1099	
1100	
1101	/// Returns the data bits of this segment.
1102	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.
1112	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.
1132	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.
1141	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.
1150static 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)]
1158pub enum QrSegmentMode {
1159	Numeric,
1160	Alphanumeric,
1161	Byte,
1162	Kanji,
1163	Eci,
1164}
1165
1166
1167impl QrSegmentMode {
1168	
1169	// Returns an unsigned 4-bit integer value (range 0 to 15)
1170	// representing the mode indicator bits for this mode object.
1171	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].
1185	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.
1205pub struct BitBuffer(pub Vec<bool>);
1206
1207
1208impl 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>.
1212	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)]
1235pub enum DataTooLong {
1236	SegmentTooLong,
1237	DataOverCapacity(usize, usize),
1238}
1239
1240impl std::error::Error for DataTooLong {}
1241
1242impl std::fmt::Display for DataTooLong {
1243	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)]
1255pub struct Version(u8);
1256
1257impl 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].
1267	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].
1273	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)]
1281pub struct Mask(u8);
1282
1283impl Mask {
1284	/// Creates a mask object from the given number.
1285	/// 
1286	/// Panics if the number is outside the range [0, 7].
1287	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].
1293	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.
1300fn get_bit(x: u32, i: i32) -> bool {
1301	(x >> i) & 1 != 0
1302}