1 #pragma once
2 /*
3 * Copyright 2016 Nu-book Inc.
4 * Copyright 2016 ZXing authors
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 *      http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18 
19 #include "BarcodeFormat.h"
20 
21 #include <vector>
22 #include <string>
23 
24 namespace ZXing {
25 
26 /**
27  * @brief The Binarizer enum
28  *
29  * Specify which algorithm to use for the grayscale to binary transformation.
30  * The difference is how to get to a threshold value T which results in a bit
31  * value R = L <= T.
32  */
33 enum class Binarizer : unsigned char // needs to unsigned for the bitfield below to work, uint8_t fails as well
34 {
35 	LocalAverage,    ///< T = average of neighboring pixels for 2D and GlobalHistogram for 1D (HybridBinarizer)
36 	GlobalHistogram, ///< T = valley between the 2 largest peaks in the histogram (per line in 1D case)
37 	FixedThreshold,  ///< T = 127
38 	BoolCast,        ///< T = 0, fastest possible
39 };
40 
41 enum class EanAddOnSymbol : unsigned char // see above
42 {
43 	Ignore,  ///< Ignore any Add-On symbol during read/scan
44 	Read,    ///< Read EAN-2/EAN-5 Add-On symbol if found
45 	Require, ///< Require EAN-2/EAN-5 Add-On symbol to be present
46 };
47 
48 class DecodeHints
49 {
50 	bool _tryHarder : 1;
51 	bool _tryRotate : 1;
52 	bool _isPure : 1;
53 	bool _tryCode39ExtendedMode : 1;
54 	bool _assumeCode39CheckDigit : 1;
55 	bool _assumeGS1 : 1;
56 	bool _returnCodabarStartEnd : 1;
57 	Binarizer _binarizer : 2;
58 	EanAddOnSymbol _eanAddOnSymbol : 2;
59 
60 	BarcodeFormats _formats = BarcodeFormat::None;
61 	std::string _characterSet;
62 	std::vector<int> _allowedLengths;
63 
64 public:
65 	// bitfields don't get default initialized to 0.
DecodeHints()66 	DecodeHints()
67 		: _tryHarder(1), _tryRotate(1), _isPure(0), _tryCode39ExtendedMode(0), _assumeCode39CheckDigit(0),
68 		  _assumeGS1(0), _returnCodabarStartEnd(0), _binarizer(Binarizer::LocalAverage),
69 		  _eanAddOnSymbol(EanAddOnSymbol::Ignore)
70 	{}
71 
72 #define ZX_PROPERTY(TYPE, GETTER, SETTER) \
73 	TYPE GETTER() const noexcept { return _##GETTER; } \
74 	DecodeHints& SETTER(TYPE v) { return _##GETTER = std::move(v), *this; }
75 
76 	/// Specify a set of BarcodeFormats that should be searched for, the default is all supported formats.
ZX_PROPERTY(BarcodeFormats,formats,setFormats)77 	ZX_PROPERTY(BarcodeFormats, formats, setFormats)
78 
79 	/// Spend more time to try to find a barcode; optimize for accuracy, not speed.
80 	ZX_PROPERTY(bool, tryHarder, setTryHarder)
81 
82 	/// Also try detecting code in 90, 180 and 270 degree rotated images.
83 	ZX_PROPERTY(bool, tryRotate, setTryRotate)
84 
85 	/// Binarizer to use internally when using the ReadBarcode function
86 	ZX_PROPERTY(Binarizer, binarizer, setBinarizer)
87 
88 	/// Set to true if the input contains nothing but a perfectly aligned barcode (generated image)
89 	ZX_PROPERTY(bool, isPure, setIsPure)
90 
91 	/// Specifies what character encoding to use when decoding, where applicable.
92 	ZX_PROPERTY(std::string, characterSet, setCharacterSet)
93 
94 	/// Allowed lengths of encoded data -- reject anything else..
95 	ZX_PROPERTY(std::vector<int>, allowedLengths, setAllowedLengths)
96 
97 	/// If true, the Code-39 reader will try to read extended mode.
98 	ZX_PROPERTY(bool, tryCode39ExtendedMode, setTryCode39ExtendedMode)
99 
100 	/// Assume Code-39 codes employ a check digit.
101 	ZX_PROPERTY(bool, assumeCode39CheckDigit, setAssumeCode39CheckDigit)
102 
103 	/**
104 	* Assume the barcode is being processed as a GS1 barcode, and modify behavior as needed.
105 	* For example this affects FNC1 handling for Code 128 (aka GS1-128).
106 	*/
107 	ZX_PROPERTY(bool, assumeGS1, setAssumeGS1)
108 
109 	/**
110 	* If true, return the start and end digits in a Codabar barcode instead of stripping them. They
111 	* are alpha, whereas the rest are numeric. By default, they are stripped, but this causes them
112 	* to not be.
113 	*/
114 	ZX_PROPERTY(bool, returnCodabarStartEnd, setReturnCodabarStartEnd)
115 
116 	/// Specify whether to ignore, read or require EAN-2/5 add-on symbols while scanning EAN/UPC codes
117 	ZX_PROPERTY(EanAddOnSymbol, eanAddOnSymbol, setEanAddOnSymbol)
118 
119 #undef ZX_PROPERTY
120 
121 	bool hasFormat(BarcodeFormats f) const noexcept { return _formats.testFlags(f); }
hasNoFormat()122 	bool hasNoFormat() const noexcept { return _formats.empty(); }
123 
setPossibleFormats(const std::vector<BarcodeFormat> & formats)124 	[[deprecated]] DecodeHints& setPossibleFormats(const std::vector<BarcodeFormat>& formats)
125 	{
126 		_formats.clear();
127 		for (auto f : formats)
128 			_formats |= f;
129 		return *this;
130 	}
131 
requireEanAddOnSymbol()132 	[[deprecated]] bool requireEanAddOnSymbol() const { return _eanAddOnSymbol == EanAddOnSymbol::Require; }
setRequireEanAddOnSymbol(bool v)133 	[[deprecated]] DecodeHints& setRequireEanAddOnSymbol(bool v)
134 	{
135 		return setEanAddOnSymbol(v ? EanAddOnSymbol::Require : EanAddOnSymbol::Ignore);
136 	}
allowedEanExtensions()137 	[[deprecated]] std::vector<int> allowedEanExtensions() const
138 	{
139 		return _eanAddOnSymbol == EanAddOnSymbol::Require ? std::vector<int>{2, 5} : std::vector<int>{};
140 	}
setAllowedEanExtensions(const std::vector<int> & v)141 	[[deprecated]] DecodeHints& setAllowedEanExtensions(const std::vector<int>& v)
142 	{
143 		return setEanAddOnSymbol(v.empty() ? EanAddOnSymbol::Ignore : EanAddOnSymbol::Require);
144 	}
145 };
146 
147 } // ZXing
148