Skip to content

Commit efa7c93

Browse files
committed
Add PDF417 decoder and BigInteger implementation
- Introduced PDFDecoder.h and ZXBigInteger.cpp/h for handling PDF417 decoding and big integer arithmetic. - Implemented addition, subtraction, multiplication, and division with remainder for big integers. - Added Nullable class for handling optional values. - Ensured proper memory management and error handling in arithmetic operations. - Included necessary headers and namespaces for functionality.
1 parent 287ae70 commit efa7c93

File tree

184 files changed

+7987
-3059
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

184 files changed

+7987
-3059
lines changed

README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,11 @@
33
[![Platform IO CI](https://github.com/rzeldent/micro-zxing/actions/workflows/main.yml/badge.svg)](https://github.com/rzeldent/micro-zxing/actions/workflows/main.yml)
44

55
ZXing Zebra crossing barcode library
6+
7+
20250628:
8+
Updated ZXing by putting in sourcecode from: [https://github.com/zxing-cpp/zxing-cpp](https://github.com/zxing-cpp/zxing-cpp)
9+
10+
Additional steps to update the library:
11+
12+
- Updated version.h manually because there is no project preprocessing
13+
- removed libzint directory (stibs) because is not used and caused compile error

lib/library.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "micro-zxing",
3-
"version": "1.0.0",
3+
"version": "2.3.0",
44
"description": "",
55
"keywords": "",
66
"repository": {

lib/libzueci/ChangeLog

Lines changed: 0 additions & 4 deletions
This file was deleted.

lib/libzueci/README

Lines changed: 0 additions & 44 deletions
This file was deleted.

lib/libzueci/library.json

Lines changed: 0 additions & 5 deletions
This file was deleted.

lib/zxing/Barcode.cpp

Lines changed: 269 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,269 @@
1+
/*
2+
* Copyright 2016 Nu-book Inc.
3+
* Copyright 2016 ZXing authors
4+
*/
5+
// SPDX-License-Identifier: Apache-2.0
6+
7+
#include "Barcode.h"
8+
9+
#include "DecoderResult.h"
10+
#include "DetectorResult.h"
11+
#include "JSON.h"
12+
#include "ZXAlgorithms.h"
13+
14+
#ifdef ZXING_EXPERIMENTAL_API
15+
#include "BitMatrix.h"
16+
17+
#ifdef ZXING_USE_ZINT
18+
#include <zint.h>
19+
void zint_symbol_deleter::operator()(zint_symbol* p) const noexcept
20+
{
21+
ZBarcode_Delete(p);
22+
}
23+
#else
24+
struct zint_symbol {};
25+
void zint_symbol_deleter::operator()(zint_symbol*) const noexcept {}
26+
#endif
27+
28+
#endif
29+
30+
#include <cmath>
31+
#include <list>
32+
#include <map>
33+
#include <utility>
34+
35+
namespace ZXing {
36+
37+
Result::Result(const std::string& text, int y, int xStart, int xStop, BarcodeFormat format, SymbologyIdentifier si, Error error, bool readerInit)
38+
: _content({ByteArray(text)}, si),
39+
_error(error),
40+
_position(Line(y, xStart, xStop)),
41+
_format(format),
42+
_readerInit(readerInit)
43+
{}
44+
45+
Result::Result(DecoderResult&& decodeResult, DetectorResult&& detectorResult, BarcodeFormat format)
46+
: _content(std::move(decodeResult).content()),
47+
_error(std::move(decodeResult).error()),
48+
_position(std::move(detectorResult).position()),
49+
_sai(decodeResult.structuredAppend()),
50+
_format(format),
51+
_lineCount(decodeResult.lineCount()),
52+
_isMirrored(decodeResult.isMirrored()),
53+
_readerInit(decodeResult.readerInit())
54+
#ifdef ZXING_EXPERIMENTAL_API
55+
, _symbol(std::make_shared<BitMatrix>(std::move(detectorResult).bits()))
56+
, _json(std::move(decodeResult).json())
57+
#endif
58+
{
59+
if (decodeResult.versionNumber())
60+
snprintf(_version, 4, "%d", decodeResult.versionNumber());
61+
snprintf(_ecLevel, 4, "%s", decodeResult.ecLevel().data());
62+
63+
// TODO: add type opaque and code specific 'extra data'? (see DecoderResult::extra())
64+
}
65+
66+
Result::Result(DecoderResult&& decodeResult, Position&& position, BarcodeFormat format)
67+
: Result(std::move(decodeResult), {{}, std::move(position)}, format)
68+
{}
69+
70+
bool Result::isValid() const
71+
{
72+
return format() != BarcodeFormat::None && !_content.bytes.empty() && !error();
73+
}
74+
75+
const ByteArray& Result::bytes() const
76+
{
77+
return _content.bytes;
78+
}
79+
80+
ByteArray Result::bytesECI() const
81+
{
82+
return _content.bytesECI();
83+
}
84+
85+
std::string Result::text(TextMode mode) const
86+
{
87+
return _content.text(mode);
88+
}
89+
90+
std::string Result::text() const
91+
{
92+
return text(_readerOpts.textMode());
93+
}
94+
95+
std::string Result::ecLevel() const
96+
{
97+
return _ecLevel;
98+
}
99+
100+
ContentType Result::contentType() const
101+
{
102+
return _content.type();
103+
}
104+
105+
bool Result::hasECI() const
106+
{
107+
return _content.hasECI;
108+
}
109+
110+
int Result::orientation() const
111+
{
112+
constexpr auto std_numbers_pi_v = 3.14159265358979323846; // TODO: c++20 <numbers>
113+
return narrow_cast<int>(std::lround(_position.orientation() * 180 / std_numbers_pi_v));
114+
}
115+
116+
std::string Result::symbologyIdentifier() const
117+
{
118+
return _content.symbology.toString();
119+
}
120+
121+
int Result::sequenceSize() const
122+
{
123+
return _sai.count;
124+
}
125+
126+
int Result::sequenceIndex() const
127+
{
128+
return _sai.index;
129+
}
130+
131+
std::string Result::sequenceId() const
132+
{
133+
return _sai.id;
134+
}
135+
136+
std::string Result::version() const
137+
{
138+
return _version;
139+
}
140+
141+
Result& Result::setReaderOptions(const ReaderOptions& opts)
142+
{
143+
if (opts.characterSet() != CharacterSet::Unknown)
144+
_content.defaultCharset = opts.characterSet();
145+
_readerOpts = opts;
146+
return *this;
147+
}
148+
149+
#ifdef ZXING_EXPERIMENTAL_API
150+
void Result::symbol(BitMatrix&& bits)
151+
{
152+
bits.flipAll();
153+
_symbol = std::make_shared<BitMatrix>(std::move(bits));
154+
}
155+
156+
ImageView Result::symbol() const
157+
{
158+
return _symbol && !_symbol->empty() ? ImageView{_symbol->row(0).begin(), _symbol->width(), _symbol->height(), ImageFormat::Lum}
159+
: ImageView{};
160+
}
161+
162+
void Result::zint(unique_zint_symbol&& z)
163+
{
164+
_zint = std::shared_ptr(std::move(z));
165+
}
166+
167+
std::string Result::extra(std::string_view key) const
168+
{
169+
if (key == "ALL") {
170+
if (format() == BarcodeFormat::None)
171+
return {};
172+
auto res =
173+
StrCat("{", JsonProp("Text", text(TextMode::Plain)), JsonProp("HRI", text(TextMode::HRI)),
174+
JsonProp("TextECI", text(TextMode::ECI)), JsonProp("Bytes", text(TextMode::Hex)),
175+
JsonProp("Identifier", symbologyIdentifier()), JsonProp("Format", ToString(format())),
176+
JsonProp("ContentType", isValid() ? ToString(contentType()) : ""), JsonProp("Position", ToString(position())),
177+
JsonProp("HasECI", hasECI()), JsonProp("IsMirrored", isMirrored()), JsonProp("IsInverted", isInverted()), _json,
178+
JsonProp("Error", ToString(error())));
179+
res.back() = '}';
180+
return res;
181+
}
182+
return _json.empty() ? "" : key.empty() ? StrCat("{", _json.substr(0, _json.size() - 1), "}") : std::string(JsonGetStr(_json, key));
183+
}
184+
#endif
185+
186+
bool Result::operator==(const Result& o) const
187+
{
188+
if (format() != o.format())
189+
return false;
190+
191+
// handle MatrixCodes first
192+
if (!IsLinearBarcode(format())) {
193+
if (bytes() != o.bytes() && isValid() && o.isValid())
194+
return false;
195+
196+
// check for equal position if both are valid with equal bytes or at least one is in error
197+
return IsInside(Center(o.position()), position());
198+
}
199+
200+
if (bytes() != o.bytes() || error() != o.error() || orientation() != o.orientation())
201+
return false;
202+
203+
if (lineCount() > 1 && o.lineCount() > 1)
204+
return HaveIntersectingBoundingBoxes(o.position(), position());
205+
206+
// the following code is only meant for this or other lineCount == 1
207+
assert(lineCount() == 1 || o.lineCount() == 1);
208+
209+
// sl == single line, ml = multi line
210+
const auto& sl = lineCount() == 1 ? *this : o;
211+
const auto& ml = lineCount() == 1 ? o : *this;
212+
213+
// If one line is less than half the length of the other away from the
214+
// latter, we consider it to belong to the same symbol.
215+
// Additionally, both need to have roughly the same length (see #367).
216+
auto dTop = maxAbsComponent(ml.position().topLeft() - sl.position().topLeft());
217+
auto dBot = maxAbsComponent(ml.position().bottomLeft() - sl.position().topLeft());
218+
auto slLength = maxAbsComponent(sl.position().topLeft() - sl.position().bottomRight());
219+
bool isHorizontal = sl.position().topLeft().y == sl.position().bottomRight().y;
220+
// Measure the multi line length in the same direction as the single line one (not diagonaly)
221+
// to make sure overly tall symbols don't get segmented (see #769).
222+
auto mlLength = isHorizontal ? std::abs(ml.position().topLeft().x - ml.position().bottomRight().x)
223+
: std::abs(ml.position().topLeft().y - ml.position().bottomRight().y);
224+
225+
return std::min(dTop, dBot) < slLength / 2 && std::abs(slLength - mlLength) < slLength / 5;
226+
}
227+
228+
Barcode MergeStructuredAppendSequence(const Barcodes& barcodes)
229+
{
230+
if (barcodes.empty())
231+
return {};
232+
233+
std::list<Barcode> allBarcodes(barcodes.begin(), barcodes.end());
234+
allBarcodes.sort([](const Barcode& r1, const Barcode& r2) { return r1.sequenceIndex() < r2.sequenceIndex(); });
235+
236+
Barcode res = allBarcodes.front();
237+
for (auto i = std::next(allBarcodes.begin()); i != allBarcodes.end(); ++i)
238+
res._content.append(i->_content);
239+
240+
res._position = {};
241+
res._sai.index = -1;
242+
243+
if (allBarcodes.back().sequenceSize() != Size(allBarcodes) ||
244+
!std::all_of(allBarcodes.begin(), allBarcodes.end(),
245+
[&](Barcode& it) { return it.sequenceId() == allBarcodes.front().sequenceId(); }))
246+
res._error = FormatError("sequenceIDs not matching during structured append sequence merging");
247+
248+
return res;
249+
}
250+
251+
Barcodes MergeStructuredAppendSequences(const Barcodes& barcodes)
252+
{
253+
std::map<std::string, Barcodes> sas;
254+
for (auto& barcode : barcodes) {
255+
if (barcode.isPartOfSequence())
256+
sas[barcode.sequenceId()].push_back(barcode);
257+
}
258+
259+
Barcodes res;
260+
for (auto& [id, seq] : sas) {
261+
auto barcode = MergeStructuredAppendSequence(seq);
262+
if (barcode.isValid())
263+
res.push_back(std::move(barcode));
264+
}
265+
266+
return res;
267+
}
268+
269+
} // namespace ZXing

0 commit comments

Comments
 (0)