Skip to main content

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