1#![no_std]
93#![forbid(unsafe_code)]
94use core::convert::TryFrom;
95
96
97pub struct QrCode<'a> {
119
120 size: &'a mut u8,
123
124 modules: &'a mut [u8],
127
128}
129
130
131impl<'a> QrCode<'a> {
132
133 pub fn encode_text<'b>(text: &str, tempbuffer: &'b mut [u8], mut outbuffer: &'a mut [u8], ecl: QrCodeEcc,
165 minversion: Version, maxversion: Version, mask: Option<Mask>, boostecl: bool) -> Result<QrCode<'a>,DataTooLong> {
166
167 let minlen: usize = outbuffer.len().min(tempbuffer.len());
168 outbuffer = &mut outbuffer[ .. minlen];
169
170 let textlen: usize = text.len(); if textlen == 0 {
172 let (datacodewordslen, ecl, version) = QrCode::encode_segments_to_codewords(&[], outbuffer, ecl, minversion, maxversion, boostecl)?;
173 return Ok(Self::encode_codewords(outbuffer, datacodewordslen, tempbuffer, ecl, version, mask));
174 }
175
176 use QrSegmentMode::*;
177 let buflen: usize = outbuffer.len();
178 let seg: QrSegment = if QrSegment::is_numeric(text) && QrSegment::calc_buffer_size(Numeric, textlen).map_or(false, |x| x <= buflen) {
179 QrSegment::make_numeric(text, tempbuffer)
180 } else if QrSegment::is_alphanumeric(text) && QrSegment::calc_buffer_size(Alphanumeric, textlen).map_or(false, |x| x <= buflen) {
181 QrSegment::make_alphanumeric(text, tempbuffer)
182 } else if QrSegment::calc_buffer_size(Byte, textlen).map_or(false, |x| x <= buflen) {
183 QrSegment::make_bytes(text.as_bytes())
184 } else {
185 return Err(DataTooLong::SegmentTooLong);
186 };
187 let (datacodewordslen, ecl, version) = QrCode::encode_segments_to_codewords(&[seg], outbuffer, ecl, minversion, maxversion, boostecl)?;
188 Ok(Self::encode_codewords(outbuffer, datacodewordslen, tempbuffer, ecl, version, mask))
189 }
190
191
192 pub fn encode_binary<'b>(dataandtempbuffer: &'b mut [u8], datalen: usize, mut outbuffer: &'a mut [u8], ecl: QrCodeEcc,
221 minversion: Version, maxversion: Version, mask: Option<Mask>, boostecl: bool) -> Result<QrCode<'a>,DataTooLong> {
222
223 assert!(datalen <= dataandtempbuffer.len(), "Invalid data length");
224 let minlen: usize = outbuffer.len().min(dataandtempbuffer.len());
225 outbuffer = &mut outbuffer[ .. minlen];
226
227 if QrSegment::calc_buffer_size(QrSegmentMode::Byte, datalen).map_or(true, |x| x > outbuffer.len()) {
228 return Err(DataTooLong::SegmentTooLong);
229 }
230 let seg: QrSegment = QrSegment::make_bytes(&dataandtempbuffer[ .. datalen]);
231 let (datacodewordslen, ecl, version) = QrCode::encode_segments_to_codewords(&[seg], outbuffer, ecl, minversion, maxversion, boostecl)?;
232 Ok(Self::encode_codewords(outbuffer, datacodewordslen, dataandtempbuffer, ecl, version, mask))
233 }
234
235
236 pub fn encode_segments_to_codewords(segs: &[QrSegment], outbuffer: &'a mut [u8],
251 mut ecl: QrCodeEcc, minversion: Version, maxversion: Version, boostecl: bool)
252 -> Result<(usize,QrCodeEcc,Version),DataTooLong> {
253
254 assert!(minversion <= maxversion, "Invalid value");
255 assert!(outbuffer.len() >= QrCode::get_num_data_codewords(maxversion, ecl), "Invalid buffer length");
256
257 let mut version: Version = minversion;
259 let datausedbits: usize = loop {
260 let datacapacitybits: usize = QrCode::get_num_data_codewords(version, ecl) * 8; let dataused: Option<usize> = QrSegment::get_total_bits(segs, version);
262 if dataused.map_or(false, |n| n <= datacapacitybits) {
263 break dataused.unwrap(); } else if version >= maxversion { return Err(match dataused {
266 None => DataTooLong::SegmentTooLong,
267 Some(n) => DataTooLong::DataOverCapacity(n, datacapacitybits),
268 });
269 } else {
270 version = Version::new(version.value() + 1);
271 }
272 };
273
274 for &newecl in &[QrCodeEcc::Medium, QrCodeEcc::Quartile, QrCodeEcc::High] { if boostecl && datausedbits <= QrCode::get_num_data_codewords(version, newecl) * 8 {
277 ecl = newecl;
278 }
279 }
280
281 let datacapacitybits: usize = QrCode::get_num_data_codewords(version, ecl) * 8;
283 let mut bb = BitBuffer::new(&mut outbuffer[ .. datacapacitybits/8]);
284 for seg in segs {
285 bb.append_bits(seg.mode.mode_bits(), 4);
286 bb.append_bits(u32::try_from(seg.numchars).unwrap(), seg.mode.num_char_count_bits(version));
287 for i in 0 .. seg.bitlength {
288 let bit: u8 = (seg.data[i >> 3] >> (7 - (i & 7))) & 1;
289 bb.append_bits(bit.into(), 1);
290 }
291 }
292 debug_assert_eq!(bb.length, datausedbits);
293
294 let numzerobits: usize = core::cmp::min(4, datacapacitybits - bb.length);
296 bb.append_bits(0, u8::try_from(numzerobits).unwrap());
297 let numzerobits: usize = bb.length.wrapping_neg() & 7;
298 bb.append_bits(0, u8::try_from(numzerobits).unwrap());
299 debug_assert_eq!(bb.length % 8, 0);
300
301 for &padbyte in [0xEC, 0x11].iter().cycle() {
303 if bb.length >= datacapacitybits {
304 break;
305 }
306 bb.append_bits(padbyte, 8);
307 }
308 Ok((bb.length / 8, ecl, version))
309 }
310
311
312 pub fn encode_codewords<'b>(mut datacodewordsandoutbuffer: &'a mut [u8], datacodewordslen: usize, mut tempbuffer: &'b mut [u8],
320 ecl: QrCodeEcc, version: Version, mut msk: Option<Mask>) -> QrCode<'a> {
321
322 datacodewordsandoutbuffer = &mut datacodewordsandoutbuffer[ .. version.buffer_len()];
323 tempbuffer = &mut tempbuffer [ .. version.buffer_len()];
324
325 let rawcodewords: usize = QrCode::get_num_raw_data_modules(version) / 8;
327 assert!(datacodewordslen <= rawcodewords);
328 let (data, temp) = datacodewordsandoutbuffer.split_at_mut(datacodewordslen);
329 let allcodewords = Self::add_ecc_and_interleave(data, version, ecl, temp, tempbuffer);
330
331 let mut result: QrCode = QrCode::<'a>::function_modules_marked(datacodewordsandoutbuffer, version);
333 result.draw_codewords(allcodewords);
334 result.draw_light_function_modules();
335 let funcmods: QrCode = QrCode::<'b>::function_modules_marked(tempbuffer, version); if msk.is_none() { let mut minpenalty = core::i32::MAX;
340 for i in 0u8 .. 8 {
341 let i = Mask::new(i);
342 result.apply_mask(&funcmods, i);
343 result.draw_format_bits(ecl, i);
344 let penalty: i32 = result.get_penalty_score();
345 if penalty < minpenalty {
346 msk = Some(i);
347 minpenalty = penalty;
348 }
349 result.apply_mask(&funcmods, i); }
351 }
352 let msk: Mask = msk.unwrap();
353 result.apply_mask(&funcmods, msk); result.draw_format_bits(ecl, msk); result
356 }
357
358
359 pub fn version(&self) -> Version {
363 Version::new((*self.size - 17) / 4)
364 }
365
366
367 pub fn size(&self) -> i32 {
369 i32::from(*self.size)
370 }
371
372
373 pub fn error_correction_level(&self) -> QrCodeEcc {
375 let index =
376 usize::from(self.get_module_bounded(0, 8)) << 1 |
377 usize::from(self.get_module_bounded(1, 8)) << 0;
378 use QrCodeEcc::*;
379 [Medium, Low, High, Quartile][index]
380 }
381
382
383 pub fn mask(&self) -> Mask {
385 Mask::new(
386 u8::from(self.get_module_bounded(2, 8)) << 2 |
387 u8::from(self.get_module_bounded(3, 8)) << 1 |
388 u8::from(self.get_module_bounded(4, 8)) << 0)
389 }
390
391
392 pub fn get_module(&self, x: i32, y: i32) -> bool {
398 let range = 0 .. self.size();
399 range.contains(&x) && range.contains(&y) && self.get_module_bounded(x as u8, y as u8)
400 }
401
402
403 fn get_module_bounded(&self, x: u8, y: u8) -> bool {
405 let range = 0 .. *self.size;
406 assert!(range.contains(&x) && range.contains(&y));
407 let index = usize::from(y) * usize::from(*self.size) + usize::from(x);
408 let byteindex: usize = index >> 3;
409 let bitindex: usize = index & 7;
410 get_bit(self.modules[byteindex].into(), bitindex as u8)
411 }
412
413
414 fn set_module_unbounded(&mut self, x: i32, y: i32, isdark: bool) {
416 let range = 0 .. self.size();
417 if range.contains(&x) && range.contains(&y) {
418 self.set_module_bounded(x as u8, y as u8, isdark);
419 }
420 }
421
422
423 fn set_module_bounded(&mut self, x: u8, y: u8, isdark: bool) {
425 let range = 0 .. *self.size;
426 assert!(range.contains(&x) && range.contains(&y));
427 let index = usize::from(y) * usize::from(*self.size) + usize::from(x);
428 let byteindex: usize = index >> 3;
429 let bitindex: usize = index & 7;
430 if isdark {
431 self.modules[byteindex] |= 1u8 << bitindex;
432 } else {
433 self.modules[byteindex] &= !(1u8 << bitindex);
434 }
435 }
436
437
438 fn add_ecc_and_interleave<'b>(data: &[u8], ver: Version, ecl: QrCodeEcc, temp: &mut [u8], resultbuf: &'b mut [u8]) -> &'b [u8] {
444 assert_eq!(data.len(), QrCode::get_num_data_codewords(ver, ecl));
445
446 let numblocks: usize = QrCode::table_get(&NUM_ERROR_CORRECTION_BLOCKS, ver, ecl);
448 let blockecclen: usize = QrCode::table_get(&ECC_CODEWORDS_PER_BLOCK , ver, ecl);
449 let rawcodewords: usize = QrCode::get_num_raw_data_modules(ver) / 8;
450 let numshortblocks: usize = numblocks - rawcodewords % numblocks;
451 let shortblockdatalen: usize = rawcodewords / numblocks - blockecclen;
452 let result = &mut resultbuf[ .. rawcodewords];
453
454 let rs = ReedSolomonGenerator::new(blockecclen);
457 let mut dat: &[u8] = data;
458 let ecc: &mut [u8] = &mut temp[ .. blockecclen]; for i in 0 .. numblocks {
460 let datlen: usize = shortblockdatalen + usize::from(i >= numshortblocks);
461 rs.compute_remainder(&dat[ .. datlen], ecc);
462 let mut k: usize = i;
463 for j in 0 .. datlen { if j == shortblockdatalen {
465 k -= numshortblocks;
466 }
467 result[k] = dat[j];
468 k += numblocks;
469 }
470 let mut k: usize = data.len() + i;
471 for j in 0 .. blockecclen { result[k] = ecc[j];
473 k += numblocks;
474 }
475 dat = &dat[datlen .. ];
476 }
477 debug_assert_eq!(dat.len(), 0);
478 result
479 }
480
481
482 fn function_modules_marked(outbuffer: &'a mut [u8], ver: Version) -> Self {
487 assert_eq!(outbuffer.len(), ver.buffer_len());
488 let parts: (&mut u8, &mut [u8]) = outbuffer.split_first_mut().unwrap();
489 let mut result = Self {
490 size: parts.0,
491 modules: parts.1,
492 };
493 let size: u8 = ver.value() * 4 + 17;
494 *result.size = size;
495 result.modules.fill(0);
496
497 result.fill_rectangle(6, 0, 1, size);
499 result.fill_rectangle(0, 6, size, 1);
500
501 result.fill_rectangle(0, 0, 9, 9);
503 result.fill_rectangle(size - 8, 0, 8, 9);
504 result.fill_rectangle(0, size - 8, 9, 8);
505
506 let mut alignpatposbuf = [0u8; 7];
508 let alignpatpos: &[u8] = result.get_alignment_pattern_positions(&mut alignpatposbuf);
509 for (i, pos0) in alignpatpos.iter().enumerate() {
510 for (j, pos1) in alignpatpos.iter().enumerate() {
511 if !((i == 0 && j == 0) || (i == 0 && j == alignpatpos.len() - 1) || (i == alignpatpos.len() - 1 && j == 0)) {
513 result.fill_rectangle(pos0 - 2, pos1 - 2, 5, 5);
514 }
515 }
516 }
517
518 if ver.value() >= 7 {
520 result.fill_rectangle(size - 11, 0, 3, 6);
521 result.fill_rectangle(0, size - 11, 6, 3);
522 }
523
524 result
525 }
526
527
528 fn draw_light_function_modules(&mut self) {
532 let size: u8 = *self.size;
534 for i in (7 .. size-7).step_by(2) {
535 self.set_module_bounded(6, i, false);
536 self.set_module_bounded(i, 6, false);
537 }
538
539 for dy in -4i32 ..= 4 {
541 for dx in -4i32 ..= 4 {
542 let dist: i32 = dx.abs().max(dy.abs());
543 if dist == 2 || dist == 4 {
544 self.set_module_unbounded(3 + dx, 3 + dy, false);
545 self.set_module_unbounded(i32::from(size) - 4 + dx, 3 + dy, false);
546 self.set_module_unbounded(3 + dx, i32::from(size) - 4 + dy, false);
547 }
548 }
549 }
550
551 let mut alignpatposbuf = [0u8; 7];
553 let alignpatpos: &[u8] = self.get_alignment_pattern_positions(&mut alignpatposbuf);
554 for (i, &pos0) in alignpatpos.iter().enumerate() {
555 for (j, &pos1) in alignpatpos.iter().enumerate() {
556 if (i == 0 && j == 0) || (i == 0 && j == alignpatpos.len() - 1) || (i == alignpatpos.len() - 1 && j == 0) {
557 continue; }
559 for dy in -1 ..= 1 {
560 for dx in -1 ..= 1 {
561 self.set_module_bounded((i32::from(pos0) + dx) as u8, (i32::from(pos1) + dy) as u8, dx == 0 && dy == 0);
562 }
563 }
564 }
565 }
566
567 let ver = u32::from(self.version().value()); if ver >= 7 {
570 let bits: u32 = {
572 let mut rem: u32 = ver;
573 for _ in 0 .. 12 {
574 rem = (rem << 1) ^ ((rem >> 11) * 0x1F25);
575 }
576 ver << 12 | rem };
578 debug_assert_eq!(bits >> 18, 0);
579
580 for i in 0u8 .. 18 {
582 let bit: bool = get_bit(bits, i);
583 let a: u8 = size - 11 + i % 3;
584 let b: u8 = i / 3;
585 self.set_module_bounded(a, b, bit);
586 self.set_module_bounded(b, a, bit);
587 }
588 }
589 }
590
591
592 fn draw_format_bits(&mut self, ecl: QrCodeEcc, mask: Mask) {
596 let bits: u32 = {
598 let data = u32::from(ecl.format_bits() << 3 | mask.value());
600 let mut rem: u32 = data;
601 for _ in 0 .. 10 {
602 rem = (rem << 1) ^ ((rem >> 9) * 0x537);
603 }
604 (data << 10 | rem) ^ 0x5412 };
606 debug_assert_eq!(bits >> 15, 0);
607
608 for i in 0 .. 6 {
610 self.set_module_bounded(8, i, get_bit(bits, i));
611 }
612 self.set_module_bounded(8, 7, get_bit(bits, 6));
613 self.set_module_bounded(8, 8, get_bit(bits, 7));
614 self.set_module_bounded(7, 8, get_bit(bits, 8));
615 for i in 9 .. 15 {
616 self.set_module_bounded(14 - i, 8, get_bit(bits, i));
617 }
618
619 let size: u8 = *self.size;
621 for i in 0 .. 8 {
622 self.set_module_bounded(size - 1 - i, 8, get_bit(bits, i));
623 }
624 for i in 8 .. 15 {
625 self.set_module_bounded(8, size - 15 + i, get_bit(bits, i));
626 }
627 self.set_module_bounded(8, size - 8, true); }
629
630
631 fn fill_rectangle(&mut self, left: u8, top: u8, width: u8, height: u8) {
633 for dy in 0 .. height {
634 for dx in 0 .. width {
635 self.set_module_bounded(left + dx, top + dy, true);
636 }
637 }
638 }
639
640
641 fn draw_codewords(&mut self, data: &[u8]) {
646 assert_eq!(data.len(), QrCode::get_num_raw_data_modules(self.version()) / 8, "Illegal argument");
647
648 let size: i32 = self.size();
649 let mut i: usize = 0; let mut right: i32 = size - 1;
652 while right >= 1 { if right == 6 {
654 right = 5;
655 }
656 for vert in 0 .. size { for j in 0 .. 2 {
658 let x = (right - j) as u8; let upward: bool = (right + 1) & 2 == 0;
660 let y = (if upward { size - 1 - vert } else { vert }) as u8; if !self.get_module_bounded(x, y) && i < data.len() * 8 {
662 self.set_module_bounded(x, y, get_bit(data[i >> 3].into(), 7 - ((i as u8) & 7)));
663 i += 1;
664 }
665 }
668 }
669 right -= 2;
670 }
671 debug_assert_eq!(i, data.len() * 8);
672 }
673
674
675 fn apply_mask(&mut self, functionmodules: &QrCode, mask: Mask) {
681 for y in 0 .. *self.size {
682 for x in 0 .. *self.size {
683 if functionmodules.get_module_bounded(x, y) {
684 continue;
685 }
686 let invert: bool = {
687 let x = i32::from(x);
688 let y = i32::from(y);
689 match mask.value() {
690 0 => (x + y) % 2 == 0,
691 1 => y % 2 == 0,
692 2 => x % 3 == 0,
693 3 => (x + y) % 3 == 0,
694 4 => (x / 3 + y / 2) % 2 == 0,
695 5 => x * y % 2 + x * y % 3 == 0,
696 6 => (x * y % 2 + x * y % 3) % 2 == 0,
697 7 => ((x + y) % 2 + x * y % 3) % 2 == 0,
698 _ => unreachable!(),
699 }
700 };
701 self.set_module_bounded(x, y,
702 self.get_module_bounded(x, y) ^ invert);
703 }
704 }
705 }
706
707
708 fn get_penalty_score(&self) -> i32 {
711 let mut result: i32 = 0;
712 let size: u8 = *self.size;
713
714 for y in 0 .. size {
716 let mut runcolor = false;
717 let mut runx: i32 = 0;
718 let mut runhistory = FinderPenalty::new(size);
719 for x in 0 .. size {
720 if self.get_module_bounded(x, y) == runcolor {
721 runx += 1;
722 if runx == 5 {
723 result += PENALTY_N1;
724 } else if runx > 5 {
725 result += 1;
726 }
727 } else {
728 runhistory.add_history(runx);
729 if !runcolor {
730 result += runhistory.count_patterns() * PENALTY_N3;
731 }
732 runcolor = self.get_module_bounded(x, y);
733 runx = 1;
734 }
735 }
736 result += runhistory.terminate_and_count(runcolor, runx) * PENALTY_N3;
737 }
738 for x in 0 .. size {
740 let mut runcolor = false;
741 let mut runy: i32 = 0;
742 let mut runhistory = FinderPenalty::new(size);
743 for y in 0 .. size {
744 if self.get_module_bounded(x, y) == runcolor {
745 runy += 1;
746 if runy == 5 {
747 result += PENALTY_N1;
748 } else if runy > 5 {
749 result += 1;
750 }
751 } else {
752 runhistory.add_history(runy);
753 if !runcolor {
754 result += runhistory.count_patterns() * PENALTY_N3;
755 }
756 runcolor = self.get_module_bounded(x, y);
757 runy = 1;
758 }
759 }
760 result += runhistory.terminate_and_count(runcolor, runy) * PENALTY_N3;
761 }
762
763 for y in 0 .. size-1 {
765 for x in 0 .. size-1 {
766 let color: bool = self.get_module_bounded(x, y);
767 if color == self.get_module_bounded(x + 1, y) &&
768 color == self.get_module_bounded(x, y + 1) &&
769 color == self.get_module_bounded(x + 1, y + 1) {
770 result += PENALTY_N2;
771 }
772 }
773 }
774
775 let dark = self.modules.iter().map(|x| x.count_ones()).sum::<u32>() as i32;
777 let total = i32::from(size) * i32::from(size); let k: i32 = ((dark * 20 - total * 10).abs() + total - 1) / total - 1;
780 debug_assert!(0 <= k && k <= 9);
781 result += k * PENALTY_N4;
782 debug_assert!(0 <= result && result <= 2568888); result
784 }
785
786
787 fn get_alignment_pattern_positions<'b>(&self, resultbuf: &'b mut [u8; 7]) -> &'b [u8] {
794 let ver: u8 = self.version().value();
795 if ver == 1 {
796 &resultbuf[ .. 0]
797 } else {
798 let numalign: u8 = ver / 7 + 2;
799 let step: u8 = if ver == 32 { 26 } else
800 {(ver * 4 + numalign * 2 + 1) / (numalign * 2 - 2) * 2};
801 let result = &mut resultbuf[ .. usize::from(numalign)];
802 for i in 0 .. numalign-1 {
803 result[usize::from(i)] = *self.size - 7 - i * step;
804 }
805 *result.last_mut().unwrap() = 6;
806 result.reverse();
807 result
808 }
809 }
810
811
812 fn get_num_raw_data_modules(ver: Version) -> usize {
816 let ver = usize::from(ver.value());
817 let mut result: usize = (16 * ver + 128) * ver + 64;
818 if ver >= 2 {
819 let numalign: usize = ver / 7 + 2;
820 result -= (25 * numalign - 10) * numalign - 55;
821 if ver >= 7 {
822 result -= 36;
823 }
824 }
825 debug_assert!((208 ..= 29648).contains(&result));
826 result
827 }
828
829
830 fn get_num_data_codewords(ver: Version, ecl: QrCodeEcc) -> usize {
834 QrCode::get_num_raw_data_modules(ver) / 8
835 - QrCode::table_get(&ECC_CODEWORDS_PER_BLOCK , ver, ecl)
836 * QrCode::table_get(&NUM_ERROR_CORRECTION_BLOCKS, ver, ecl)
837 }
838
839
840 fn table_get(table: &'static [[i8; 41]; 4], ver: Version, ecl: QrCodeEcc) -> usize {
842 table[ecl.ordinal()][usize::from(ver.value())] as usize
843 }
844
845}
846
847
848impl PartialEq for QrCode<'_> {
849 fn eq(&self, other: &QrCode<'_>) -> bool{
850 *self.size == *other.size &&
851 *self.modules == *other.modules
852 }
853}
854
855impl Eq for QrCode<'_> {}
856
857
858struct ReedSolomonGenerator {
861
862 divisor: [u8; 30],
865
866 degree: usize,
868
869}
870
871
872impl ReedSolomonGenerator {
873
874 fn new(degree: usize) -> Self {
877 let mut result = Self {
878 divisor: [0u8; 30],
879 degree: degree,
880 };
881 assert!((1 ..= result.divisor.len()).contains(°ree), "Degree out of range");
882 let divisor: &mut [u8] = &mut result.divisor[ .. degree];
883 divisor[degree - 1] = 1; let mut root: u8 = 1;
889 for _ in 0 .. degree { for j in 0 .. degree {
892 divisor[j] = Self::multiply(divisor[j], root);
893 if j + 1 < divisor.len() {
894 divisor[j] ^= divisor[j + 1];
895 }
896 }
897 root = Self::multiply(root, 0x02);
898 }
899 result
900 }
901
902
903 fn compute_remainder(&self, data: &[u8], result: &mut [u8]) {
905 assert_eq!(result.len(), self.degree);
906 result.fill(0);
907 for b in data { let factor: u8 = b ^ result[0];
909 result.copy_within(1 .. , 0);
910 result[result.len() - 1] = 0;
911 for (x, &y) in result.iter_mut().zip(self.divisor.iter()) {
912 *x ^= Self::multiply(y, factor);
913 }
914 }
915 }
916
917
918 fn multiply(x: u8, y: u8) -> u8 {
921 let mut z: u8 = 0;
923 for i in (0 .. 8).rev() {
924 z = (z << 1) ^ ((z >> 7) * 0x1D);
925 z ^= ((y >> i) & 1) * x;
926 }
927 z
928 }
929
930}
931
932
933struct FinderPenalty {
936 qr_size: i32,
937 run_history: [i32; 7],
938}
939
940
941impl FinderPenalty {
942
943 pub fn new(size: u8) -> Self {
944 Self {
945 qr_size: i32::from(size),
946 run_history: [0; 7],
947 }
948 }
949
950
951 pub fn add_history(&mut self, mut currentrunlength: i32) {
953 if self.run_history[0] == 0 {
954 currentrunlength += self.qr_size; }
956 let len: usize = self.run_history.len();
957 self.run_history.copy_within(0 .. len-1, 1);
958 self.run_history[0] = currentrunlength;
959 }
960
961
962 pub fn count_patterns(&self) -> i32 {
964 let rh = &self.run_history;
965 let n = rh[1];
966 debug_assert!(n <= self.qr_size * 3);
967 let core = n > 0 && rh[2] == n && rh[3] == n * 3 && rh[4] == n && rh[5] == n;
968 #[allow(unused_parens)]
969 ( i32::from(core && rh[0] >= n * 4 && rh[6] >= n)
970 + i32::from(core && rh[6] >= n * 4 && rh[0] >= n))
971 }
972
973
974 pub fn terminate_and_count(mut self, currentruncolor: bool, mut currentrunlength: i32) -> i32 {
976 if currentruncolor { self.add_history(currentrunlength);
978 currentrunlength = 0;
979 }
980 currentrunlength += self.qr_size; self.add_history(currentrunlength);
982 self.count_patterns()
983 }
984
985}
986
987
988const PENALTY_N1: i32 = 3;
992const PENALTY_N2: i32 = 3;
993const PENALTY_N3: i32 = 40;
994const PENALTY_N4: i32 = 10;
995
996
997static ECC_CODEWORDS_PER_BLOCK: [[i8; 41]; 4] = [
998 [-1, 7, 10, 15, 20, 26, 18, 20, 24, 30, 18, 20, 24, 26, 30, 22, 24, 28, 30, 28, 28, 28, 28, 30, 30, 26, 28, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30], [-1, 10, 16, 26, 18, 24, 16, 18, 22, 22, 26, 30, 22, 22, 24, 24, 28, 28, 26, 26, 26, 26, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28], [-1, 13, 22, 18, 26, 18, 24, 18, 22, 20, 24, 28, 26, 24, 20, 30, 24, 28, 28, 26, 30, 28, 30, 30, 30, 30, 28, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30], [-1, 17, 28, 22, 16, 22, 28, 26, 26, 24, 28, 24, 28, 22, 24, 24, 30, 28, 28, 26, 28, 30, 24, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30], ];
1005
1006static NUM_ERROR_CORRECTION_BLOCKS: [[i8; 41]; 4] = [
1007 [-1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 4, 4, 4, 4, 4, 6, 6, 6, 6, 7, 8, 8, 9, 9, 10, 12, 12, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 24, 25], [-1, 1, 1, 1, 2, 2, 4, 4, 4, 5, 5, 5, 8, 9, 9, 10, 10, 11, 13, 14, 16, 17, 17, 18, 20, 21, 23, 25, 26, 28, 29, 31, 33, 35, 37, 38, 40, 43, 45, 47, 49], [-1, 1, 1, 2, 2, 4, 4, 6, 6, 8, 8, 8, 10, 12, 16, 12, 17, 16, 18, 21, 20, 23, 23, 25, 27, 29, 34, 34, 35, 38, 40, 43, 45, 48, 51, 53, 56, 59, 62, 65, 68], [-1, 1, 1, 2, 4, 4, 4, 5, 6, 8, 8, 11, 11, 16, 16, 18, 16, 19, 21, 25, 25, 25, 34, 30, 32, 35, 37, 40, 42, 45, 48, 51, 54, 57, 60, 63, 66, 70, 74, 77, 81], ];
1014
1015
1016
1017#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug)]
1021pub enum QrCodeEcc {
1022 Low ,
1024 Medium ,
1026 Quartile,
1028 High ,
1030}
1031
1032
1033impl QrCodeEcc {
1034
1035 fn ordinal(self) -> usize {
1037 use QrCodeEcc::*;
1038 match self {
1039 Low => 0,
1040 Medium => 1,
1041 Quartile => 2,
1042 High => 3,
1043 }
1044 }
1045
1046
1047 fn format_bits(self) -> u8 {
1049 use QrCodeEcc::*;
1050 match self {
1051 Low => 1,
1052 Medium => 0,
1053 Quartile => 3,
1054 High => 2,
1055 }
1056 }
1057
1058}
1059
1060
1061
1062pub struct QrSegment<'a> {
1077
1078 mode: QrSegmentMode,
1080
1081 numchars: usize,
1085
1086 data: &'a [u8],
1088
1089 bitlength: usize,
1092
1093}
1094
1095
1096impl<'a> QrSegment<'a> {
1097
1098 pub fn make_bytes(data: &'a [u8]) -> Self {
1106 QrSegment::new(QrSegmentMode::Byte, data.len(), data, data.len().checked_mul(8).unwrap())
1107 }
1108
1109
1110 pub fn make_numeric(text: &str, buf: &'a mut [u8]) -> Self {
1114 let mut bb = BitBuffer::new(buf);
1115 let mut accumdata: u32 = 0;
1116 let mut accumcount: u8 = 0;
1117 for b in text.bytes() {
1118 assert!((b'0' ..= b'9').contains(&b), "String contains non-numeric characters");
1119 accumdata = accumdata * 10 + u32::from(b - b'0');
1120 accumcount += 1;
1121 if accumcount == 3 {
1122 bb.append_bits(accumdata, 10);
1123 accumdata = 0;
1124 accumcount = 0;
1125 }
1126 }
1127 if accumcount > 0 { bb.append_bits(accumdata, accumcount * 3 + 1);
1129 }
1130 QrSegment::new(QrSegmentMode::Numeric, text.len(), bb.data, bb.length)
1131 }
1132
1133
1134 pub fn make_alphanumeric(text: &str, buf: &'a mut [u8]) -> Self {
1141 let mut bb = BitBuffer::new(buf);
1142 let mut accumdata: u32 = 0;
1143 let mut accumcount: u8 = 0;
1144 for c in text.chars() {
1145 let i: usize = ALPHANUMERIC_CHARSET.find(c)
1146 .expect("String contains unencodable characters in alphanumeric mode");
1147 accumdata = accumdata * 45 + u32::try_from(i).unwrap();
1148 accumcount += 1;
1149 if accumcount == 2 {
1150 bb.append_bits(accumdata, 11);
1151 accumdata = 0;
1152 accumcount = 0;
1153 }
1154 }
1155 if accumcount > 0 { bb.append_bits(accumdata, 6);
1157 }
1158 QrSegment::new(QrSegmentMode::Alphanumeric, text.len(), bb.data, bb.length)
1159 }
1160
1161
1162 pub fn make_eci(assignval: u32, buf: &'a mut [u8]) -> Self {
1165 let mut bb = BitBuffer::new(buf);
1166 if assignval < (1 << 7) {
1167 bb.append_bits(assignval, 8);
1168 } else if assignval < (1 << 14) {
1169 bb.append_bits(0b10, 2);
1170 bb.append_bits(assignval, 14);
1171 } else if assignval < 1_000_000 {
1172 bb.append_bits(0b110, 3);
1173 bb.append_bits(assignval, 21);
1174 } else {
1175 panic!("ECI assignment value out of range");
1176 }
1177 QrSegment::new(QrSegmentMode::Eci, 0, bb.data, bb.length)
1178 }
1179
1180
1181 pub fn new(mode: QrSegmentMode, numchars: usize, data: &'a [u8], bitlength: usize) -> Self {
1188 assert!(bitlength == 0 || (bitlength - 1) / 8 < data.len());
1189 Self { mode, numchars, data, bitlength }
1190 }
1191
1192
1193 pub fn mode(&self) -> QrSegmentMode {
1197 self.mode
1198 }
1199
1200
1201 pub fn num_chars(&self) -> usize {
1203 self.numchars
1204 }
1205
1206
1207 pub fn calc_buffer_size(mode: QrSegmentMode, numchars: usize) -> Option<usize> {
1218 let temp = Self::calc_bit_length(mode, numchars)?;
1219 Some(temp / 8 + usize::from(temp % 8 != 0)) }
1221
1222
1223 fn calc_bit_length(mode: QrSegmentMode, numchars: usize) -> Option<usize> {
1230 let mul_frac_ceil = |numer: usize, denom: usize|
1232 Some(numchars)
1233 .and_then(|x| x.checked_mul(numer))
1234 .and_then(|x| x.checked_add(denom - 1))
1235 .map(|x| x / denom);
1236
1237 use QrSegmentMode::*;
1238 match mode {
1239 Numeric => mul_frac_ceil(10, 3),
1240 Alphanumeric => mul_frac_ceil(11, 2),
1241 Byte => mul_frac_ceil( 8, 1),
1242 Kanji => mul_frac_ceil(13, 1),
1243 Eci => {
1244 assert_eq!(numchars, 0);
1245 Some(3 * 8)
1246 },
1247 }
1248 }
1249
1250
1251 fn get_total_bits(segs: &[Self], version: Version) -> Option<usize> {
1255 let mut result: usize = 0;
1256 for seg in segs {
1257 let ccbits: u8 = seg.mode.num_char_count_bits(version);
1258 if let Some(limit) = 1usize.checked_shl(ccbits.into()) {
1260 if seg.numchars >= limit {
1261 return None; }
1263 }
1264 result = result.checked_add(4 + usize::from(ccbits))?;
1265 result = result.checked_add(seg.bitlength)?;
1266 }
1267 Some(result)
1268 }
1269
1270
1271 pub fn is_numeric(text: &str) -> bool {
1274 text.chars().all(|c| ('0' ..= '9').contains(&c))
1275 }
1276
1277
1278 pub fn is_alphanumeric(text: &str) -> bool {
1282 text.chars().all(|c| ALPHANUMERIC_CHARSET.contains(c))
1283 }
1284
1285}
1286
1287
1288static ALPHANUMERIC_CHARSET: &str = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:";
1291
1292
1293
1294#[derive(Clone, Copy, PartialEq, Eq, Debug)]
1298pub enum QrSegmentMode {
1299 Numeric,
1300 Alphanumeric,
1301 Byte,
1302 Kanji,
1303 Eci,
1304}
1305
1306
1307impl QrSegmentMode {
1308
1309 fn mode_bits(self) -> u32 {
1312 use QrSegmentMode::*;
1313 match self {
1314 Numeric => 0x1,
1315 Alphanumeric => 0x2,
1316 Byte => 0x4,
1317 Kanji => 0x8,
1318 Eci => 0x7,
1319 }
1320 }
1321
1322
1323 fn num_char_count_bits(self, ver: Version) -> u8 {
1326 use QrSegmentMode::*;
1327 (match self {
1328 Numeric => [10, 12, 14],
1329 Alphanumeric => [ 9, 11, 13],
1330 Byte => [ 8, 16, 16],
1331 Kanji => [ 8, 10, 12],
1332 Eci => [ 0, 0, 0],
1333 })[usize::from((ver.value() + 7) / 17)]
1334 }
1335
1336}
1337
1338
1339pub struct BitBuffer<'a> {
1345
1346 data: &'a mut [u8],
1347
1348 length: usize,
1349
1350}
1351
1352
1353impl<'a> BitBuffer<'a> {
1354
1355 pub fn new(buffer: &'a mut [u8]) -> Self {
1357 Self {
1358 data: buffer,
1359 length: 0,
1360 }
1361 }
1362
1363
1364 pub fn len(&self) -> usize {
1366 self.length
1367 }
1368
1369
1370 pub fn append_bits(&mut self, val: u32, len: u8) {
1373 assert!(len <= 31 && val >> len == 0);
1374 assert!(usize::from(len) <= usize::MAX - self.length);
1375 for i in (0 .. len).rev() {
1376 let index: usize = self.length >> 3;
1377 let shift: u8 = 7 - ((self.length as u8) & 7);
1378 let bit: u8 = ((val >> i) as u8) & 1;
1379 if shift == 7 {
1380 self.data[index] = bit << shift;
1381 } else {
1382 self.data[index] |= bit << shift;
1383 }
1384 self.length += 1;
1385 }
1386 }
1387
1388}
1389
1390
1391
1392#[derive(Debug, Clone)]
1405pub enum DataTooLong {
1406 SegmentTooLong,
1407 DataOverCapacity(usize, usize),
1408}
1409
1410impl core::fmt::Display for DataTooLong {
1411 fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
1412 match *self {
1413 Self::SegmentTooLong => write!(f, "Segment too long"),
1414 Self::DataOverCapacity(datalen, maxcapacity) =>
1415 write!(f, "Data length = {} bits, Max capacity = {} bits", datalen, maxcapacity),
1416 }
1417 }
1418}
1419
1420
1421#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug)]
1423pub struct Version(u8);
1424
1425impl Version {
1426 pub const MIN: Version = Version( 1);
1428
1429 pub const MAX: Version = Version(40);
1431
1432 pub const fn new(ver: u8) -> Self {
1436 assert!(Version::MIN.value() <= ver && ver <= Version::MAX.value(), "Version number out of range");
1437 Self(ver)
1438 }
1439
1440 pub const fn value(self) -> u8 {
1442 self.0
1443 }
1444
1445 pub const fn buffer_len(self) -> usize {
1448 let sidelen = (self.0 as usize) * 4 + 17;
1449 (sidelen * sidelen + 7) / 8 + 1
1450 }
1451}
1452
1453
1454#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug)]
1456pub struct Mask(u8);
1457
1458impl Mask {
1459 pub const fn new(mask: u8) -> Self {
1463 assert!(mask <= 7, "Mask value out of range");
1464 Self(mask)
1465 }
1466
1467 pub const fn value(self) -> u8 {
1469 self.0
1470 }
1471}
1472
1473
1474fn get_bit(x: u32, i: u8) -> bool {
1476 (x >> i) & 1 != 0
1477}