From 23951ac87c390135d5001df70781620c4fc3b825 Mon Sep 17 00:00:00 2001 From: Henry Schimke Date: Fri, 14 Apr 2023 11:03:04 -0500 Subject: [PATCH] ported test SimpleSJIS and fixed regression pdf417 --- src/common/bit_array.rs | 17 +++--- src/common/cpp_essentials/decoder_result.rs | 2 +- src/common/eci.rs | 17 ++++++ src/common/eci_string_builder.rs | 56 +++++++++++++++---- src/qrcode/cpp_port/decoder.rs | 16 +++--- .../test/QRDecodedBitStreamParserTest.rs | 54 +++++++++--------- 6 files changed, 109 insertions(+), 53 deletions(-) diff --git a/src/common/bit_array.rs b/src/common/bit_array.rs index 26c1851..4155c37 100644 --- a/src/common/bit_array.rs +++ b/src/common/bit_array.rs @@ -405,12 +405,15 @@ impl Default for BitArray { impl Into> for BitArray { fn into(self) -> Vec { - let mut arr = vec![0; self.get_size()]; - for x in 0..self.get_size() { - if self.get(x) { - arr[x] = 1; - } - } - arr + let mut array = vec![0; self.getSizeInBytes()]; + self.toBytes(0, &mut array, 0, self.getSizeInBytes()); + array + // let mut arr = vec![0; self.get_size()]; + // for x in 0..self.get_size() { + // if self.get(x) { + // arr[x] = 1; + // } + // } + // arr } } diff --git a/src/common/cpp_essentials/decoder_result.rs b/src/common/cpp_essentials/decoder_result.rs index 52862a0..c1d25d3 100644 --- a/src/common/cpp_essentials/decoder_result.rs +++ b/src/common/cpp_essentials/decoder_result.rs @@ -217,7 +217,7 @@ where vec!['1'; s.code as usize].into_iter().collect::(), char::from( s.modifier - + if self.content.is_eci { + + if self.content.has_eci { s.eciModifierOffset } else { 0 diff --git a/src/common/eci.rs b/src/common/eci.rs index da47109..3d8e6ce 100644 --- a/src/common/eci.rs +++ b/src/common/eci.rs @@ -1,7 +1,11 @@ use std::fmt::Display; +use crate::Exceptions; + use super::CharacterSet; +use crate::common::Result; + #[derive(Copy, Clone, Debug, PartialEq, Eq)] pub enum Eci { Unknown = -1, @@ -44,6 +48,19 @@ impl Eci { pub fn can_encode(self) -> bool { (self as i32) >= 899 } + + pub fn try_from_i32(value: i32) -> Result { + let v = Self::from(value); + if v == Eci::Unknown { + Err(Exceptions::ILLEGAL_ARGUMENT) + } else { + Ok(v) + } + } + + pub fn try_from_u32(value: u32) -> Result { + Self::try_from_i32(value as i32) + } } impl From for Eci { diff --git a/src/common/eci_string_builder.rs b/src/common/eci_string_builder.rs index b791d61..2aee154 100644 --- a/src/common/eci_string_builder.rs +++ b/src/common/eci_string_builder.rs @@ -21,9 +21,9 @@ // import java.nio.charset.Charset; // import java.nio.charset.StandardCharsets; -use std::fmt; +use std::{collections::HashMap, fmt}; -use super::{CharacterSet, Eci}; +use super::{CharacterSet, Eci, StringUtils}; /** * Class that converts a sequence of ECIs and bytes into a string @@ -32,7 +32,7 @@ use super::{CharacterSet, Eci}; */ #[derive(Default, PartialEq, Eq, Debug, Clone)] pub struct ECIStringBuilder { - pub is_eci: bool, + pub has_eci: bool, eci_result: Option, bytes: Vec, eci_positions: Vec<(Eci, usize, usize)>, // (Eci, start, end) @@ -45,7 +45,7 @@ impl ECIStringBuilder { eci_result: None, bytes: Vec::with_capacity(initial_capacity), eci_positions: Vec::default(), - is_eci: false, + has_eci: false, symbology: SymbologyIdentifier::default(), } } @@ -109,11 +109,12 @@ impl ECIStringBuilder { */ pub fn append_eci(&mut self, eci: Eci) { self.eci_result = None; - if !self.is_eci && eci != Eci::ISO8859_1 { - self.is_eci = true; + + if !self.has_eci && eci != Eci::ISO8859_1 { + self.has_eci = true; } - if self.is_eci { + if self.has_eci { if let Some(last) = self.eci_positions.last_mut() { last.2 = self.bytes.len() } @@ -124,7 +125,17 @@ impl ECIStringBuilder { /// Change the current encoding characterset, finding an eci to do so pub fn switch_encoding(&mut self, charset: CharacterSet) { - self.append_eci(Eci::from(charset)) + //self.append_eci(Eci::from(charset)) + if (false && !self.has_eci) { + self.eci_positions.clear(); + } + if (false || !self.has_eci) + //{self.eci_positions.push_back({eci, Size(bytes)});} + { + self.append_eci(Eci::from(charset)) + } + + self.has_eci |= false; } /// Finishes encoding anything in the buffer using the current ECI and resets. @@ -133,7 +144,7 @@ impl ECIStringBuilder { pub fn encodeCurrentBytesIfAny(&self) -> String { let mut encoded_string = String::with_capacity(self.bytes.len()); // First encode the first set - let (_, end, _) = + let (_eci, end, _) = *self .eci_positions .first() @@ -143,6 +154,10 @@ impl ECIStringBuilder { &Self::encode_segment(&self.bytes[0..end], Eci::ISO8859_1).unwrap_or_default(), ); + if end == self.bytes.len() { + return encoded_string; + } + // If there are more sets, encode each of them in turn for (eci, eci_start, eci_end) in &self.eci_positions { // let (_,end) = *self.eci_positions.first().unwrap_or(&(*eci, self.bytes.len())); @@ -161,20 +176,41 @@ impl ECIStringBuilder { } fn encode_segment(bytes: &[u8], eci: Eci) -> Option { + let mut not_encoded_yet = true; let mut encoded_string = String::with_capacity(bytes.len()); if ![Eci::Binary, Eci::Unknown].contains(&eci) { if eci == Eci::UTF8 { if !bytes.is_empty() { encoded_string.push_str(&CharacterSet::UTF8.decode(bytes).ok()?); + not_encoded_yet = false; } else { return None; } } else if !bytes.is_empty() { encoded_string.push_str(&CharacterSet::from(eci).decode(bytes).ok()?); + not_encoded_yet = false; } else { return None; } - } else { + } else if eci == Eci::Unknown { + /* // This probably should never be used, it's here just in case I don't understand what's + // going on. + let cs = CharacterSet::from(Eci::ISO8859_1); + if let Ok(enc_str) = cs.decode(bytes) { + encoded_string.push_str(&enc_str); + not_encoded_yet = false; + } + + else */ + if let Some(found_encoding) = StringUtils::guessCharset(bytes, &HashMap::default()) { + if let Ok(found_encoded_str) = found_encoding.decode(bytes) { + encoded_string.push_str(&found_encoded_str); + not_encoded_yet = false; + } + } + } + + if not_encoded_yet { for byte in bytes { encoded_string.push(char::from(*byte)) } diff --git a/src/qrcode/cpp_port/decoder.rs b/src/qrcode/cpp_port/decoder.rs index bda6371..279b4cf 100644 --- a/src/qrcode/cpp_port/decoder.rs +++ b/src/qrcode/cpp_port/decoder.rs @@ -125,7 +125,7 @@ pub fn DecodeByteSegment( result.switch_encoding(CharacterSet::Unknown); result.reserve(count as usize); - for i in 0..count { + for _i in 0..count { // for (int i = 0; i < count; i++) *result += (bits.readBits(8)?) as u8; } @@ -297,7 +297,7 @@ pub fn DecodeBitStream( let mut structuredAppend = StructuredAppendInfo::default(); let modeBitLength = Mode::get_codec_mode_bits_length(version); - let res = (|| { + let _res = (|| { while (!IsEndOfStream(&mut bits, version)?) { let mode: Mode; if (modeBitLength == 0) { @@ -361,26 +361,26 @@ pub fn DecodeBitStream( // throw FormatError("Unsupported HANZI subset"); } let count = bits.readBits(mode.CharacterCountBits(version) as usize)?; - DecodeHanziSegment(&mut bits, count, &mut result); + DecodeHanziSegment(&mut bits, count, &mut result)?; } _ => { // "Normal" QR code modes: // How many characters will follow, encoded in this mode? let count = bits.readBits(mode.CharacterCountBits(version) as usize)?; match (mode) { - Mode::NUMERIC => DecodeNumericSegment(&mut bits, count, &mut result), + Mode::NUMERIC => DecodeNumericSegment(&mut bits, count, &mut result)?, Mode::ALPHANUMERIC => { - DecodeAlphanumericSegment(&mut bits, count, &mut result) + DecodeAlphanumericSegment(&mut bits, count, &mut result)? } - Mode::BYTE => DecodeByteSegment(&mut bits, count, &mut result), - Mode::KANJI => DecodeKanjiSegment(&mut bits, count, &mut result), + Mode::BYTE => DecodeByteSegment(&mut bits, count, &mut result)?, + Mode::KANJI => DecodeKanjiSegment(&mut bits, count, &mut result)?, _ => return Err(Exceptions::format_with("Invalid CodecMode")), //throw FormatError("Invalid CodecMode"); }; } } } Ok(()) - })(); + })()?; // } catch (std::out_of_range& e) { // see BitSource::readBits // error = FormatError("Truncated bit stream"); // } catch (Error e) { diff --git a/src/qrcode/cpp_port/test/QRDecodedBitStreamParserTest.rs b/src/qrcode/cpp_port/test/QRDecodedBitStreamParserTest.rs index c00b897..9cfb93f 100644 --- a/src/qrcode/cpp_port/test/QRDecodedBitStreamParserTest.rs +++ b/src/qrcode/cpp_port/test/QRDecodedBitStreamParserTest.rs @@ -36,11 +36,11 @@ use crate::{ #[test] fn SimpleByteMode() { let mut ba = BitArray::new(); - ba.appendBits(0x04, 4); // Byte mode - ba.appendBits(0x03, 8); // 3 bytes - ba.appendBits(0xF1, 8); - ba.appendBits(0xF2, 8); - ba.appendBits(0xF3, 8); + ba.appendBits(0x04, 4).unwrap(); // Byte mode + ba.appendBits(0x03, 8).unwrap(); // 3 bytes + ba.appendBits(0xF1, 8).unwrap(); + ba.appendBits(0xF2, 8).unwrap(); + ba.appendBits(0xF3, 8).unwrap(); let bytes: Vec = ba.into(); let result = DecodeBitStream( &bytes, @@ -57,12 +57,12 @@ fn SimpleByteMode() { #[test] fn SimpleSJIS() { let mut ba = BitArray::new(); - ba.appendBits(0x04, 4); // Byte mode - ba.appendBits(0x04, 8); // 4 bytes - ba.appendBits(0xA1, 8); - ba.appendBits(0xA2, 8); - ba.appendBits(0xA3, 8); - ba.appendBits(0xD0, 8); + ba.appendBits(0x04, 4).expect("append"); // Byte mode + ba.appendBits(0x04, 8).expect("append"); // 4 bytes + ba.appendBits(0xA1, 8).expect("append"); + ba.appendBits(0xA2, 8).expect("append"); + ba.appendBits(0xA3, 8).expect("append"); + ba.appendBits(0xD0, 8).expect("append"); let bytes: Vec = ba.into(); let result = DecodeBitStream( &bytes, @@ -78,13 +78,13 @@ fn SimpleSJIS() { #[test] fn ECI() { let mut ba = BitArray::new(); - ba.appendBits(0x07, 4); // ECI mode - ba.appendBits(0x02, 8); // ECI 2 = CP437 encoding - ba.appendBits(0x04, 4); // Byte mode - ba.appendBits(0x03, 8); // 3 bytes - ba.appendBits(0xA1, 8); - ba.appendBits(0xA2, 8); - ba.appendBits(0xA3, 8); + ba.appendBits(0x07, 4).expect("append"); // ECI mode + ba.appendBits(0x02, 8).expect("append"); // ECI 2 = CP437 encoding + ba.appendBits(0x04, 4).expect("append"); // Byte mode + ba.appendBits(0x03, 8).expect("append"); // 3 bytes + ba.appendBits(0xA1, 8).expect("append"); + ba.appendBits(0xA2, 8).expect("append"); + ba.appendBits(0xA3, 8).expect("append"); let bytes: Vec = ba.into(); let result = DecodeBitStream( &bytes, @@ -100,10 +100,10 @@ fn ECI() { #[test] fn Hanzi() { let mut ba = BitArray::new(); - ba.appendBits(0x0D, 4); // Hanzi mode - ba.appendBits(0x01, 4); // Subset 1 = GB2312 encoding - ba.appendBits(0x01, 8); // 1 characters - ba.appendBits(0x03C1, 13); + ba.appendBits(0x0D, 4).expect("append"); // Hanzi mode + ba.appendBits(0x01, 4).expect("append"); // Subset 1 = GB2312 encoding + ba.appendBits(0x01, 8).expect("append"); // 1 characters + ba.appendBits(0x03C1, 13).expect("append"); let bytes: Vec = ba.into(); let result = DecodeBitStream( &bytes, @@ -119,11 +119,11 @@ fn Hanzi() { #[test] fn HanziLevel1() { let mut ba = BitArray::new(); - ba.appendBits(0x0D, 4); // Hanzi mode - ba.appendBits(0x01, 4); // Subset 1 = GB2312 encoding - ba.appendBits(0x01, 8); // 1 characters - // A5A2 (U+30A2) => A5A2 - A1A1 = 401, 4*60 + 01 = 0181 - ba.appendBits(0x0181, 13); + ba.appendBits(0x0D, 4).expect("append"); // Hanzi mode + ba.appendBits(0x01, 4).expect("append"); // Subset 1 = GB2312 encoding + ba.appendBits(0x01, 8).expect("append"); // 1 characters + // A5A2 (U+30A2) => A5A2 - A1A1 = 401, 4*60 + 01 = 0181 + ba.appendBits(0x0181, 13).expect("append"); let bytes: Vec = ba.into();