Skip to content

Commit

Permalink
Merge pull request #39 from cpwood/main
Browse files Browse the repository at this point in the history
Telepen support
  • Loading branch information
hschimke authored Jan 2, 2024
2 parents 84a54d4 + d43c525 commit aa7556d
Show file tree
Hide file tree
Showing 39 changed files with 939 additions and 4 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ resvg = {version = "0.35", optional = true, default-features=false}
serde = { version = "1.0", features = ["derive", "rc"], optional = true }
thiserror = "1.0.44"
multimap = "0.9"
bit_reverse = "0.1.8"

[dev-dependencies]
java-properties = "2.0"
Expand Down
14 changes: 13 additions & 1 deletion benches/benchmarks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use rxing::multi::{GenericMultipleBarcodeReader, MultipleBarcodeReader};
use rxing::oned::rss::expanded::RSSExpandedReader;
use rxing::oned::rss::RSS14Reader;
use rxing::oned::{
CodaBarReader, Code39Reader, Code93Reader, EAN13Reader, EAN8Reader, ITFReader, UPCAReader,
CodaBarReader, Code39Reader, Code93Reader, EAN13Reader, EAN8Reader, TelepenReader, ITFReader, UPCAReader,
UPCEReader,
};
use rxing::pdf417::PDF417Reader;
Expand Down Expand Up @@ -165,6 +165,17 @@ fn rss_expanded_benchmark(c: &mut Criterion) {
});
}

fn telepen_benchmark(c: &mut Criterion) {
let mut image = get_image("test_resources/blackbox/telepen-1/02.png");
let mut reader = TelepenReader::default();

c.bench_function("telepen", |b| {
b.iter(|| {
let _res = reader.decode(&mut image);
});
});
}

fn upca_benchmark(c: &mut Criterion) {
let mut image = get_image("test_resources/blackbox/upca-4/1.png");
c.bench_function("upca", |b| {
Expand Down Expand Up @@ -210,6 +221,7 @@ criterion_group!(
qrcode_benchmark,
rss14_benchmark,
rss_expanded_benchmark,
telepen_benchmark,
upca_benchmark,
upce_benchmark,
multi_barcode_benchmark
Expand Down
5 changes: 5 additions & 0 deletions src/barcode_format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,9 @@ pub enum BarcodeFormat {
/** RSS EXPANDED */
RSS_EXPANDED,

/** TELEPEN */
TELEPEN,

/** UPC-A 1D format. */
UPC_A,

Expand Down Expand Up @@ -107,6 +110,7 @@ impl Display for BarcodeFormat {
BarcodeFormat::MICRO_QR_CODE => "mqr",
BarcodeFormat::RSS_14 => "rss 14",
BarcodeFormat::RSS_EXPANDED => "rss expanded",
BarcodeFormat::TELEPEN => "telepen",
BarcodeFormat::UPC_A => "upc a",
BarcodeFormat::UPC_E => "upc e",
BarcodeFormat::UPC_EAN_EXTENSION => "upc/ean extension",
Expand Down Expand Up @@ -149,6 +153,7 @@ impl From<&str> for BarcodeFormat {
"rss 14" | "rss_14" | "rss14" | "gs1 databar" | "gs1 databar coupon"
| "gs1_databar_coupon" => BarcodeFormat::RSS_14,
"rss expanded" | "expanded rss" | "rss_expanded" => BarcodeFormat::RSS_EXPANDED,
"telepen" => BarcodeFormat::TELEPEN,
"upc a" | "upc_a" | "upca" => BarcodeFormat::UPC_A,
"upc e" | "upc_e" | "upce" => BarcodeFormat::UPC_E,
"upc ean extension" | "upc extension" | "ean extension" | "upc/ean extension"
Expand Down
11 changes: 11 additions & 0 deletions src/decode_hints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,12 @@ pub enum DecodeHintType {
*/
#[cfg(feature = "allow_forced_iso_ied_18004_compliance")]
QR_ASSUME_SPEC_CONFORM_INPUT,

/*
* Will translate the ASCII values parsed by the Telepen reader into the Telepen Numeric form.
*/
TELEPEN_AS_NUMERIC,

/*
* Data type the hint is expecting.
* Among the possible values the {@link Void} stands out as being used for
Expand Down Expand Up @@ -231,4 +237,9 @@ pub enum DecodeHintValue {
*/
#[cfg(feature = "allow_forced_iso_ied_18004_compliance")]
QrAssumeSpecConformInput(bool),

/**
* Translate the ASCII values parsed by the Telepen reader into the Telepen Numeric form; use {@link Boolean#TRUE}.
*/
TelepenAsNumeric(bool),
}
10 changes: 10 additions & 0 deletions src/encode_hints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,11 @@ pub enum EncodeHintType {
* exclusive.
*/
CODE128_COMPACT,

/*
* Will translate the numeric values received by the Telepen writer into the Telepen Alphanumeric form.
*/
TELEPEN_AS_NUMERIC,
}

#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
Expand Down Expand Up @@ -333,4 +338,9 @@ pub enum EncodeHintValue {
* exclusive.
*/
Code128Compact(bool),

/**
* Translate the numeric values received by the Telepen reader into the Telepen Alphaumeric form; use {@link Boolean#TRUE}.
*/
TelepenAsNumeric(bool),
}
3 changes: 2 additions & 1 deletion src/multi_format_reader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,8 @@ impl MultiFormatReader {
|| self.possible_formats.contains(&BarcodeFormat::CODE_128)
|| self.possible_formats.contains(&BarcodeFormat::ITF)
|| self.possible_formats.contains(&BarcodeFormat::RSS_14)
|| self.possible_formats.contains(&BarcodeFormat::RSS_EXPANDED);
|| self.possible_formats.contains(&BarcodeFormat::RSS_EXPANDED)
|| self.possible_formats.contains(&BarcodeFormat::TELEPEN);
if one_d && !self.try_harder {
if let Ok(res) = self.one_d_reader.decode_with_hints(image, &self.hints) {
return Ok(res);
Expand Down
3 changes: 2 additions & 1 deletion src/multi_format_writer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ use crate::{
datamatrix::DataMatrixWriter,
oned::{
CodaBarWriter, Code128Writer, Code39Writer, Code93Writer, EAN13Writer, EAN8Writer,
ITFWriter, UPCAWriter, UPCEWriter,
ITFWriter, TelepenWriter, UPCAWriter, UPCEWriter,
},
pdf417::PDF417Writer,
qrcode::QRCodeWriter,
Expand Down Expand Up @@ -70,6 +70,7 @@ impl Writer for MultiFormatWriter {
BarcodeFormat::PDF_417 => Box::<PDF417Writer>::default(),
BarcodeFormat::CODABAR => Box::<CodaBarWriter>::default(),
BarcodeFormat::DATA_MATRIX => Box::<DataMatrixWriter>::default(),
BarcodeFormat::TELEPEN => Box::<TelepenWriter>::default(),
BarcodeFormat::AZTEC => Box::<AztecWriter>::default(),
_ => {
return Err(Exceptions::illegal_argument_with(format!(
Expand Down
3 changes: 2 additions & 1 deletion src/multi_use_multi_format_reader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,8 @@ impl MultiUseMultiFormatReader {
|| self.possible_formats.contains(&BarcodeFormat::CODE_128)
|| self.possible_formats.contains(&BarcodeFormat::ITF)
|| self.possible_formats.contains(&BarcodeFormat::RSS_14)
|| self.possible_formats.contains(&BarcodeFormat::RSS_EXPANDED);
|| self.possible_formats.contains(&BarcodeFormat::RSS_EXPANDED)
|| self.possible_formats.contains(&BarcodeFormat::TELEPEN);
if one_d && !self.try_harder {
if let Ok(res) = self.one_d_reader.decode_with_hints(image, &self.hints) {
return Ok(res);
Expand Down
8 changes: 8 additions & 0 deletions src/oned/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ pub use code_128_reader::*;
mod itf_reader;
pub use itf_reader::*;

mod telepen_reader;
pub use telepen_reader::*;

mod upc_ean_reader;
pub use upc_ean_reader::*;

Expand Down Expand Up @@ -77,6 +80,9 @@ pub use upc_a_writer::*;
mod ean_13_writer;
pub use ean_13_writer::*;

mod telepen_writer;
pub use telepen_writer::*;

mod upc_ean_writer;
pub use upc_ean_writer::*;

Expand All @@ -85,3 +91,5 @@ pub use ean_8_writer::*;

mod upc_e_writer;
pub use upc_e_writer::*;

mod telepen_common;
9 changes: 9 additions & 0 deletions src/oned/multi_format_one_d_reader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ use super::Code93Reader;
use super::ITFReader;
use super::MultiFormatUPCEANReader;
use super::OneDReader;
use super::TelepenReader;
use crate::common::Result;
use crate::DecodeHintValue;
use crate::Exceptions;
Expand Down Expand Up @@ -104,6 +105,11 @@ impl OneDReader for MultiFormatOneDReader {
return Ok(res);
}
}
if possible_formats.contains(&BarcodeFormat::TELEPEN) {
if let Ok(res) = TelepenReader::default().decode_row(row_number, row, hints) {
return Ok(res);
}
}
} else {
if let Ok(res) =
MultiFormatUPCEANReader::new(internal_hints).decode_row(row_number, row, hints)
Expand Down Expand Up @@ -133,6 +139,9 @@ impl OneDReader for MultiFormatOneDReader {
if let Ok(res) = rss_expanded_reader.decode_row(row_number, row, hints) {
return Ok(res);
}
if let Ok(res) = TelepenReader::default().decode_row(row_number, row, hints) {
return Ok(res);
}
}

Err(Exceptions::NOT_FOUND)
Expand Down
98 changes: 98 additions & 0 deletions src/oned/telepen_common.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
use crate::Exceptions;
use crate::common::Result;

pub fn calculate_checksum(contents: &str) -> char {
let mut sum = 0;

for c in contents.chars() {
sum += c as u32;
}

let remainder = sum % 127;
let diff = 127 - remainder;
return if diff != 127 {
diff as u8 as char
}
else {
0 as char
};
}

pub fn ascii_to_numeric(contents: &str) -> String {
let mut number = String::new();

for c in contents.chars().map(|x| x as u32) {
if c >= 27 {
number.push_str(&format!("{:0>2}", (c - 27)));
}
else {
number.push_str(&format!("{:0>2}", (c - 17)));
}
}

return number;
}

pub fn numeric_to_ascii(contents: &str) -> Result<String> {
if contents.len() % 2 != 0 {
return Err(Exceptions::illegal_argument_with("Input must contain an even number of characters."));
}

let mut ascii = String::new();
let mut i = 0;

while i < contents.len() {
let first = contents.chars().nth(i).unwrap() as u8;
let second = contents.chars().nth(i + 1).unwrap() as u8;

if second == 88 && first >= 48 && first <= 57 {
ascii.push((17 + first - 48) as char);
}
else if second >= 48 && second <= 57 && first >= 48 && first <= 57 {
ascii.push((27 + (first - 48) * 10 + (second - 48)) as char);
}
else {
return Err(Exceptions::illegal_argument_with(format!("Input contains an invalid character around position {}.", i.to_string())));
}

i += 2;
}

return Ok(ascii);
}

#[test]
fn telepen_checksum_test1() {
let contents = "Hello world!";
let checksum = calculate_checksum(contents);
assert_eq!('\u{1a}', checksum);
}

#[test]
fn telepen_checksum_test2() {
let contents = "ABC123456";
let checksum = calculate_checksum(contents);
assert_eq!('\u{1}', checksum);
}

#[test]
fn telepen_alpha_to_numeric_test() {
let mut ascii = "'=Siu";
let mut result = ascii_to_numeric(ascii);
assert_eq!("1234567890", result);

ascii = "& oe";
result = ascii_to_numeric(ascii);
assert_eq!("11058474", result);
}

#[test]
fn telepen_numeric_to_ascii_test() {
let mut numeric = "1234567890";
let mut result = numeric_to_ascii(numeric).unwrap();
assert_eq!("'=Siu", result);

numeric = "11058474";
result = numeric_to_ascii(numeric).unwrap();
assert_eq!("& oe", result);
}
Loading

0 comments on commit aa7556d

Please sign in to comment.