/* * Copyright 2013 ZXing.Net authors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ using System; using System.Collections.Generic; using System.ComponentModel; namespace ZXing.Common { /// /// Defines an container for encoder options /// public class DecodingOptions { /// /// Gets the data container for all options /// public IDictionary Hints { get; private set; } public event Action ValueChanged; /// /// Gets or sets a flag which cause a deeper look into the bitmap /// /// /// true if [try harder]; otherwise, false. /// public bool TryHarder { get { if (Hints.ContainsKey(DecodeHintType.TRY_HARDER)) return (bool)Hints[DecodeHintType.TRY_HARDER]; return false; } set { if (value) { Hints[DecodeHintType.TRY_HARDER] = true; } else { if (Hints.ContainsKey(DecodeHintType.TRY_HARDER)) { Hints.Remove(DecodeHintType.TRY_HARDER); } } } } /// /// Image is a pure monochrome image of a barcode. /// /// /// true if monochrome image of a barcode; otherwise, false. /// public bool PureBarcode { get { if (Hints.ContainsKey(DecodeHintType.PURE_BARCODE)) return (bool)Hints[DecodeHintType.PURE_BARCODE]; return false; } set { if (value) { Hints[DecodeHintType.PURE_BARCODE] = true; } else { if (Hints.ContainsKey(DecodeHintType.PURE_BARCODE)) { Hints.Remove(DecodeHintType.PURE_BARCODE); } } } } /// /// Specifies what character encoding to use when decoding, where applicable (type String) /// /// /// The character set. /// public string CharacterSet { get { if (Hints.ContainsKey(DecodeHintType.CHARACTER_SET)) return (string)Hints[DecodeHintType.CHARACTER_SET]; return null; } set { if (value != null) { Hints[DecodeHintType.CHARACTER_SET] = value; } else { if (Hints.ContainsKey(DecodeHintType.CHARACTER_SET)) { Hints.Remove(DecodeHintType.CHARACTER_SET); } } } } /// /// Image is known to be of one of a few possible formats. /// Maps to a {@link java.util.List} of {@link BarcodeFormat}s. /// /// /// The possible formats. /// public IList PossibleFormats { get { if (Hints.ContainsKey(DecodeHintType.POSSIBLE_FORMATS)) return (IList)Hints[DecodeHintType.POSSIBLE_FORMATS]; return null; } set { if (value != null) { Hints[DecodeHintType.POSSIBLE_FORMATS] = value; } else { if (Hints.ContainsKey(DecodeHintType.POSSIBLE_FORMATS)) { Hints.Remove(DecodeHintType.POSSIBLE_FORMATS); } } } } /// /// if Code39 could be detected try to use extended mode for full ASCII character set /// public bool UseCode39ExtendedMode { get { if (Hints.ContainsKey(DecodeHintType.USE_CODE_39_EXTENDED_MODE)) return (bool)Hints[DecodeHintType.USE_CODE_39_EXTENDED_MODE]; return false; } set { if (value) { Hints[DecodeHintType.USE_CODE_39_EXTENDED_MODE] = true; } else { if (Hints.ContainsKey(DecodeHintType.USE_CODE_39_EXTENDED_MODE)) { Hints.Remove(DecodeHintType.USE_CODE_39_EXTENDED_MODE); } } } } /// /// Don't fail if a Code39 is detected but can't be decoded in extended mode. /// Return the raw Code39 result instead. Maps to . /// public bool UseCode39RelaxedExtendedMode { get { if (Hints.ContainsKey(DecodeHintType.RELAXED_CODE_39_EXTENDED_MODE)) return (bool)Hints[DecodeHintType.RELAXED_CODE_39_EXTENDED_MODE]; return false; } set { if (value) { Hints[DecodeHintType.RELAXED_CODE_39_EXTENDED_MODE] = true; } else { if (Hints.ContainsKey(DecodeHintType.RELAXED_CODE_39_EXTENDED_MODE)) { Hints.Remove(DecodeHintType.RELAXED_CODE_39_EXTENDED_MODE); } } } } /// /// If true, return the start and end digits in a Codabar barcode instead of stripping them. They /// are alpha, whereas the rest are numeric. By default, they are stripped, but this causes them /// to not be. Doesn't matter what it maps to; use . /// public bool ReturnCodabarStartEnd { get { if (Hints.ContainsKey(DecodeHintType.RETURN_CODABAR_START_END)) return (bool)Hints[DecodeHintType.RETURN_CODABAR_START_END]; return false; } set { if (value) { Hints[DecodeHintType.RETURN_CODABAR_START_END] = true; } else { if (Hints.ContainsKey(DecodeHintType.RETURN_CODABAR_START_END)) { Hints.Remove(DecodeHintType.RETURN_CODABAR_START_END); } } } } /// /// Assume the barcode is being processed as a GS1 barcode, and modify behavior as needed. /// For example this affects FNC1 handling for Code 128 (aka GS1-128). /// /// /// true if it should assume GS1; otherwise, false. /// public bool AssumeGS1 { get { if (Hints.ContainsKey(DecodeHintType.ASSUME_GS1)) return (bool)Hints[DecodeHintType.ASSUME_GS1]; return false; } set { if (value) { Hints[DecodeHintType.ASSUME_GS1] = true; } else { if (Hints.ContainsKey(DecodeHintType.ASSUME_GS1)) { Hints.Remove(DecodeHintType.ASSUME_GS1); } } } } /// /// Assume MSI codes employ a check digit. Maps to . /// /// /// true if it should assume a MSI check digit; otherwise, false. /// public bool AssumeMSICheckDigit { get { if (Hints.ContainsKey(DecodeHintType.ASSUME_MSI_CHECK_DIGIT)) return (bool)Hints[DecodeHintType.ASSUME_MSI_CHECK_DIGIT]; return false; } set { if (value) { Hints[DecodeHintType.ASSUME_MSI_CHECK_DIGIT] = true; } else { if (Hints.ContainsKey(DecodeHintType.ASSUME_MSI_CHECK_DIGIT)) { Hints.Remove(DecodeHintType.ASSUME_MSI_CHECK_DIGIT); } } } } /// /// Allowed lengths of encoded data -- reject anything else. Maps to an int[]. /// public int[] AllowedLengths { get { if (Hints.ContainsKey(DecodeHintType.ALLOWED_LENGTHS)) return (int[])Hints[DecodeHintType.ALLOWED_LENGTHS]; return null; } set { if (value != null && value.Length > 0) { Hints[DecodeHintType.ALLOWED_LENGTHS] = value; } else { if (Hints.ContainsKey(DecodeHintType.ALLOWED_LENGTHS)) { Hints.Remove(DecodeHintType.ALLOWED_LENGTHS); } } } } /// /// Allowed extension lengths for EAN or UPC barcodes. Other formats will ignore this. /// Maps to an of the allowed extension lengths, for example [2], [5], or [2, 5]. /// If it is optional to have an extension, do not set this hint. If this is set, /// and a UPC or EAN barcode is found but an extension is not, then no result will be returned /// at all. /// public int[] AllowedEANExtensions { get { if (Hints.ContainsKey(DecodeHintType.ALLOWED_EAN_EXTENSIONS)) return (int[])Hints[DecodeHintType.ALLOWED_EAN_EXTENSIONS]; return null; } set { if (value != null && value.Length > 0) { Hints[DecodeHintType.ALLOWED_EAN_EXTENSIONS] = value; } else { if (Hints.ContainsKey(DecodeHintType.ALLOWED_EAN_EXTENSIONS)) { Hints.Remove(DecodeHintType.ALLOWED_EAN_EXTENSIONS); } } } } /// /// Initializes a new instance of the class. /// public DecodingOptions() { var hints = new ChangeNotifyDictionary(); Hints = hints; UseCode39ExtendedMode = true; UseCode39RelaxedExtendedMode = true; hints.ValueChanged += (o, args) => { if (ValueChanged != null) ValueChanged(this, EventArgs.Empty); }; } private class ChangeNotifyDictionary: IDictionary { private readonly IDictionary values; public event Action ValueChanged; public ChangeNotifyDictionary() { values = new Dictionary(); } private void OnValueChanged() { if (ValueChanged != null) ValueChanged(this, EventArgs.Empty); } public void Add(TKey key, TValue value) { values.Add(key, value); OnValueChanged(); } public bool ContainsKey(TKey key) { return values.ContainsKey(key); } public ICollection Keys { get { return values.Keys; } } public bool Remove(TKey key) { var result = values.Remove(key); OnValueChanged(); return result; } public bool TryGetValue(TKey key, out TValue value) { return values.TryGetValue(key, out value); } public ICollection Values { get { return values.Values; } } public TValue this[TKey key] { get { return values[key]; } set { values[key] = value; OnValueChanged(); } } public void Add(KeyValuePair item) { values.Add(item); OnValueChanged(); } public void Clear() { values.Clear(); OnValueChanged(); } public bool Contains(KeyValuePair item) { return values.Contains(item); } public void CopyTo(KeyValuePair[] array, int arrayIndex) { values.CopyTo(array, arrayIndex); } public int Count { get { return values.Count; } } public bool IsReadOnly { get { return values.IsReadOnly; } } public bool Remove(KeyValuePair item) { var result = values.Remove(item); OnValueChanged(); return result; } public IEnumerator> GetEnumerator() { return values.GetEnumerator(); } System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { return ((System.Collections.IEnumerable)values).GetEnumerator(); } } } }