qrcode_rs/
bits.rs

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