Skip to main content

qrcode_rs/
bits.rs

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