qrcodegen_no_heap/
lib.rs

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