1#![allow(clippy::unreadable_literal, clippy::unusual_byte_groupings)]
2use 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
23pub struct Bits {
28 data: Vec<u8>,
29 bit_offset: usize,
30 version: Version,
31}
32
33impl Bits {
34 pub const fn new(version: Version) -> Self {
36 Self { data: Vec::new(), bit_offset: 0, version }
37 }
38
39 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 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 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 pub fn into_bytes(self) -> Vec<u8> {
94 self.data
95 }
96
97 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 pub fn is_empty(&self) -> bool {
104 self.data.is_empty()
105 }
106
107 pub fn max_len(&self, ec_level: EcLevel) -> QrResult<usize> {
116 self.version.fetch(ec_level, &DATA_LENGTHS)
117 }
118
119 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); bits.push_number(3, 0b110); bits.push_number(3, 0b101); bits.push_number(7, 0b001_1010); bits.push_number(4, 0b1100); bits.push_number(12, 0b1011_0110_1101); bits.push_number(10, 0b01_1001_0001); bits.push_number(15, 0b111_0010_1110_0011); let bytes = bits.into_bytes();
139
140 assert_eq!(
141 bytes,
142 vec![
143 0b010_110_10, 0b1_001_1010, 0b1100_1011, 0b0110_1101, 0b01_1001_00, 0b01_111_001, 0b0_1110_001, 0b1_0000000, ]
152 );
153}
154
155#[derive(Copy, Clone)]
162pub enum ExtendedMode {
163 Eci,
165
166 Data(Mode),
168
169 Fnc1First,
171
172 Fnc1Second,
174
175 StructuredAppend,
177}
178
179impl Bits {
180 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
209impl Bits {
214 pub fn push_eci_designator(&mut self, eci_designator: u32) -> QrResult<()> {
252 self.reserve(12); 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
312impl 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 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#[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 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
464impl Bits {
469 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
522impl Bits {
527 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
575impl Bits {
580 pub fn push_fnc1_first_position(&mut self) -> QrResult<()> {
600 self.push_mode_indicator(ExtendedMode::Fnc1First)
601 }
602
603 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
635static DATA_LENGTHS: [[usize; 4]; 44] = [
641 [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 [20, 0, 0, 0],
684 [40, 32, 0, 0],
685 [84, 68, 0, 0],
686 [128, 112, 80, 0],
687];
688
689impl Bits {
690 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
793impl Bits {
798 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 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
870pub fn data_capacity_bits(version: Version, ec_level: EcLevel) -> QrResult<usize> {
883 version.fetch(ec_level, &DATA_LENGTHS)
884}
885
886pub 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
913pub 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
946fn 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 base = if DATA_LENGTHS[mid][ec_level as usize] > length { base } else { mid };
958 size -= half;
959 }
960 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