qrcode/
bits.rs

1//! The `bits` module encodes binary data into raw bits used in a QR code.
2
3use std::cmp::min;
4
5#[cfg(feature = "bench")]
6extern crate test;
7
8use crate::cast::{As, Truncate};
9use crate::optimize::{total_encoded_len, Optimizer, Parser, Segment};
10use crate::types::{EcLevel, Mode, QrError, QrResult, Version};
11
12//------------------------------------------------------------------------------
13//{{{ Bits
14
15/// The `Bits` structure stores the encoded data for a QR code.
16pub struct Bits {
17    data: Vec<u8>,
18    bit_offset: usize,
19    version: Version,
20}
21
22impl Bits {
23    /// Constructs a new, empty bits structure.
24    pub fn new(version: Version) -> Self {
25        Self { data: Vec::new(), bit_offset: 0, version }
26    }
27
28    /// Pushes an N-bit big-endian integer to the end of the bits.
29    ///
30    /// Note: It is up to the developer to ensure that `number` really only is
31    /// `n` bit in size. Otherwise the excess bits may stomp on the existing
32    /// ones.
33    fn push_number(&mut self, n: usize, number: u16) {
34        debug_assert!(n == 16 || n < 16 && number < (1 << n), "{number} is too big as a {n}-bit number");
35
36        let b = self.bit_offset + n;
37        let last_index = self.data.len().wrapping_sub(1);
38        match (self.bit_offset, b) {
39            (0, 0..=8) => {
40                self.data.push((number << (8 - b)).truncate_as_u8());
41            }
42            (0, _) => {
43                self.data.push((number >> (b - 8)).truncate_as_u8());
44                self.data.push((number << (16 - b)).truncate_as_u8());
45            }
46            (_, 0..=8) => {
47                self.data[last_index] |= (number << (8 - b)).truncate_as_u8();
48            }
49            (_, 9..=16) => {
50                self.data[last_index] |= (number >> (b - 8)).truncate_as_u8();
51                self.data.push((number << (16 - b)).truncate_as_u8());
52            }
53            _ => {
54                self.data[last_index] |= (number >> (b - 8)).truncate_as_u8();
55                self.data.push((number >> (b - 16)).truncate_as_u8());
56                self.data.push((number << (24 - b)).truncate_as_u8());
57            }
58        }
59        self.bit_offset = b & 7;
60    }
61
62    /// Pushes an N-bit big-endian integer to the end of the bits, and check
63    /// that the number does not overflow the bits.
64    ///
65    /// Returns `Err(QrError::DataTooLong)` on overflow.
66    fn push_number_checked(&mut self, n: usize, number: usize) -> QrResult<()> {
67        if n > 16 || number >= (1 << n) {
68            Err(QrError::DataTooLong)
69        } else {
70            self.push_number(n, number.as_u16());
71            Ok(())
72        }
73    }
74
75    /// Reserves `n` extra bits of space for pushing.
76    fn reserve(&mut self, n: usize) {
77        let extra_bytes = (n + (8 - self.bit_offset) % 8) / 8;
78        self.data.reserve(extra_bytes);
79    }
80
81    /// Convert the bits into a bytes vector.
82    pub fn into_bytes(self) -> Vec<u8> {
83        self.data
84    }
85
86    /// Total number of bits currently pushed.
87    pub fn len(&self) -> usize {
88        if self.bit_offset == 0 {
89            self.data.len() * 8
90        } else {
91            (self.data.len() - 1) * 8 + self.bit_offset
92        }
93    }
94
95    /// Whether there are any bits pushed.
96    pub fn is_empty(&self) -> bool {
97        self.data.is_empty()
98    }
99
100    /// The maximum number of bits allowed by the provided QR code version and
101    /// error correction level.
102    ///
103    /// # Errors
104    ///
105    /// Returns `Err(QrError::InvalidVersion)` if it is not valid to use the
106    /// `ec_level` for the given version (e.g. `Version::Micro(1)` with
107    /// `EcLevel::H`).
108    pub fn max_len(&self, ec_level: EcLevel) -> QrResult<usize> {
109        self.version.fetch(ec_level, &DATA_LENGTHS)
110    }
111
112    /// Version of the QR code.
113    pub fn version(&self) -> Version {
114        self.version
115    }
116}
117
118#[test]
119fn test_push_number() {
120    let mut bits = Bits::new(Version::Normal(1));
121
122    bits.push_number(3, 0b010); // 0:0 .. 0:3
123    bits.push_number(3, 0b110); // 0:3 .. 0:6
124    bits.push_number(3, 0b101); // 0:6 .. 1:1
125    bits.push_number(7, 0b001_1010); // 1:1 .. 2:0
126    bits.push_number(4, 0b1100); // 2:0 .. 2:4
127    bits.push_number(12, 0b1011_0110_1101); // 2:4 .. 4:0
128    bits.push_number(10, 0b01_1001_0001); // 4:0 .. 5:2
129    bits.push_number(15, 0b111_0010_1110_0011); // 5:2 .. 7:1
130
131    let bytes = bits.into_bytes();
132
133    assert_eq!(
134        bytes,
135        vec![
136            0b010__110__10, // 90
137            0b1__001_1010,  // 154
138            0b1100__1011,   // 203
139            0b0110_1101,    // 109
140            0b01_1001_00,   // 100
141            0b01__111_001,  // 121
142            0b0_1110_001,   // 113
143            0b1__0000000,   // 128
144        ]
145    );
146}
147
148#[cfg(feature = "bench")]
149#[bench]
150fn bench_push_splitted_bytes(bencher: &mut test::Bencher) {
151    bencher.iter(|| {
152        let mut bits = Bits::new(Version::Normal(40));
153        bits.push_number(4, 0b0101);
154        for _ in 0..1024 {
155            bits.push_number(8, 0b10101010);
156        }
157        bits.into_bytes()
158    });
159}
160
161//}}}
162//------------------------------------------------------------------------------
163//{{{ Mode indicator
164
165/// An "extended" mode indicator, includes all indicators supported by QR code
166/// beyond those bearing data.
167#[derive(Copy, Clone)]
168pub enum ExtendedMode {
169    /// ECI mode indicator, to introduce an ECI designator.
170    Eci,
171
172    /// The normal mode to introduce data.
173    Data(Mode),
174
175    /// FNC-1 mode in the first position.
176    Fnc1First,
177
178    /// FNC-1 mode in the second position.
179    Fnc1Second,
180
181    /// Structured append.
182    StructuredAppend,
183}
184
185impl Bits {
186    /// Push the mode indicator to the end of the bits.
187    ///
188    /// # Errors
189    ///
190    /// If the mode is not supported in the provided version, this method
191    /// returns `Err(QrError::UnsupportedCharacterSet)`.
192    pub fn push_mode_indicator(&mut self, mode: ExtendedMode) -> QrResult<()> {
193        #[allow(clippy::match_same_arms)]
194        let number = match (self.version, mode) {
195            (Version::Micro(1), ExtendedMode::Data(Mode::Numeric)) => return Ok(()),
196            (Version::Micro(_), ExtendedMode::Data(Mode::Numeric)) => 0,
197            (Version::Micro(_), ExtendedMode::Data(Mode::Alphanumeric)) => 1,
198            (Version::Micro(_), ExtendedMode::Data(Mode::Byte)) => 0b10,
199            (Version::Micro(_), ExtendedMode::Data(Mode::Kanji)) => 0b11,
200            (Version::Micro(_), _) => return Err(QrError::UnsupportedCharacterSet),
201            (_, ExtendedMode::Data(Mode::Numeric)) => 0b0001,
202            (_, ExtendedMode::Data(Mode::Alphanumeric)) => 0b0010,
203            (_, ExtendedMode::Data(Mode::Byte)) => 0b0100,
204            (_, ExtendedMode::Data(Mode::Kanji)) => 0b1000,
205            (_, ExtendedMode::Eci) => 0b0111,
206            (_, ExtendedMode::Fnc1First) => 0b0101,
207            (_, ExtendedMode::Fnc1Second) => 0b1001,
208            (_, ExtendedMode::StructuredAppend) => 0b0011,
209        };
210        let bits = self.version.mode_bits_count();
211        self.push_number_checked(bits, number).or(Err(QrError::UnsupportedCharacterSet))
212    }
213}
214
215//}}}
216//------------------------------------------------------------------------------
217//{{{ ECI
218
219impl Bits {
220    /// Push an ECI (Extended Channel Interpretation) designator to the bits.
221    ///
222    /// An ECI designator is a 6-digit number to specify the character set of
223    /// the following binary data. After calling this method, one could call
224    /// `.push_byte_data()` or similar methods to insert the actual data, e.g.
225    ///
226    ///     #![allow(unused_must_use)]
227    ///
228    ///     use qrcode::bits::Bits;
229    ///     use qrcode::types::Version;
230    ///
231    ///     let mut bits = Bits::new(Version::Normal(1));
232    ///     bits.push_eci_designator(9); // 9 = ISO-8859-7 (Greek).
233    ///     bits.push_byte_data(b"\xa1\xa2\xa3\xa4\xa5"); // ΑΒΓΔΕ
234    ///
235    ///
236    /// The full list of ECI designator values can be found from
237    /// <http://strokescribe.com/en/ECI.html>. Some example values are:
238    ///
239    /// ECI # | Character set
240    /// ------|-------------------------------------
241    /// 3     | ISO-8859-1 (Western European)
242    /// 20    | Shift JIS (Japanese)
243    /// 23    | Windows 1252 (Latin 1) (Western European)
244    /// 25    | UTF-16 Big Endian
245    /// 26    | UTF-8
246    /// 28    | Big 5 (Traditional Chinese)
247    /// 29    | GB-18030 (Simplified Chinese)
248    /// 30    | EUC-KR (Korean)
249    ///
250    /// # Errors
251    ///
252    /// If the QR code version does not support ECI, this method will return
253    /// `Err(QrError::UnsupportedCharacterSet)`.
254    ///
255    /// If the designator is outside of the expected range, this method will
256    /// return `Err(QrError::InvalidECIDesignator)`.
257    pub fn push_eci_designator(&mut self, eci_designator: u32) -> QrResult<()> {
258        self.reserve(12); // assume the common case that eci_designator <= 127.
259        self.push_mode_indicator(ExtendedMode::Eci)?;
260        match eci_designator {
261            0..=127 => {
262                self.push_number(8, eci_designator.as_u16());
263            }
264            128..=16383 => {
265                self.push_number(2, 0b10);
266                self.push_number(14, eci_designator.as_u16());
267            }
268            16384..=999_999 => {
269                self.push_number(3, 0b110);
270                self.push_number(5, (eci_designator >> 16).as_u16());
271                self.push_number(16, (eci_designator & 0xffff).as_u16());
272            }
273            _ => return Err(QrError::InvalidEciDesignator),
274        }
275        Ok(())
276    }
277}
278
279#[cfg(test)]
280mod eci_tests {
281    use crate::bits::Bits;
282    use crate::types::{QrError, Version};
283
284    #[test]
285    fn test_9() {
286        let mut bits = Bits::new(Version::Normal(1));
287        assert_eq!(bits.push_eci_designator(9), Ok(()));
288        assert_eq!(bits.into_bytes(), vec![0b0111__0000, 0b1001__0000]);
289    }
290
291    #[test]
292    fn test_899() {
293        let mut bits = Bits::new(Version::Normal(1));
294        assert_eq!(bits.push_eci_designator(899), Ok(()));
295        assert_eq!(bits.into_bytes(), vec![0b0111__10_00, 0b00111000, 0b0011__0000]);
296    }
297
298    #[test]
299    fn test_999999() {
300        let mut bits = Bits::new(Version::Normal(1));
301        assert_eq!(bits.push_eci_designator(999999), Ok(()));
302        assert_eq!(bits.into_bytes(), vec![0b0111__110_0, 0b11110100, 0b00100011, 0b1111__0000]);
303    }
304
305    #[test]
306    fn test_invalid_designator() {
307        let mut bits = Bits::new(Version::Normal(1));
308        assert_eq!(bits.push_eci_designator(1000000), Err(QrError::InvalidEciDesignator));
309    }
310
311    #[test]
312    fn test_unsupported_character_set() {
313        let mut bits = Bits::new(Version::Micro(4));
314        assert_eq!(bits.push_eci_designator(9), Err(QrError::UnsupportedCharacterSet));
315    }
316}
317
318//}}}
319//------------------------------------------------------------------------------
320//{{{ Mode::Numeric mode
321
322impl Bits {
323    fn push_header(&mut self, mode: Mode, raw_data_len: usize) -> QrResult<()> {
324        let length_bits = mode.length_bits_count(self.version);
325        self.reserve(length_bits + 4 + mode.data_bits_count(raw_data_len));
326        self.push_mode_indicator(ExtendedMode::Data(mode))?;
327        self.push_number_checked(length_bits, raw_data_len)?;
328        Ok(())
329    }
330
331    /// Encodes a numeric string to the bits.
332    ///
333    /// The data should only contain the characters 0 to 9.
334    ///
335    /// # Errors
336    ///
337    /// Returns `Err(QrError::DataTooLong)` on overflow.
338    pub fn push_numeric_data(&mut self, data: &[u8]) -> QrResult<()> {
339        self.push_header(Mode::Numeric, data.len())?;
340        for chunk in data.chunks(3) {
341            let number = chunk.iter().map(|b| u16::from(*b - b'0')).fold(0, |a, b| a * 10 + b);
342            let length = chunk.len() * 3 + 1;
343            self.push_number(length, number);
344        }
345        Ok(())
346    }
347}
348
349#[cfg(test)]
350mod numeric_tests {
351    use crate::bits::Bits;
352    use crate::types::{QrError, Version};
353
354    #[test]
355    fn test_iso_18004_2006_example_1() {
356        let mut bits = Bits::new(Version::Normal(1));
357        assert_eq!(bits.push_numeric_data(b"01234567"), Ok(()));
358        assert_eq!(
359            bits.into_bytes(),
360            vec![0b0001_0000, 0b001000_00, 0b00001100, 0b01010110, 0b01_100001, 0b1__0000000]
361        );
362    }
363
364    #[test]
365    fn test_iso_18004_2000_example_2() {
366        let mut bits = Bits::new(Version::Normal(1));
367        assert_eq!(bits.push_numeric_data(b"0123456789012345"), Ok(()));
368        assert_eq!(
369            bits.into_bytes(),
370            vec![
371                0b0001_0000,
372                0b010000_00,
373                0b00001100,
374                0b01010110,
375                0b01_101010,
376                0b0110_1110,
377                0b000101_00,
378                0b11101010,
379                0b0101__0000,
380            ]
381        );
382    }
383
384    #[test]
385    fn test_iso_18004_2006_example_2() {
386        let mut bits = Bits::new(Version::Micro(3));
387        assert_eq!(bits.push_numeric_data(b"0123456789012345"), Ok(()));
388        assert_eq!(
389            bits.into_bytes(),
390            vec![
391                0b00_10000_0,
392                0b00000110,
393                0b0_0101011,
394                0b001_10101,
395                0b00110_111,
396                0b0000101_0,
397                0b01110101,
398                0b00101__000,
399            ]
400        );
401    }
402
403    #[test]
404    fn test_data_too_long_error() {
405        let mut bits = Bits::new(Version::Micro(1));
406        assert_eq!(bits.push_numeric_data(b"12345678"), Err(QrError::DataTooLong));
407    }
408}
409
410//}}}
411//------------------------------------------------------------------------------
412//{{{ Mode::Alphanumeric mode
413
414/// In QR code `Mode::Alphanumeric` mode, a pair of alphanumeric characters will
415/// be encoded as a base-45 integer. `alphanumeric_digit` converts each
416/// character into its corresponding base-45 digit.
417///
418/// The conversion is specified in ISO/IEC 18004:2006, §8.4.3, Table 5.
419#[inline]
420fn alphanumeric_digit(character: u8) -> u16 {
421    match character {
422        b'0'..=b'9' => u16::from(character - b'0'),
423        b'A'..=b'Z' => u16::from(character - b'A') + 10,
424        b' ' => 36,
425        b'$' => 37,
426        b'%' => 38,
427        b'*' => 39,
428        b'+' => 40,
429        b'-' => 41,
430        b'.' => 42,
431        b'/' => 43,
432        b':' => 44,
433        _ => 0,
434    }
435}
436
437impl Bits {
438    /// Encodes an alphanumeric string to the bits.
439    ///
440    /// The data should only contain the charaters A to Z (excluding lowercase),
441    /// 0 to 9, space, `$`, `%`, `*`, `+`, `-`, `.`, `/` or `:`.
442    ///
443    /// # Errors
444    ///
445    /// Returns `Err(QrError::DataTooLong)` on overflow.
446    pub fn push_alphanumeric_data(&mut self, data: &[u8]) -> QrResult<()> {
447        self.push_header(Mode::Alphanumeric, data.len())?;
448        for chunk in data.chunks(2) {
449            let number = chunk.iter().map(|b| alphanumeric_digit(*b)).fold(0, |a, b| a * 45 + b);
450            let length = chunk.len() * 5 + 1;
451            self.push_number(length, number);
452        }
453        Ok(())
454    }
455}
456
457#[cfg(test)]
458mod alphanumeric_tests {
459    use crate::bits::Bits;
460    use crate::types::{QrError, Version};
461
462    #[test]
463    fn test_iso_18004_2006_example() {
464        let mut bits = Bits::new(Version::Normal(1));
465        assert_eq!(bits.push_alphanumeric_data(b"AC-42"), Ok(()));
466        assert_eq!(
467            bits.into_bytes(),
468            vec![0b0010_0000, 0b00101_001, 0b11001110, 0b11100111, 0b001_00001, 0b0__0000000]
469        );
470    }
471
472    #[test]
473    fn test_micro_qr_unsupported() {
474        let mut bits = Bits::new(Version::Micro(1));
475        assert_eq!(bits.push_alphanumeric_data(b"A"), Err(QrError::UnsupportedCharacterSet));
476    }
477
478    #[test]
479    fn test_data_too_long() {
480        let mut bits = Bits::new(Version::Micro(2));
481        assert_eq!(bits.push_alphanumeric_data(b"ABCDEFGH"), Err(QrError::DataTooLong));
482    }
483}
484
485//}}}
486//------------------------------------------------------------------------------
487//{{{ Mode::Byte mode
488
489impl Bits {
490    /// Encodes 8-bit byte data to the bits.
491    ///
492    /// # Errors
493    ///
494    /// Returns `Err(QrError::DataTooLong)` on overflow.
495    pub fn push_byte_data(&mut self, data: &[u8]) -> QrResult<()> {
496        self.push_header(Mode::Byte, data.len())?;
497        for b in data {
498            self.push_number(8, u16::from(*b));
499        }
500        Ok(())
501    }
502}
503
504#[cfg(test)]
505mod byte_tests {
506    use crate::bits::Bits;
507    use crate::types::{QrError, Version};
508
509    #[test]
510    fn test() {
511        let mut bits = Bits::new(Version::Normal(1));
512        assert_eq!(bits.push_byte_data(b"\x12\x34\x56\x78\x9a\xbc\xde\xf0"), Ok(()));
513        assert_eq!(
514            bits.into_bytes(),
515            vec![
516                0b0100_0000,
517                0b1000_0001,
518                0b0010_0011,
519                0b0100_0101,
520                0b0110_0111,
521                0b1000_1001,
522                0b1010_1011,
523                0b1100_1101,
524                0b1110_1111,
525                0b0000__0000,
526            ]
527        );
528    }
529
530    #[test]
531    fn test_micro_qr_unsupported() {
532        let mut bits = Bits::new(Version::Micro(2));
533        assert_eq!(bits.push_byte_data(b"?"), Err(QrError::UnsupportedCharacterSet));
534    }
535
536    #[test]
537    fn test_data_too_long() {
538        let mut bits = Bits::new(Version::Micro(3));
539        assert_eq!(bits.push_byte_data(b"0123456701234567"), Err(QrError::DataTooLong));
540    }
541}
542
543//}}}
544//------------------------------------------------------------------------------
545//{{{ Mode::Kanji mode
546
547impl Bits {
548    /// Encodes Shift JIS double-byte data to the bits.
549    ///
550    /// # Errors
551    ///
552    /// Returns `Err(QrError::DataTooLong)` on overflow.
553    ///
554    /// Returns `Err(QrError::InvalidCharacter)` if the data is not Shift JIS
555    /// double-byte data (e.g. if the length of data is not an even number).
556    pub fn push_kanji_data(&mut self, data: &[u8]) -> QrResult<()> {
557        self.push_header(Mode::Kanji, data.len() / 2)?;
558        for kanji in data.chunks(2) {
559            if kanji.len() != 2 {
560                return Err(QrError::InvalidCharacter);
561            }
562            let cp = u16::from(kanji[0]) * 256 + u16::from(kanji[1]);
563            let bytes = if cp < 0xe040 { cp - 0x8140 } else { cp - 0xc140 };
564            let number = (bytes >> 8) * 0xc0 + (bytes & 0xff);
565            self.push_number(13, number);
566        }
567        Ok(())
568    }
569}
570
571#[cfg(test)]
572mod kanji_tests {
573    use crate::bits::Bits;
574    use crate::types::{QrError, Version};
575
576    #[test]
577    fn test_iso_18004_example() {
578        let mut bits = Bits::new(Version::Normal(1));
579        assert_eq!(bits.push_kanji_data(b"\x93\x5f\xe4\xaa"), Ok(()));
580        assert_eq!(bits.into_bytes(), vec![0b1000_0000, 0b0010_0110, 0b11001111, 0b1_1101010, 0b101010__00]);
581    }
582
583    #[test]
584    fn test_micro_qr_unsupported() {
585        let mut bits = Bits::new(Version::Micro(2));
586        assert_eq!(bits.push_kanji_data(b"?"), Err(QrError::UnsupportedCharacterSet));
587    }
588
589    #[test]
590    fn test_data_too_long() {
591        let mut bits = Bits::new(Version::Micro(3));
592        assert_eq!(bits.push_kanji_data(b"\x93_\x93_\x93_\x93_\x93_\x93_\x93_\x93_"), Err(QrError::DataTooLong));
593    }
594}
595
596//}}}
597//------------------------------------------------------------------------------
598//{{{ FNC1 mode
599
600impl Bits {
601    /// Encodes an indicator that the following data are formatted according to
602    /// the UCC/EAN Application Identifiers standard.
603    ///
604    ///     #![allow(unused_must_use)]
605    ///
606    ///     use qrcode::bits::Bits;
607    ///     use qrcode::types::Version;
608    ///
609    ///     let mut bits = Bits::new(Version::Normal(1));
610    ///     bits.push_fnc1_first_position();
611    ///     bits.push_numeric_data(b"01049123451234591597033130128");
612    ///     bits.push_alphanumeric_data(b"%10ABC123");
613    ///
614    /// In QR code, the character `%` is used as the data field separator (0x1D).
615    ///
616    /// # Errors
617    ///
618    /// If the mode is not supported in the provided version, this method
619    /// returns `Err(QrError::UnsupportedCharacterSet)`.
620    pub fn push_fnc1_first_position(&mut self) -> QrResult<()> {
621        self.push_mode_indicator(ExtendedMode::Fnc1First)
622    }
623
624    /// Encodes an indicator that the following data are formatted in accordance
625    /// with specific industry or application specifications previously agreed
626    /// with AIM International.
627    ///
628    ///     #![allow(unused_must_use)]
629    ///
630    ///     use qrcode::bits::Bits;
631    ///     use qrcode::types::Version;
632    ///
633    ///     let mut bits = Bits::new(Version::Normal(1));
634    ///     bits.push_fnc1_second_position(37);
635    ///     bits.push_alphanumeric_data(b"AA1234BBB112");
636    ///     bits.push_byte_data(b"text text text text\r");
637    ///
638    /// If the application indicator is a single Latin alphabet (a–z / A–Z),
639    /// please pass in its ASCII value + 100:
640    ///
641    /// ```ignore
642    /// bits.push_fnc1_second_position(b'A' + 100);
643    /// ```
644    ///
645    /// # Errors
646    ///
647    /// If the mode is not supported in the provided version, this method
648    /// returns `Err(QrError::UnsupportedCharacterSet)`.
649    pub fn push_fnc1_second_position(&mut self, application_indicator: u8) -> QrResult<()> {
650        self.push_mode_indicator(ExtendedMode::Fnc1Second)?;
651        self.push_number(8, u16::from(application_indicator));
652        Ok(())
653    }
654}
655
656//}}}
657//------------------------------------------------------------------------------
658//{{{ Finish
659
660// This table is copied from ISO/IEC 18004:2006 §6.4.10, Table 7.
661static DATA_LENGTHS: [[usize; 4]; 44] = [
662    // Normal versions
663    [152, 128, 104, 72],
664    [272, 224, 176, 128],
665    [440, 352, 272, 208],
666    [640, 512, 384, 288],
667    [864, 688, 496, 368],
668    [1088, 864, 608, 480],
669    [1248, 992, 704, 528],
670    [1552, 1232, 880, 688],
671    [1856, 1456, 1056, 800],
672    [2192, 1728, 1232, 976],
673    [2592, 2032, 1440, 1120],
674    [2960, 2320, 1648, 1264],
675    [3424, 2672, 1952, 1440],
676    [3688, 2920, 2088, 1576],
677    [4184, 3320, 2360, 1784],
678    [4712, 3624, 2600, 2024],
679    [5176, 4056, 2936, 2264],
680    [5768, 4504, 3176, 2504],
681    [6360, 5016, 3560, 2728],
682    [6888, 5352, 3880, 3080],
683    [7456, 5712, 4096, 3248],
684    [8048, 6256, 4544, 3536],
685    [8752, 6880, 4912, 3712],
686    [9392, 7312, 5312, 4112],
687    [10208, 8000, 5744, 4304],
688    [10960, 8496, 6032, 4768],
689    [11744, 9024, 6464, 5024],
690    [12248, 9544, 6968, 5288],
691    [13048, 10136, 7288, 5608],
692    [13880, 10984, 7880, 5960],
693    [14744, 11640, 8264, 6344],
694    [15640, 12328, 8920, 6760],
695    [16568, 13048, 9368, 7208],
696    [17528, 13800, 9848, 7688],
697    [18448, 14496, 10288, 7888],
698    [19472, 15312, 10832, 8432],
699    [20528, 15936, 11408, 8768],
700    [21616, 16816, 12016, 9136],
701    [22496, 17728, 12656, 9776],
702    [23648, 18672, 13328, 10208],
703    // Micro versions
704    [20, 0, 0, 0],
705    [40, 32, 0, 0],
706    [84, 68, 0, 0],
707    [128, 112, 80, 0],
708];
709
710impl Bits {
711    /// Pushes the ending bits to indicate no more data.
712    ///
713    /// # Errors
714    ///
715    /// Returns `Err(QrError::DataTooLong)` on overflow.
716    ///
717    /// Returns `Err(QrError::InvalidVersion)` if it is not valid to use the
718    /// `ec_level` for the given version (e.g. `Version::Micro(1)` with
719    /// `EcLevel::H`).
720    pub fn push_terminator(&mut self, ec_level: EcLevel) -> QrResult<()> {
721        let terminator_size = if let Version::Micro(a) = self.version { a.as_usize() * 2 + 1 } else { 4 };
722
723        let cur_length = self.len();
724        let data_length = self.max_len(ec_level)?;
725        if cur_length > data_length {
726            return Err(QrError::DataTooLong);
727        }
728
729        let terminator_size = min(terminator_size, data_length - cur_length);
730        if terminator_size > 0 {
731            self.push_number(terminator_size, 0);
732        }
733
734        if self.len() < data_length {
735            const PADDING_BYTES: &[u8] = &[0b1110_1100, 0b0001_0001];
736
737            self.bit_offset = 0;
738            let data_bytes_length = data_length / 8;
739            let padding_bytes_count = data_bytes_length - self.data.len();
740            let padding = PADDING_BYTES.iter().copied().cycle().take(padding_bytes_count);
741            self.data.extend(padding);
742        }
743
744        if self.len() < data_length {
745            self.data.push(0);
746        }
747
748        Ok(())
749    }
750}
751
752#[cfg(test)]
753mod finish_tests {
754    use crate::bits::Bits;
755    use crate::types::{EcLevel, QrError, Version};
756
757    #[test]
758    fn test_hello_world() {
759        let mut bits = Bits::new(Version::Normal(1));
760        assert_eq!(bits.push_alphanumeric_data(b"HELLO WORLD"), Ok(()));
761        assert_eq!(bits.push_terminator(EcLevel::Q), Ok(()));
762        assert_eq!(
763            bits.into_bytes(),
764            vec![
765                0b00100000, 0b01011011, 0b00001011, 0b01111000, 0b11010001, 0b01110010, 0b11011100, 0b01001101,
766                0b01000011, 0b01000000, 0b11101100, 0b00010001, 0b11101100,
767            ]
768        );
769    }
770
771    #[test]
772    fn test_too_long() {
773        let mut bits = Bits::new(Version::Micro(1));
774        assert_eq!(bits.push_numeric_data(b"9999999"), Ok(()));
775        assert_eq!(bits.push_terminator(EcLevel::L), Err(QrError::DataTooLong));
776    }
777
778    #[test]
779    fn test_no_terminator() {
780        let mut bits = Bits::new(Version::Micro(1));
781        assert_eq!(bits.push_numeric_data(b"99999"), Ok(()));
782        assert_eq!(bits.push_terminator(EcLevel::L), Ok(()));
783        assert_eq!(bits.into_bytes(), vec![0b101_11111, 0b00111_110, 0b0011__0000]);
784    }
785
786    #[test]
787    fn test_no_padding() {
788        let mut bits = Bits::new(Version::Micro(1));
789        assert_eq!(bits.push_numeric_data(b"9999"), Ok(()));
790        assert_eq!(bits.push_terminator(EcLevel::L), Ok(()));
791        assert_eq!(bits.into_bytes(), vec![0b100_11111, 0b00111_100, 0b1_000__0000]);
792    }
793
794    #[test]
795    fn test_micro_version_1_half_byte_padding() {
796        let mut bits = Bits::new(Version::Micro(1));
797        assert_eq!(bits.push_numeric_data(b"999"), Ok(()));
798        assert_eq!(bits.push_terminator(EcLevel::L), Ok(()));
799        assert_eq!(bits.into_bytes(), vec![0b011_11111, 0b00111_000, 0b0000__0000]);
800    }
801
802    #[test]
803    fn test_micro_version_1_full_byte_padding() {
804        let mut bits = Bits::new(Version::Micro(1));
805        assert_eq!(bits.push_numeric_data(b""), Ok(()));
806        assert_eq!(bits.push_terminator(EcLevel::L), Ok(()));
807        assert_eq!(bits.into_bytes(), vec![0b000_000_00, 0b11101100, 0]);
808    }
809}
810
811//}}}
812//------------------------------------------------------------------------------
813//{{{ Front end.
814
815impl Bits {
816    /// Push a segmented data to the bits, and then terminate it.
817    ///
818    /// # Errors
819    ///
820    /// Returns `Err(QrError::DataTooLong)` on overflow.
821    ///
822    /// Returns `Err(QrError::InvalidData)` if the segment refers to incorrectly
823    /// encoded byte sequence.
824    pub fn push_segments<I>(&mut self, data: &[u8], segments_iter: I) -> QrResult<()>
825    where
826        I: Iterator<Item = Segment>,
827    {
828        for segment in segments_iter {
829            let slice = &data[segment.begin..segment.end];
830            match segment.mode {
831                Mode::Numeric => self.push_numeric_data(slice),
832                Mode::Alphanumeric => self.push_alphanumeric_data(slice),
833                Mode::Byte => self.push_byte_data(slice),
834                Mode::Kanji => self.push_kanji_data(slice),
835            }?;
836        }
837        Ok(())
838    }
839
840    /// Pushes the data the bits, using the optimal encoding.
841    ///
842    /// # Errors
843    ///
844    /// Returns `Err(QrError::DataTooLong)` on overflow.
845    pub fn push_optimal_data(&mut self, data: &[u8]) -> QrResult<()> {
846        let segments = Parser::new(data).optimize(self.version);
847        self.push_segments(data, segments)
848    }
849}
850
851#[cfg(test)]
852mod encode_tests {
853    use crate::bits::Bits;
854    use crate::types::{EcLevel, QrError, QrResult, Version};
855
856    fn encode(data: &[u8], version: Version, ec_level: EcLevel) -> QrResult<Vec<u8>> {
857        let mut bits = Bits::new(version);
858        bits.push_optimal_data(data)?;
859        bits.push_terminator(ec_level)?;
860        Ok(bits.into_bytes())
861    }
862
863    #[test]
864    fn test_alphanumeric() {
865        let res = encode(b"HELLO WORLD", Version::Normal(1), EcLevel::Q);
866        assert_eq!(
867            res,
868            Ok(vec![
869                0b00100000, 0b01011011, 0b00001011, 0b01111000, 0b11010001, 0b01110010, 0b11011100, 0b01001101,
870                0b01000011, 0b01000000, 0b11101100, 0b00010001, 0b11101100,
871            ])
872        );
873    }
874
875    #[test]
876    fn test_auto_mode_switch() {
877        let res = encode(b"123A", Version::Micro(2), EcLevel::L);
878        assert_eq!(res, Ok(vec![0b0_0011_000, 0b1111011_1, 0b001_00101, 0b0_00000__00, 0b11101100]));
879    }
880
881    #[test]
882    fn test_too_long() {
883        let res = encode(b">>>>>>>>", Version::Normal(1), EcLevel::H);
884        assert_eq!(res, Err(QrError::DataTooLong));
885    }
886}
887
888//}}}
889//------------------------------------------------------------------------------
890//{{{ Auto version minimization
891
892/// Automatically determines the minimum version to store the data, and encode
893/// the result.
894///
895/// This method will not consider any Micro QR code versions.
896///
897/// # Errors
898///
899/// Returns `Err(QrError::DataTooLong)` if the data is too long to fit even the
900/// highest QR code version.
901#[allow(clippy::missing_panics_doc)] // the panic caused by the expect() will never actually happen since the `version`s are known good constants.
902pub fn encode_auto(data: &[u8], ec_level: EcLevel) -> QrResult<Bits> {
903    let segments = Parser::new(data).collect::<Vec<Segment>>();
904    for version in &[Version::Normal(9), Version::Normal(26), Version::Normal(40)] {
905        let opt_segments = Optimizer::new(segments.iter().copied(), *version).collect::<Vec<_>>();
906        let total_len = total_encoded_len(&opt_segments, *version);
907        let data_capacity = version.fetch(ec_level, &DATA_LENGTHS).expect("invalid DATA_LENGTHS");
908        if total_len <= data_capacity {
909            let min_version = find_min_version(total_len, ec_level);
910            let mut bits = Bits::new(min_version);
911            bits.reserve(total_len);
912            bits.push_segments(data, opt_segments.into_iter())?;
913            bits.push_terminator(ec_level)?;
914            return Ok(bits);
915        }
916    }
917    Err(QrError::DataTooLong)
918}
919
920/// Finds the smallest version (QR code only) that can store N bits of data
921/// in the given error correction level.
922fn find_min_version(length: usize, ec_level: EcLevel) -> Version {
923    let mut base = 0_usize;
924    let mut size = 39;
925    while size > 1 {
926        let half = size / 2;
927        let mid = base + half;
928        // mid is always in [0, size).
929        // mid >= 0: by definition
930        // mid < size: mid = size / 2 + size / 4 + size / 8 ...
931        base = if DATA_LENGTHS[mid][ec_level as usize] > length { base } else { mid };
932        size -= half;
933    }
934    // base is always in [0, mid) because base <= mid.
935    base = if DATA_LENGTHS[base][ec_level as usize] >= length { base } else { base + 1 };
936    Version::Normal((base + 1).as_i16())
937}
938
939#[cfg(test)]
940mod encode_auto_tests {
941    use crate::bits::{encode_auto, find_min_version};
942    use crate::types::{EcLevel, Version};
943
944    #[test]
945    fn test_find_min_version() {
946        assert_eq!(find_min_version(60, EcLevel::L), Version::Normal(1));
947        assert_eq!(find_min_version(200, EcLevel::L), Version::Normal(2));
948        assert_eq!(find_min_version(200, EcLevel::H), Version::Normal(3));
949        assert_eq!(find_min_version(20000, EcLevel::L), Version::Normal(37));
950        assert_eq!(find_min_version(640, EcLevel::L), Version::Normal(4));
951        assert_eq!(find_min_version(641, EcLevel::L), Version::Normal(5));
952        assert_eq!(find_min_version(999999, EcLevel::H), Version::Normal(40));
953    }
954
955    #[test]
956    fn test_alpha_q() {
957        let bits = encode_auto(b"HELLO WORLD", EcLevel::Q).unwrap();
958        assert_eq!(bits.version(), Version::Normal(1));
959    }
960
961    #[test]
962    fn test_alpha_h() {
963        let bits = encode_auto(b"HELLO WORLD", EcLevel::H).unwrap();
964        assert_eq!(bits.version(), Version::Normal(2));
965    }
966
967    #[test]
968    fn test_mixed() {
969        let bits = encode_auto(b"This is a mixed data test. 1234567890", EcLevel::H).unwrap();
970        assert_eq!(bits.version(), Version::Normal(4));
971    }
972}
973
974#[cfg(feature = "bench")]
975#[bench]
976fn bench_find_min_version(bencher: &mut test::Bencher) {
977    use test::black_box;
978
979    bencher.iter(|| {
980        black_box(find_min_version(60, EcLevel::L));
981        black_box(find_min_version(200, EcLevel::L));
982        black_box(find_min_version(200, EcLevel::H));
983        black_box(find_min_version(20000, EcLevel::L));
984        black_box(find_min_version(640, EcLevel::L));
985        black_box(find_min_version(641, EcLevel::L));
986        black_box(find_min_version(999999, EcLevel::H));
987    })
988}
989
990//}}}
991//------------------------------------------------------------------------------