ported test SimpleSJIS and fixed regression pdf417

This commit is contained in:
Henry Schimke
2023-04-14 11:03:04 -05:00
parent 1900e1ca57
commit 23951ac87c
6 changed files with 109 additions and 53 deletions

View File

@@ -405,12 +405,15 @@ impl Default for BitArray {
impl Into<Vec<u8>> for BitArray { impl Into<Vec<u8>> for BitArray {
fn into(self) -> Vec<u8> { fn into(self) -> Vec<u8> {
let mut arr = vec![0; self.get_size()]; let mut array = vec![0; self.getSizeInBytes()];
for x in 0..self.get_size() { self.toBytes(0, &mut array, 0, self.getSizeInBytes());
if self.get(x) { array
arr[x] = 1; // let mut arr = vec![0; self.get_size()];
} // for x in 0..self.get_size() {
} // if self.get(x) {
arr // arr[x] = 1;
// }
// }
// arr
} }
} }

View File

@@ -217,7 +217,7 @@ where
vec!['1'; s.code as usize].into_iter().collect::<String>(), vec!['1'; s.code as usize].into_iter().collect::<String>(),
char::from( char::from(
s.modifier s.modifier
+ if self.content.is_eci { + if self.content.has_eci {
s.eciModifierOffset s.eciModifierOffset
} else { } else {
0 0

View File

@@ -1,7 +1,11 @@
use std::fmt::Display; use std::fmt::Display;
use crate::Exceptions;
use super::CharacterSet; use super::CharacterSet;
use crate::common::Result;
#[derive(Copy, Clone, Debug, PartialEq, Eq)] #[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum Eci { pub enum Eci {
Unknown = -1, Unknown = -1,
@@ -44,6 +48,19 @@ impl Eci {
pub fn can_encode(self) -> bool { pub fn can_encode(self) -> bool {
(self as i32) >= 899 (self as i32) >= 899
} }
pub fn try_from_i32(value: i32) -> Result<Self> {
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> {
Self::try_from_i32(value as i32)
}
} }
impl From<u32> for Eci { impl From<u32> for Eci {

View File

@@ -21,9 +21,9 @@
// import java.nio.charset.Charset; // import java.nio.charset.Charset;
// import java.nio.charset.StandardCharsets; // 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 * 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)] #[derive(Default, PartialEq, Eq, Debug, Clone)]
pub struct ECIStringBuilder { pub struct ECIStringBuilder {
pub is_eci: bool, pub has_eci: bool,
eci_result: Option<String>, eci_result: Option<String>,
bytes: Vec<u8>, bytes: Vec<u8>,
eci_positions: Vec<(Eci, usize, usize)>, // (Eci, start, end) eci_positions: Vec<(Eci, usize, usize)>, // (Eci, start, end)
@@ -45,7 +45,7 @@ impl ECIStringBuilder {
eci_result: None, eci_result: None,
bytes: Vec::with_capacity(initial_capacity), bytes: Vec::with_capacity(initial_capacity),
eci_positions: Vec::default(), eci_positions: Vec::default(),
is_eci: false, has_eci: false,
symbology: SymbologyIdentifier::default(), symbology: SymbologyIdentifier::default(),
} }
} }
@@ -109,11 +109,12 @@ impl ECIStringBuilder {
*/ */
pub fn append_eci(&mut self, eci: Eci) { pub fn append_eci(&mut self, eci: Eci) {
self.eci_result = None; 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() { if let Some(last) = self.eci_positions.last_mut() {
last.2 = self.bytes.len() last.2 = self.bytes.len()
} }
@@ -124,7 +125,17 @@ impl ECIStringBuilder {
/// Change the current encoding characterset, finding an eci to do so /// Change the current encoding characterset, finding an eci to do so
pub fn switch_encoding(&mut self, charset: CharacterSet) { 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. /// Finishes encoding anything in the buffer using the current ECI and resets.
@@ -133,7 +144,7 @@ impl ECIStringBuilder {
pub fn encodeCurrentBytesIfAny(&self) -> String { pub fn encodeCurrentBytesIfAny(&self) -> String {
let mut encoded_string = String::with_capacity(self.bytes.len()); let mut encoded_string = String::with_capacity(self.bytes.len());
// First encode the first set // First encode the first set
let (_, end, _) = let (_eci, end, _) =
*self *self
.eci_positions .eci_positions
.first() .first()
@@ -143,6 +154,10 @@ impl ECIStringBuilder {
&Self::encode_segment(&self.bytes[0..end], Eci::ISO8859_1).unwrap_or_default(), &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 // If there are more sets, encode each of them in turn
for (eci, eci_start, eci_end) in &self.eci_positions { for (eci, eci_start, eci_end) in &self.eci_positions {
// let (_,end) = *self.eci_positions.first().unwrap_or(&(*eci, self.bytes.len())); // 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<String> { fn encode_segment(bytes: &[u8], eci: Eci) -> Option<String> {
let mut not_encoded_yet = true;
let mut encoded_string = String::with_capacity(bytes.len()); let mut encoded_string = String::with_capacity(bytes.len());
if ![Eci::Binary, Eci::Unknown].contains(&eci) { if ![Eci::Binary, Eci::Unknown].contains(&eci) {
if eci == Eci::UTF8 { if eci == Eci::UTF8 {
if !bytes.is_empty() { if !bytes.is_empty() {
encoded_string.push_str(&CharacterSet::UTF8.decode(bytes).ok()?); encoded_string.push_str(&CharacterSet::UTF8.decode(bytes).ok()?);
not_encoded_yet = false;
} else { } else {
return None; return None;
} }
} else if !bytes.is_empty() { } else if !bytes.is_empty() {
encoded_string.push_str(&CharacterSet::from(eci).decode(bytes).ok()?); encoded_string.push_str(&CharacterSet::from(eci).decode(bytes).ok()?);
not_encoded_yet = false;
} else { } else {
return None; 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 { for byte in bytes {
encoded_string.push(char::from(*byte)) encoded_string.push(char::from(*byte))
} }

View File

@@ -125,7 +125,7 @@ pub fn DecodeByteSegment(
result.switch_encoding(CharacterSet::Unknown); result.switch_encoding(CharacterSet::Unknown);
result.reserve(count as usize); result.reserve(count as usize);
for i in 0..count { for _i in 0..count {
// for (int i = 0; i < count; i++) // for (int i = 0; i < count; i++)
*result += (bits.readBits(8)?) as u8; *result += (bits.readBits(8)?) as u8;
} }
@@ -297,7 +297,7 @@ pub fn DecodeBitStream(
let mut structuredAppend = StructuredAppendInfo::default(); let mut structuredAppend = StructuredAppendInfo::default();
let modeBitLength = Mode::get_codec_mode_bits_length(version); let modeBitLength = Mode::get_codec_mode_bits_length(version);
let res = (|| { let _res = (|| {
while (!IsEndOfStream(&mut bits, version)?) { while (!IsEndOfStream(&mut bits, version)?) {
let mode: Mode; let mode: Mode;
if (modeBitLength == 0) { if (modeBitLength == 0) {
@@ -361,26 +361,26 @@ pub fn DecodeBitStream(
// throw FormatError("Unsupported HANZI subset"); // throw FormatError("Unsupported HANZI subset");
} }
let count = bits.readBits(mode.CharacterCountBits(version) as usize)?; 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: // "Normal" QR code modes:
// How many characters will follow, encoded in this mode? // How many characters will follow, encoded in this mode?
let count = bits.readBits(mode.CharacterCountBits(version) as usize)?; let count = bits.readBits(mode.CharacterCountBits(version) as usize)?;
match (mode) { match (mode) {
Mode::NUMERIC => DecodeNumericSegment(&mut bits, count, &mut result), Mode::NUMERIC => DecodeNumericSegment(&mut bits, count, &mut result)?,
Mode::ALPHANUMERIC => { Mode::ALPHANUMERIC => {
DecodeAlphanumericSegment(&mut bits, count, &mut result) DecodeAlphanumericSegment(&mut bits, count, &mut result)?
} }
Mode::BYTE => DecodeByteSegment(&mut bits, count, &mut result), Mode::BYTE => DecodeByteSegment(&mut bits, count, &mut result)?,
Mode::KANJI => DecodeKanjiSegment(&mut bits, count, &mut result), Mode::KANJI => DecodeKanjiSegment(&mut bits, count, &mut result)?,
_ => return Err(Exceptions::format_with("Invalid CodecMode")), //throw FormatError("Invalid CodecMode"); _ => return Err(Exceptions::format_with("Invalid CodecMode")), //throw FormatError("Invalid CodecMode");
}; };
} }
} }
} }
Ok(()) Ok(())
})(); })()?;
// } catch (std::out_of_range& e) { // see BitSource::readBits // } catch (std::out_of_range& e) { // see BitSource::readBits
// error = FormatError("Truncated bit stream"); // error = FormatError("Truncated bit stream");
// } catch (Error e) { // } catch (Error e) {

View File

@@ -36,11 +36,11 @@ use crate::{
#[test] #[test]
fn SimpleByteMode() { fn SimpleByteMode() {
let mut ba = BitArray::new(); let mut ba = BitArray::new();
ba.appendBits(0x04, 4); // Byte mode ba.appendBits(0x04, 4).unwrap(); // Byte mode
ba.appendBits(0x03, 8); // 3 bytes ba.appendBits(0x03, 8).unwrap(); // 3 bytes
ba.appendBits(0xF1, 8); ba.appendBits(0xF1, 8).unwrap();
ba.appendBits(0xF2, 8); ba.appendBits(0xF2, 8).unwrap();
ba.appendBits(0xF3, 8); ba.appendBits(0xF3, 8).unwrap();
let bytes: Vec<u8> = ba.into(); let bytes: Vec<u8> = ba.into();
let result = DecodeBitStream( let result = DecodeBitStream(
&bytes, &bytes,
@@ -57,12 +57,12 @@ fn SimpleByteMode() {
#[test] #[test]
fn SimpleSJIS() { fn SimpleSJIS() {
let mut ba = BitArray::new(); let mut ba = BitArray::new();
ba.appendBits(0x04, 4); // Byte mode ba.appendBits(0x04, 4).expect("append"); // Byte mode
ba.appendBits(0x04, 8); // 4 bytes ba.appendBits(0x04, 8).expect("append"); // 4 bytes
ba.appendBits(0xA1, 8); ba.appendBits(0xA1, 8).expect("append");
ba.appendBits(0xA2, 8); ba.appendBits(0xA2, 8).expect("append");
ba.appendBits(0xA3, 8); ba.appendBits(0xA3, 8).expect("append");
ba.appendBits(0xD0, 8); ba.appendBits(0xD0, 8).expect("append");
let bytes: Vec<u8> = ba.into(); let bytes: Vec<u8> = ba.into();
let result = DecodeBitStream( let result = DecodeBitStream(
&bytes, &bytes,
@@ -78,13 +78,13 @@ fn SimpleSJIS() {
#[test] #[test]
fn ECI() { fn ECI() {
let mut ba = BitArray::new(); let mut ba = BitArray::new();
ba.appendBits(0x07, 4); // ECI mode ba.appendBits(0x07, 4).expect("append"); // ECI mode
ba.appendBits(0x02, 8); // ECI 2 = CP437 encoding ba.appendBits(0x02, 8).expect("append"); // ECI 2 = CP437 encoding
ba.appendBits(0x04, 4); // Byte mode ba.appendBits(0x04, 4).expect("append"); // Byte mode
ba.appendBits(0x03, 8); // 3 bytes ba.appendBits(0x03, 8).expect("append"); // 3 bytes
ba.appendBits(0xA1, 8); ba.appendBits(0xA1, 8).expect("append");
ba.appendBits(0xA2, 8); ba.appendBits(0xA2, 8).expect("append");
ba.appendBits(0xA3, 8); ba.appendBits(0xA3, 8).expect("append");
let bytes: Vec<u8> = ba.into(); let bytes: Vec<u8> = ba.into();
let result = DecodeBitStream( let result = DecodeBitStream(
&bytes, &bytes,
@@ -100,10 +100,10 @@ fn ECI() {
#[test] #[test]
fn Hanzi() { fn Hanzi() {
let mut ba = BitArray::new(); let mut ba = BitArray::new();
ba.appendBits(0x0D, 4); // Hanzi mode ba.appendBits(0x0D, 4).expect("append"); // Hanzi mode
ba.appendBits(0x01, 4); // Subset 1 = GB2312 encoding ba.appendBits(0x01, 4).expect("append"); // Subset 1 = GB2312 encoding
ba.appendBits(0x01, 8); // 1 characters ba.appendBits(0x01, 8).expect("append"); // 1 characters
ba.appendBits(0x03C1, 13); ba.appendBits(0x03C1, 13).expect("append");
let bytes: Vec<u8> = ba.into(); let bytes: Vec<u8> = ba.into();
let result = DecodeBitStream( let result = DecodeBitStream(
&bytes, &bytes,
@@ -119,11 +119,11 @@ fn Hanzi() {
#[test] #[test]
fn HanziLevel1() { fn HanziLevel1() {
let mut ba = BitArray::new(); let mut ba = BitArray::new();
ba.appendBits(0x0D, 4); // Hanzi mode ba.appendBits(0x0D, 4).expect("append"); // Hanzi mode
ba.appendBits(0x01, 4); // Subset 1 = GB2312 encoding ba.appendBits(0x01, 4).expect("append"); // Subset 1 = GB2312 encoding
ba.appendBits(0x01, 8); // 1 characters ba.appendBits(0x01, 8).expect("append"); // 1 characters
// A5A2 (U+30A2) => A5A2 - A1A1 = 401, 4*60 + 01 = 0181 // A5A2 (U+30A2) => A5A2 - A1A1 = 401, 4*60 + 01 = 0181
ba.appendBits(0x0181, 13); ba.appendBits(0x0181, 13).expect("append");
let bytes: Vec<u8> = ba.into(); let bytes: Vec<u8> = ba.into();