Skip to content

Commit b175313

Browse files
committed
feat: begin migration to new Encoding and Decoding hints
1 parent 430031e commit b175313

File tree

6 files changed

+426
-8
lines changed

6 files changed

+426
-8
lines changed

src/decode_hints.rs

Lines changed: 230 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717
//package com.google.zxing;
1818

19-
use std::collections::HashSet;
19+
use std::collections::{HashMap, HashSet};
2020

2121
use crate::{BarcodeFormat, PointCallback};
2222

@@ -242,3 +242,232 @@ pub enum DecodeHintValue {
242242
*/
243243
TelepenAsNumeric(bool),
244244
}
245+
246+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
247+
#[derive(Default, Clone)]
248+
pub struct DecodeHints {
249+
/**
250+
* Unspecified, application-specific hint. Maps to an unspecified {@link Object}.
251+
*/
252+
pub Other: Option<String>,
253+
254+
/**
255+
* Image is a pure monochrome image of a barcode. Doesn't matter what it maps to;
256+
* use {@link Boolean#TRUE}.
257+
*/
258+
pub PureBarcode: Option<bool>,
259+
260+
/**
261+
* Image is known to be of one of a few possible formats.
262+
* Maps to a {@link List} of {@link BarcodeFormat}s.
263+
*/
264+
pub PossibleFormats: Option<HashSet<BarcodeFormat>>,
265+
266+
/**
267+
* Spend more time to try to find a barcode; optimize for accuracy, not speed.
268+
* Doesn't matter what it maps to; use {@link Boolean#TRUE}.
269+
*/
270+
pub TryHarder: Option<bool>,
271+
272+
/**
273+
* Specifies what character encoding to use when decoding, where applicable (type String)
274+
*/
275+
pub CharacterSet: Option<String>,
276+
277+
/**
278+
* Allowed lengths of encoded data -- reject anything else. Maps to an {@code int[]}.
279+
*/
280+
pub AllowedLengths: Option<Vec<u32>>,
281+
282+
/**
283+
* Assume Code 39 codes employ a check digit. Doesn't matter what it maps to;
284+
* use {@link Boolean#TRUE}.
285+
*/
286+
pub AssumeCode39CheckDigit: Option<bool>,
287+
288+
/**
289+
* Assume the barcode is being processed as a GS1 barcode, and modify behavior as needed.
290+
* For example this affects FNC1 handling for Code 128 (aka GS1-128). Doesn't matter what it maps to;
291+
* use {@link Boolean#TRUE}.
292+
*/
293+
pub AssumeGs1: Option<bool>,
294+
295+
/**
296+
* If true, return the start and end digits in a Codabar barcode instead of stripping them. They
297+
* are alpha, whereas the rest are numeric. By default, they are stripped, but this causes them
298+
* to not be. Doesn't matter what it maps to; use {@link Boolean#TRUE}.
299+
*/
300+
pub ReturnCodabarStartEnd: Option<bool>,
301+
302+
/**
303+
* The caller needs to be notified via callback when a possible {@link Point}
304+
* is found. Maps to a {@link PointCallback}.
305+
*/
306+
#[cfg_attr(feature = "serde", serde(skip_serializing, skip_deserializing))]
307+
pub NeedResultPointCallback: Option<PointCallback>,
308+
309+
/**
310+
* Allowed extension lengths for EAN or UPC barcodes. Other formats will ignore this.
311+
* Maps to an {@code int[]} of the allowed extension lengths, for example [2], [5], or [2, 5].
312+
* If it is optional to have an extension, do not set this hint. If this is set,
313+
* and a UPC or EAN barcode is found but an extension is not, then no result will be returned
314+
* at all.
315+
*/
316+
pub AllowedEanExtensions: Option<Vec<u32>>,
317+
318+
/**
319+
* If true, also tries to decode as inverted image. All configured decoders are simply called a
320+
* second time with an inverted image. Doesn't matter what it maps to; use {@link Boolean#TRUE}.
321+
*/
322+
pub AlsoInverted: Option<bool>,
323+
324+
/**
325+
* Specifies that the codes are expected to be in conformance with the specification
326+
* ISO/IEC 18004 regading the interpretation of character encoding. Values encoded in BYTE mode
327+
* or in KANJI mode are interpreted as ISO-8859-1 characters unless an ECI specified at a prior
328+
* location in the input specified a different encoding. By default the encoding of BYTE encoded
329+
* values is determinied by the {@link #CHARACTER_SET} hint or otherwise by a heuristic that
330+
* examines the bytes. By default KANJI encoded values are interpreted as the bytes of Shift-JIS
331+
* encoded characters (note that this is the case even if an ECI specifies a different
332+
* encoding).
333+
*/
334+
#[cfg(feature = "allow_forced_iso_ied_18004_compliance")]
335+
pub QrAssumeSpecConformInput: Option<bool>,
336+
337+
/**
338+
* Translate the ASCII values parsed by the Telepen reader into the Telepen Numeric form; use {@link Boolean#TRUE}.
339+
*/
340+
pub TelepenAsNumeric: Option<bool>,
341+
}
342+
343+
impl From<super::DecodingHintDictionary> for DecodeHints {
344+
fn from(value: super::DecodingHintDictionary) -> Self {
345+
let mut new_self: Self = Self::default();
346+
for (_, v) in value.into_iter() {
347+
match v {
348+
DecodeHintValue::Other(v) => new_self.Other = Some(v),
349+
DecodeHintValue::PureBarcode(v) => new_self.PureBarcode = Some(v),
350+
DecodeHintValue::PossibleFormats(v) => new_self.PossibleFormats = Some(v),
351+
DecodeHintValue::TryHarder(v) => new_self.TryHarder = Some(v),
352+
DecodeHintValue::CharacterSet(v) => new_self.CharacterSet = Some(v),
353+
DecodeHintValue::AllowedLengths(v) => new_self.AllowedLengths = Some(v),
354+
DecodeHintValue::AssumeCode39CheckDigit(v) => {
355+
new_self.AssumeCode39CheckDigit = Some(v)
356+
}
357+
DecodeHintValue::AssumeGs1(v) => new_self.AssumeGs1 = Some(v),
358+
DecodeHintValue::ReturnCodabarStartEnd(v) => {
359+
new_self.ReturnCodabarStartEnd = Some(v)
360+
}
361+
DecodeHintValue::NeedResultPointCallback(v) => {
362+
new_self.NeedResultPointCallback = Some(v)
363+
}
364+
DecodeHintValue::AllowedEanExtensions(v) => new_self.AllowedEanExtensions = Some(v),
365+
DecodeHintValue::AlsoInverted(v) => new_self.AlsoInverted = Some(v),
366+
DecodeHintValue::TelepenAsNumeric(v) => new_self.TelepenAsNumeric = Some(v),
367+
#[cfg(feature = "allow_forced_iso_ied_18004_compliance")]
368+
DecodeHintValue::QrAssumeSpecConformInput(v) => {
369+
new_self.QrAssumeSpecConformInput = Some(v)
370+
}
371+
}
372+
}
373+
new_self
374+
}
375+
}
376+
377+
impl From<DecodeHints> for super::DecodingHintDictionary {
378+
fn from(value: DecodeHints) -> Self {
379+
let mut new_self = HashMap::default();
380+
381+
if let Some(v) = value.Other {
382+
new_self.insert(DecodeHintType::OTHER, DecodeHintValue::Other(v));
383+
}
384+
385+
if let Some(v) = value.PureBarcode {
386+
new_self.insert(
387+
DecodeHintType::PURE_BARCODE,
388+
DecodeHintValue::PureBarcode(v),
389+
);
390+
}
391+
392+
if let Some(v) = value.PossibleFormats {
393+
new_self.insert(
394+
DecodeHintType::POSSIBLE_FORMATS,
395+
DecodeHintValue::PossibleFormats(v),
396+
);
397+
}
398+
399+
if let Some(v) = value.TryHarder {
400+
new_self.insert(DecodeHintType::TRY_HARDER, DecodeHintValue::TryHarder(v));
401+
}
402+
403+
if let Some(v) = value.CharacterSet {
404+
new_self.insert(
405+
DecodeHintType::CHARACTER_SET,
406+
DecodeHintValue::CharacterSet(v),
407+
);
408+
}
409+
410+
if let Some(v) = value.AllowedLengths {
411+
new_self.insert(
412+
DecodeHintType::ALLOWED_LENGTHS,
413+
DecodeHintValue::AllowedLengths(v),
414+
);
415+
}
416+
417+
if let Some(v) = value.AssumeCode39CheckDigit {
418+
new_self.insert(
419+
DecodeHintType::ASSUME_CODE_39_CHECK_DIGIT,
420+
DecodeHintValue::AssumeCode39CheckDigit(v),
421+
);
422+
}
423+
424+
if let Some(v) = value.AssumeGs1 {
425+
new_self.insert(DecodeHintType::ASSUME_GS1, DecodeHintValue::AssumeGs1(v));
426+
}
427+
428+
if let Some(v) = value.ReturnCodabarStartEnd {
429+
new_self.insert(
430+
DecodeHintType::RETURN_CODABAR_START_END,
431+
DecodeHintValue::ReturnCodabarStartEnd(v),
432+
);
433+
}
434+
435+
if let Some(v) = value.NeedResultPointCallback {
436+
new_self.insert(
437+
DecodeHintType::NEED_RESULT_POINT_CALLBACK,
438+
DecodeHintValue::NeedResultPointCallback(v),
439+
);
440+
}
441+
442+
if let Some(v) = value.AllowedEanExtensions {
443+
new_self.insert(
444+
DecodeHintType::ALLOWED_EAN_EXTENSIONS,
445+
DecodeHintValue::AllowedEanExtensions(v),
446+
);
447+
}
448+
449+
if let Some(v) = value.AlsoInverted {
450+
new_self.insert(
451+
DecodeHintType::ALSO_INVERTED,
452+
DecodeHintValue::AlsoInverted(v),
453+
);
454+
}
455+
456+
if let Some(v) = value.TelepenAsNumeric {
457+
new_self.insert(
458+
DecodeHintType::TELEPEN_AS_NUMERIC,
459+
DecodeHintValue::TelepenAsNumeric(v),
460+
);
461+
}
462+
463+
#[cfg(feature = "allow_forced_iso_ied_18004_compliance")]
464+
if let Some(v) = value.QrAssumeSpecConformInput {
465+
new_self.insert(
466+
DecodeHintType::QR_ASSUME_SPEC_CONFORM_INPUT,
467+
DecodeHintValue::QrAssumeSpecConformInput(v),
468+
);
469+
}
470+
471+
new_self
472+
}
473+
}

src/dimension.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ use serde::{Deserialize, Serialize};
2525
* Simply encapsulates a width and height.
2626
*/
2727
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
28-
#[derive(Eq, PartialEq, Hash, Copy, Clone)]
28+
#[derive(Eq, PartialEq, Hash, Copy, Clone, Debug)]
2929
pub struct Dimension(usize, usize);
3030

3131
impl Dimension {

0 commit comments

Comments
 (0)