mirror of
https://github.com/starovoid/rxing.git
synced 2026-07-26 04:12:34 +00:00
ported test SimpleSJIS and fixed regression pdf417
This commit is contained in:
@@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user