1use crate::{
18 common::{BitSource, CharacterSet, DecoderRXingResult, ECIStringBuilder, Eci, Result},
19 Exceptions,
20};
21
22#[derive(Debug, PartialEq, Eq, Clone, Copy)]
33enum Mode {
34 PAD_ENCODE, ASCII_ENCODE,
36 C40_ENCODE,
37 TEXT_ENCODE,
38 ANSIX12_ENCODE,
39 EDIFACT_ENCODE,
40 BASE256_ENCODE,
41 ECI_ENCODE,
42}
43
44const C40_BASIC_SET_CHARS: [char; 40] = [
49 '*', '*', '*', ' ', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E',
50 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
51 'Y', 'Z',
52];
53
54const C40_SHIFT2_SET_CHARS: [char; 27] = [
55 '!', '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.', '/', ':', ';', '<', '=',
56 '>', '?', '@', '[', '\\', ']', '^', '_',
57];
58
59const TEXT_BASIC_SET_CHARS: [char; 40] = [
64 '*', '*', '*', ' ', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e',
65 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x',
66 'y', 'z',
67];
68
69const TEXT_SHIFT2_SET_CHARS: [char; 27] = C40_SHIFT2_SET_CHARS;
71
72const TEXT_SHIFT3_SET_CHARS: [char; 32] = [
73 '`',
74 'A',
75 'B',
76 'C',
77 'D',
78 'E',
79 'F',
80 'G',
81 'H',
82 'I',
83 'J',
84 'K',
85 'L',
86 'M',
87 'N',
88 'O',
89 'P',
90 'Q',
91 'R',
92 'S',
93 'T',
94 'U',
95 'V',
96 'W',
97 'X',
98 'Y',
99 'Z',
100 '{',
101 '|',
102 '}',
103 '~',
104 127 as char,
105];
106
107const INSERT_STRING_CONST: &str = "\u{001E}\u{0004}";
108const VALUE_236: &str = "[)>\u{001E}05\u{001D}";
109const VALUE_237: &str = "[)>\u{001E}06\u{001D}";
110
111pub fn decode(bytes: &[u8], is_flipped: bool) -> Result<DecoderRXingResult> {
112 let mut bits = BitSource::new(bytes);
113 let mut result = ECIStringBuilder::with_capacity(100);
114 let mut resultTrailer = String::new();
115 let mut byteSegments = Vec::new();
116 let mut mode = Mode::ASCII_ENCODE;
117 let mut fnc1Positions = Vec::new();
119 let symbologyModifier;
120 let mut isECIencoded = false;
121 let mut known_eci = true;
122 let mut is_gs1 = false;
123 loop {
124 match mode {
125 Mode::ASCII_ENCODE => {
126 mode = decodeAsciiSegment(
127 &mut bits,
128 &mut result,
129 &mut resultTrailer,
130 &mut fnc1Positions,
131 &mut is_gs1,
132 )?
133 }
134 Mode::C40_ENCODE => {
135 decodeC40Segment(&mut bits, &mut result, &mut fnc1Positions)?;
136 mode = Mode::ASCII_ENCODE;
137 }
138 Mode::TEXT_ENCODE => {
139 decodeTextSegment(&mut bits, &mut result, &mut fnc1Positions)?;
140 mode = Mode::ASCII_ENCODE;
141 }
142 Mode::ANSIX12_ENCODE => {
143 decodeAnsiX12Segment(&mut bits, &mut result)?;
144 mode = Mode::ASCII_ENCODE;
145 }
146 Mode::EDIFACT_ENCODE => {
147 decodeEdifactSegment(&mut bits, &mut result)?;
148 mode = Mode::ASCII_ENCODE;
149 }
150 Mode::BASE256_ENCODE => {
151 decodeBase256Segment(&mut bits, &mut result, &mut byteSegments)?;
152 mode = Mode::ASCII_ENCODE;
153 }
154 Mode::ECI_ENCODE => {
155 known_eci &= decodeECISegment(&mut bits, &mut result)?;
156 isECIencoded = true; mode = Mode::ASCII_ENCODE;
158 }
159 _ => return Err(Exceptions::FORMAT),
160 }
161
162 if !(mode != Mode::PAD_ENCODE && bits.available() > 0) {
163 break;
164 }
165 } if !resultTrailer.is_empty() {
167 result.appendCharacters(&resultTrailer);
168 }
169 if isECIencoded && known_eci {
170 if fnc1Positions.contains(&0) || fnc1Positions.contains(&4) {
173 symbologyModifier = 5;
174 } else if fnc1Positions.contains(&1) || fnc1Positions.contains(&5) {
175 symbologyModifier = 6;
176 } else {
177 symbologyModifier = 4;
178 }
179 } else if fnc1Positions.contains(&0) || fnc1Positions.contains(&4) {
180 symbologyModifier = 2;
181 } else if fnc1Positions.contains(&1) || fnc1Positions.contains(&5) {
182 symbologyModifier = 3;
183 } else {
184 symbologyModifier = 1;
185 }
186
187 let mut result = DecoderRXingResult::with_symbology(
188 bytes.to_vec(),
189 result.build_result().to_string(),
190 byteSegments,
191 String::new(),
192 symbologyModifier,
193 );
194 if is_gs1 {
195 result.setContentType(String::from("GS1"));
196 }
197
198 if !known_eci {
199 result.setContentType(String::from("UnknownECI"));
200 }
201
202 if is_flipped {
203 result.setIsMirrored(is_flipped);
204 }
205
206 Ok(result)
207}
208
209fn decodeAsciiSegment(
213 bits: &mut BitSource,
214 result: &mut ECIStringBuilder,
215 resultTrailer: &mut String,
216 fnc1positions: &mut Vec<usize>,
217 is_gs1: &mut bool,
218) -> Result<Mode> {
219 let mut upperShift = false;
220 let mut firstFNC1Position = 1;
221 let mut firstCodeword = true;
222 let mut sai = StructuredAppendInfo::default();
223 loop {
224 let mut oneByte = bits.readBits(8)?;
225 match oneByte {
226 0 => return Err(Exceptions::FORMAT),
227 1..=128 => {
228 if upperShift {
230 oneByte += 128;
231 }
233 result.append_char(char::from_u32(oneByte - 1).ok_or(Exceptions::PARSE)?);
234 return Ok(Mode::ASCII_ENCODE);
235 }
236 129 => return Ok(Mode::PAD_ENCODE), 130..=229 => {
238 let value = oneByte - 130;
240 if value < 10 {
241 result.append_char('0');
243 }
244 result.append_string(&format!("{value}"));
245 }
246 230 =>
247 {
249 return Ok(Mode::C40_ENCODE)
250 }
251 231 =>
252 {
254 return Ok(Mode::BASE256_ENCODE)
255 }
256 232 => {
257 if bits.getByteOffset() == firstFNC1Position {
259 *is_gs1 = true;
261 }
262 else if bits.getByteOffset() == firstFNC1Position + 1 {
264 }
266 else {
268 result.append_char(29 as char);
269 } fnc1positions.push(result.len());
272 }
273 233 =>
274 {
276 if !firstCodeword
277 {
279 return Err(Exceptions::format_with(
280 "structured append tag must be first code word",
281 ));
282 }
283 parse_structured_append(bits, &mut sai)?;
284 firstFNC1Position = 5;
285 }
286 234 =>
287 {}
291 235 =>
292 {
294 upperShift = true
295 }
296 236 => {
297 result.append_string(VALUE_236);
299 resultTrailer.replace_range(0..0, INSERT_STRING_CONST);
300 }
302 237 => {
303 result.append_string(VALUE_237);
305 resultTrailer.replace_range(0..0, INSERT_STRING_CONST);
306 }
308 238 =>
309 {
311 return Ok(Mode::ANSIX12_ENCODE)
312 }
313 239 =>
314 {
316 return Ok(Mode::TEXT_ENCODE)
317 }
318 240 =>
319 {
321 return Ok(Mode::EDIFACT_ENCODE)
322 }
323 241 =>
324 {
326 return Ok(Mode::ECI_ENCODE)
327 }
328 _ => {
329 if oneByte != 254 || bits.available() != 0 {
332 return Err(Exceptions::FORMAT);
333 }
334 }
335 }
336
337 if bits.available() == 0 {
338 break;
339 }
340 firstCodeword = false;
341 } Ok(Mode::ASCII_ENCODE)
343}
344
345fn decodeC40Segment(
349 bits: &mut BitSource,
350 result: &mut ECIStringBuilder,
351 fnc1positions: &mut Vec<usize>,
352) -> Result<()> {
353 let mut upperShift = false;
357
358 let mut cValues = [0; 3];
359 let mut shift = 0;
360
361 loop {
362 if bits.available() == 8 {
364 return Ok(());
365 }
366 let firstByte = bits.readBits(8)?;
367 if firstByte == 254 {
368 return Ok(());
370 }
371
372 parseTwoBytes(firstByte, bits.readBits(8)?, &mut cValues);
373
374 for cValue in cValues {
375 match shift {
379 0 => {
380 if cValue < 3 {
381 shift = cValue + 1;
382 } else if cValue < C40_BASIC_SET_CHARS.len() as u32 {
383 let c40char = C40_BASIC_SET_CHARS[cValue as usize];
384 if upperShift {
385 result.append_char(
386 char::from_u32(c40char as u32 + 128).ok_or(Exceptions::PARSE)?,
387 );
388 upperShift = false;
389 } else {
390 result.append_char(c40char);
391 }
392 } else {
393 return Err(Exceptions::FORMAT);
394 }
395 }
396 1 => {
397 if upperShift {
398 result.append_char(char::from_u32(cValue + 128).ok_or(Exceptions::PARSE)?);
399 upperShift = false;
400 } else {
401 result.append_char(char::from_u32(cValue).ok_or(Exceptions::PARSE)?);
402 }
403 shift = 0;
404 }
405 2 => {
406 if cValue < C40_SHIFT2_SET_CHARS.len() as u32 {
407 let c40char = C40_SHIFT2_SET_CHARS[cValue as usize];
408 if upperShift {
409 result.append_char(
410 char::from_u32(c40char as u32 + 128).ok_or(Exceptions::PARSE)?,
411 );
412 upperShift = false;
413 } else {
414 result.append_char(c40char);
415 }
416 } else {
417 match cValue {
418 27 => {
419 fnc1positions.push(result.len());
421 result.append_char(29 as char); }
423 30 =>
424 {
426 upperShift = true
427 }
428
429 _ => return Err(Exceptions::FORMAT),
430 }
431 }
432 shift = 0;
433 }
434 3 => {
435 if upperShift {
436 result.append_char(char::from_u32(cValue + 224).ok_or(Exceptions::PARSE)?);
437 upperShift = false;
438 } else {
439 result.append_char(char::from_u32(cValue + 96).ok_or(Exceptions::PARSE)?);
440 }
441 shift = 0;
442 }
443
444 _ => return Err(Exceptions::FORMAT),
445 }
446 }
447 if bits.available() == 0 {
448 break;
449 }
450 } Ok(())
452}
453
454fn decodeTextSegment(
458 bits: &mut BitSource,
459 result: &mut ECIStringBuilder,
460 fnc1positions: &mut Vec<usize>,
461) -> Result<()> {
462 let mut upperShift = false;
466
467 let mut cValues = [0; 3]; let mut shift = 0;
469 loop {
470 if bits.available() == 8 {
472 return Ok(());
473 }
474 let firstByte = bits.readBits(8)?;
475 if firstByte == 254 {
476 return Ok(());
478 }
479
480 parseTwoBytes(firstByte, bits.readBits(8)?, &mut cValues);
481
482 for cValue in cValues {
483 match shift {
486 0 => {
487 if cValue < 3 {
488 shift = cValue + 1;
489 } else if cValue < TEXT_BASIC_SET_CHARS.len() as u32 {
490 let textChar = TEXT_BASIC_SET_CHARS[cValue as usize];
491 if upperShift {
492 result.append_char(
493 char::from_u32(textChar as u32 + 128).ok_or(Exceptions::PARSE)?,
494 );
495 upperShift = false;
496 } else {
497 result.append_char(textChar);
498 }
499 } else {
500 return Err(Exceptions::FORMAT);
501 }
502 }
503 1 => {
504 if upperShift {
505 result.append_char(char::from_u32(cValue + 128).ok_or(Exceptions::PARSE)?);
506 upperShift = false;
507 } else {
508 result.append_char(char::from_u32(cValue).ok_or(Exceptions::PARSE)?);
509 }
510 shift = 0;
511 }
512
513 2 => {
514 if cValue < TEXT_SHIFT2_SET_CHARS.len() as u32 {
516 let textChar = TEXT_SHIFT2_SET_CHARS[cValue as usize];
517 if upperShift {
518 result.append_char(
519 char::from_u32(textChar as u32 + 128).ok_or(Exceptions::PARSE)?,
520 );
521 upperShift = false;
522 } else {
523 result.append_char(textChar);
524 }
525 } else {
526 match cValue {
527 27 => {
528 fnc1positions.push(result.len());
530 result.append_char(29 as char); }
532 30 =>
533 {
535 upperShift = true
536 }
537
538 _ => return Err(Exceptions::FORMAT),
539 }
540 }
541 shift = 0;
542 }
543 3 => {
544 if cValue < TEXT_SHIFT3_SET_CHARS.len() as u32 {
545 let textChar = TEXT_SHIFT3_SET_CHARS[cValue as usize];
546 if upperShift {
547 result.append_char(
548 char::from_u32(textChar as u32 + 128).ok_or(Exceptions::PARSE)?,
549 );
550 upperShift = false;
551 } else {
552 result.append_char(textChar);
553 }
554 shift = 0;
555 } else {
556 return Err(Exceptions::FORMAT);
557 }
558 }
559
560 _ => return Err(Exceptions::FORMAT),
561 }
562 }
563 if bits.available() == 0 {
564 break;
565 }
566 } Ok(())
569}
570
571fn decodeAnsiX12Segment(bits: &mut BitSource, result: &mut ECIStringBuilder) -> Result<()> {
575 let mut cValues = [0; 3]; loop {
580 if bits.available() == 8 {
582 return Ok(());
583 }
584 let firstByte = bits.readBits(8)?;
585 if firstByte == 254 {
586 return Ok(());
588 }
589
590 parseTwoBytes(firstByte, bits.readBits(8)?, &mut cValues);
591
592 for cValue in cValues {
593 match cValue {
596 0 =>
597 {
599 result.append_char('\r')
600 }
601
602 1 =>
603 {
605 result.append_char('*')
606 }
607
608 2 =>
609 {
611 result.append_char('>')
612 }
613
614 3 =>
615 {
617 result.append_char(' ')
618 }
619
620 _ => {
621 if cValue < 14 {
622 result.append_char(char::from_u32(cValue + 44).ok_or(Exceptions::PARSE)?);
624 } else if cValue < 40 {
625 result.append_char(char::from_u32(cValue + 51).ok_or(Exceptions::PARSE)?);
627 } else {
628 return Err(Exceptions::FORMAT);
629 }
630 }
631 }
632 }
633 if bits.available() == 0 {
634 break;
635 }
636 } Ok(())
639}
640
641fn parseTwoBytes(firstByte: u32, secondByte: u32, result: &mut [u32]) {
642 let mut fullBitValue = (firstByte << 8) + secondByte - 1;
643 let mut temp = fullBitValue / 1600;
644 result[0] = temp;
645 fullBitValue -= temp * 1600;
646 temp = fullBitValue / 40;
647 result[1] = temp;
648 result[2] = fullBitValue - temp * 40;
649}
650
651fn decodeEdifactSegment(bits: &mut BitSource, result: &mut ECIStringBuilder) -> Result<()> {
655 loop {
656 if bits.available() <= 16 {
658 return Ok(());
659 }
660
661 for _i in 0..4 {
662 let mut edifactValue = bits.readBits(6)?;
664
665 if edifactValue == 0x1F {
667 let bitsLeft = 8 - bits.getBitOffset();
670 if bitsLeft != 8 {
671 bits.readBits(bitsLeft)?;
672 }
673 return Ok(());
674 }
675
676 if (edifactValue & 0x20) == 0 {
677 edifactValue |= 0x40; }
680 result.append_char(char::from_u32(edifactValue).ok_or(Exceptions::PARSE)?);
681 }
682
683 if bits.available() == 0 {
684 break;
685 }
686 }
687
688 Ok(())
689}
690
691fn decodeBase256Segment(
695 bits: &mut BitSource,
696 result: &mut ECIStringBuilder,
697 byteSegments: &mut Vec<Vec<u8>>,
698) -> Result<()> {
699 let mut codewordPosition = 1 + bits.getByteOffset(); let d1 = unrandomize255State(bits.readBits(8)?, codewordPosition);
702 codewordPosition += 1;
703 let count;
704 if d1 == 0 {
705 count = bits.available() as u32 / 8;
707 } else if d1 < 250 {
708 count = d1;
709 } else {
710 count = 250 * (d1 - 249) + unrandomize255State(bits.readBits(8)?, codewordPosition);
711 codewordPosition += 1;
712 }
713
714 let mut bytes = vec![0u8; count as usize];
721 for byte in bytes.iter_mut().take(count as usize) {
722 if bits.available() < 8 {
725 return Err(Exceptions::FORMAT);
726 }
727 *byte = unrandomize255State(bits.readBits(8)?, codewordPosition) as u8;
728 codewordPosition += 1;
729 }
730 result.append_string(&CharacterSet::ISO8859_1.decode(&bytes)?);
731 byteSegments.push(bytes);
732
733 Ok(())
734}
735
736fn decodeECISegment(bits: &mut BitSource, result: &mut ECIStringBuilder) -> Result<bool> {
740 let firstByte = bits.readBits(8)?;
741 if firstByte <= 127 {
742 result.append_eci(Eci::from(firstByte - 1));
743 return Ok(true);
744 }
745
746 let secondByte = bits.readBits(8)?;
747 if firstByte <= 191 {
748 result.append_eci(Eci::from((firstByte - 128) * 254 + 127 + secondByte - 1));
749 return Ok((firstByte - 128) * 254 + 127 + secondByte - 1 > 900);
750 }
751
752 let thirdByte = bits.readBits(8)?;
753
754 result.append_eci(Eci::from(
755 (firstByte - 192) * 64516 + 16383 + (secondByte - 1) * 254 + thirdByte - 1,
756 ));
757 Ok((firstByte - 192) * 64516 + 16383 + (secondByte - 1) * 254 + thirdByte - 1 > 900)
758}
759
760fn parse_structured_append(bits: &mut BitSource, sai: &mut StructuredAppendInfo) -> Result<()> {
764 let symbolSequenceIndicator = bits.readBits(8)?;
766 sai.index = (symbolSequenceIndicator >> 4) as i32;
767 sai.count = (17 - (symbolSequenceIndicator & 0x0F)) as i32; if sai.count == 17 || sai.count <= sai.index
770 {
772 sai.count = 0; }
774
775 let fileId1 = bits.readBits(8)?; let fileId2 = bits.readBits(8)?; sai.id = ((fileId1 << 8) | fileId2).to_string();
781 Ok(())
782}
783struct StructuredAppendInfo {
784 index: i32, count: i32, id: String,
787}
788
789impl Default for StructuredAppendInfo {
790 fn default() -> Self {
791 Self {
792 index: -1,
793 count: -1,
794 id: Default::default(),
795 }
796 }
797}
798
799fn unrandomize255State(randomizedBase256Codeword: u32, base256CodewordPosition: usize) -> u32 {
803 let pseudoRandomNumber = ((149 * base256CodewordPosition as u32) % 255) + 1;
804 let tempVariable = randomizedBase256Codeword as i32 - pseudoRandomNumber as i32;
805
806 if tempVariable >= 0 {
807 tempVariable as u32
808 } else {
809 (tempVariable + 256) as u32
810 }
811}
812
813#[cfg(test)]
814mod tests {
815 use crate::datamatrix::decoder::decoded_bit_stream_parser;
816
817 #[test]
818 fn testAsciiStandardDecode() {
819 let bytes = [
821 (b'a' + 1),
822 (b'b' + 1),
823 (b'c' + 1),
824 (b'A' + 1),
825 (b'B' + 1),
826 (b'C' + 1),
827 ];
828 let decodedString = String::from(
829 decoded_bit_stream_parser::decode(&bytes, false)
830 .expect("decode")
831 .getText(),
832 );
833 assert_eq!("abcABC", decodedString);
834 }
835
836 #[test]
837 fn testAsciiDoubleDigitDecode() {
838 let bytes = [130, (1 + 130), (98 + 130), (99 + 130)];
840 let decodedString = String::from(
841 decoded_bit_stream_parser::decode(&bytes, false)
842 .expect("decode")
843 .getText(),
844 );
845 assert_eq!("00019899", decodedString);
846 }
847
848 }