mirror of
https://github.com/status-im/qzxing.git
synced 2025-02-12 10:56:47 +00:00
Merge pull request #106 from Eism/UPCEAN_Extensions
UPCEANExtensions Thank you very much @Eism for your contribution!
This commit is contained in:
commit
465e1f0065
@ -5,6 +5,7 @@
|
||||
#include <zxing/BinaryBitmap.h>
|
||||
#include <zxing/MultiFormatReader.h>
|
||||
#include <zxing/DecodeHints.h>
|
||||
#include <zxing/ResultMetadata.h>
|
||||
#include "CameraImageWrapper.h"
|
||||
#include "ImageHandler.h"
|
||||
#include <QTime>
|
||||
@ -109,6 +110,25 @@ bool QZXing::getTryHarder()
|
||||
{
|
||||
return tryHarder_;
|
||||
}
|
||||
void QZXing::setAllowedExtensions(const QVariantList& extensions)
|
||||
{
|
||||
std::set<int> allowedExtensions;
|
||||
for (const QVariant& extension: extensions) {
|
||||
allowedExtensions.insert(extension.toInt());
|
||||
}
|
||||
|
||||
allowedExtensions_ = allowedExtensions;
|
||||
}
|
||||
|
||||
QVariantList QZXing::getAllowedExtensions()
|
||||
{
|
||||
QVariantList allowedExtensions;
|
||||
for (const int& extension: allowedExtensions_) {
|
||||
allowedExtensions << extension;
|
||||
}
|
||||
|
||||
return allowedExtensions;
|
||||
}
|
||||
|
||||
QString QZXing::decoderFormatToString(int fmt)
|
||||
{
|
||||
@ -185,6 +205,37 @@ bool QZXing::getLastDecodeOperationSucceded()
|
||||
return lastDecodeOperationSucceded_;
|
||||
}
|
||||
|
||||
QVariantMap QZXing::metadataToMap(const ResultMetadata &metadata)
|
||||
{
|
||||
QVariantMap obj;
|
||||
for (const ResultMetadata::Key &key: metadata.keys()) {
|
||||
QString keyName = QString::fromStdString(metadata.keyToString(key));
|
||||
|
||||
switch (key) {
|
||||
case ResultMetadata::ORIENTATION:
|
||||
case ResultMetadata::ISSUE_NUMBER:
|
||||
case ResultMetadata::STRUCTURED_APPEND_SEQUENCE:
|
||||
case ResultMetadata::STRUCTURED_APPEND_CODE_COUNT:
|
||||
case ResultMetadata::STRUCTURED_APPEND_PARITY:
|
||||
obj[keyName] = QVariant(metadata.getInt(key));
|
||||
break;
|
||||
case ResultMetadata::ERROR_CORRECTION_LEVEL:
|
||||
case ResultMetadata::SUGGESTED_PRICE:
|
||||
case ResultMetadata::POSSIBLE_COUNTRY:
|
||||
case ResultMetadata::UPC_EAN_EXTENSION:
|
||||
obj[keyName] = QVariant(metadata.getString(key).c_str());
|
||||
break;
|
||||
|
||||
case ResultMetadata::OTHER:
|
||||
case ResultMetadata::PDF417_EXTRA_METADATA:
|
||||
case ResultMetadata::BYTE_SEGMENTS:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
void QZXing::setDecoder(const uint &hint)
|
||||
{
|
||||
unsigned int newHints = 0;
|
||||
@ -352,6 +403,10 @@ QString QZXing::decodeImage(const QImage &image, int maxWidth, int maxHeight, bo
|
||||
|
||||
DecodeHints hints(static_cast<DecodeHintType>(enabledDecoders));
|
||||
|
||||
if (hints.containsFormat(BarcodeFormat::UPC_EAN_EXTENSION)) {
|
||||
hints.setAllowedEanExtensions(allowedExtensions_);
|
||||
}
|
||||
|
||||
lastDecodeOperationSucceded_ = false;
|
||||
try {
|
||||
res = decoder->decode(bb, hints);
|
||||
@ -369,6 +424,19 @@ QString QZXing::decodeImage(const QImage &image, int maxWidth, int maxHeight, bo
|
||||
lastDecodeOperationSucceded_ = true;
|
||||
} catch(zxing::Exception &/*e*/) {}
|
||||
|
||||
if (!lastDecodeOperationSucceded_ &&
|
||||
hints.containsFormat(BarcodeFormat::UPC_EAN_EXTENSION) &&
|
||||
!allowedExtensions_.empty() &&
|
||||
!(hints & DecodeHints::PRODUCT_HINT).isEmpty() ) {
|
||||
hints.setAllowedEanExtensions(std::set<int>());
|
||||
|
||||
try {
|
||||
res = decoder->decode(bb, hints);
|
||||
processingTime = t.elapsed();
|
||||
lastDecodeOperationSucceded_ = true;
|
||||
} catch(zxing::Exception &/*e*/) {}
|
||||
}
|
||||
|
||||
if (tryHarder_ && bb->isRotateSupported()) {
|
||||
Ref<BinaryBitmap> bbTmp = bb;
|
||||
|
||||
@ -400,6 +468,9 @@ QString QZXing::decodeImage(const QImage &image, int maxWidth, int maxHeight, bo
|
||||
emit tagFound(string);
|
||||
emit tagFoundAdvanced(string, foundedFmt, charSet_);
|
||||
|
||||
QVariantMap metadataMap = metadataToMap(res->getMetadata());
|
||||
emit tagFoundAdvanced(string, foundedFmt, charSet_, metadataMap);
|
||||
|
||||
try {
|
||||
const QRectF rect = getTagRect(res->getResultPoints(), binz->getBlackMatrix());
|
||||
emit tagFoundAdvanced(string, foundedFmt, charSet_, rect);
|
||||
|
12
src/QZXing.h
12
src/QZXing.h
@ -22,6 +22,9 @@
|
||||
|
||||
#include <QObject>
|
||||
#include <QImage>
|
||||
#include <QVariantList>
|
||||
|
||||
#include <set>
|
||||
|
||||
#if QT_VERSION >= 0x050000
|
||||
class QQmlEngine;
|
||||
@ -30,6 +33,7 @@
|
||||
// forward declaration
|
||||
namespace zxing {
|
||||
class MultiFormatReader;
|
||||
class ResultMetadata;
|
||||
}
|
||||
class ImageHandler;
|
||||
|
||||
@ -53,6 +57,7 @@ class
|
||||
Q_PROPERTY(int processingTime READ getProcessTimeOfLastDecoding)
|
||||
Q_PROPERTY(uint enabledDecoders READ getEnabledFormats WRITE setDecoder NOTIFY enabledFormatsChanged)
|
||||
Q_PROPERTY(bool tryHarder READ getTryHarder WRITE setTryHarder)
|
||||
Q_PROPERTY(QVariantList allowedExtensions READ getAllowedExtensions WRITE setAllowedExtensions)
|
||||
|
||||
public:
|
||||
/*
|
||||
@ -112,12 +117,17 @@ public:
|
||||
|
||||
void setTryHarder(bool tryHarder);
|
||||
bool getTryHarder();
|
||||
void setAllowedExtensions(const QVariantList& extensions);
|
||||
QVariantList getAllowedExtensions();
|
||||
static QString decoderFormatToString(int fmt);
|
||||
Q_INVOKABLE QString foundedFormat() const;
|
||||
Q_INVOKABLE QString charSet() const;
|
||||
|
||||
bool getLastDecodeOperationSucceded();
|
||||
|
||||
private:
|
||||
QVariantMap metadataToMap(const zxing::ResultMetadata& metadata);
|
||||
|
||||
public slots:
|
||||
/**
|
||||
* The decoding function. Will try to decode the given image based on the enabled decoders.
|
||||
@ -200,6 +210,7 @@ signals:
|
||||
void tagFound(QString tag);
|
||||
void tagFoundAdvanced(const QString &tag, const QString &format, const QString &charSet) const;
|
||||
void tagFoundAdvanced(const QString &tag, const QString &format, const QString &charSet, const QRectF &rect) const;
|
||||
void tagFoundAdvanced(const QString &tag, const QString &format, const QString &charSet, const QVariantMap &metadata) const;
|
||||
void error(QString msg);
|
||||
|
||||
private:
|
||||
@ -211,6 +222,7 @@ private:
|
||||
QString charSet_;
|
||||
bool tryHarder_;
|
||||
bool lastDecodeOperationSucceded_;
|
||||
std::set<int> allowedExtensions_;
|
||||
|
||||
/**
|
||||
* If true, the decoding operation will take place at a different thread.
|
||||
|
@ -34,6 +34,7 @@ HEADERS += $$PWD/QZXing_global.h \
|
||||
$$PWD/zxing/zxing/ResultPointCallback.h \
|
||||
$$PWD/zxing/zxing/ResultPoint.h \
|
||||
$$PWD/zxing/zxing/Result.h \
|
||||
$$PWD/zxing/zxing/ResultMetadata.h \
|
||||
$$PWD/zxing/zxing/ReaderException.h \
|
||||
$$PWD/zxing/zxing/Reader.h \
|
||||
$$PWD/zxing/zxing/NotFoundException.h \
|
||||
@ -75,6 +76,7 @@ HEADERS += $$PWD/QZXing_global.h \
|
||||
$$PWD/zxing/zxing/common/reedsolomon/ReedSolomonDecoder.h \
|
||||
$$PWD/zxing/zxing/common/reedsolomon/GenericGFPoly.h \
|
||||
$$PWD/zxing/zxing/common/reedsolomon/GenericGF.h \
|
||||
$$PWD/zxing/zxing/common/ByteArray.h \
|
||||
$$PWD/zxing/zxing/datamatrix/Version.h \
|
||||
$$PWD/zxing/zxing/datamatrix/DataMatrixReader.h \
|
||||
$$PWD/zxing/zxing/datamatrix/decoder/Decoder.h \
|
||||
@ -86,6 +88,9 @@ HEADERS += $$PWD/QZXing_global.h \
|
||||
$$PWD/zxing/zxing/datamatrix/detector/CornerPoint.h \
|
||||
$$PWD/zxing/zxing/oned/UPCEReader.h \
|
||||
$$PWD/zxing/zxing/oned/UPCEANReader.h \
|
||||
$$PWD/zxing/zxing/oned/UPCEANExtensionSupport.h \
|
||||
$$PWD/zxing/zxing/oned/UPCEANExtension2Support.h \
|
||||
$$PWD/zxing/zxing/oned/UPCEANExtension5Support.h \
|
||||
$$PWD/zxing/zxing/oned/UPCAReader.h \
|
||||
$$PWD/zxing/zxing/oned/OneDResultPoint.h \
|
||||
$$PWD/zxing/zxing/oned/OneDReader.h \
|
||||
@ -94,6 +99,7 @@ HEADERS += $$PWD/QZXing_global.h \
|
||||
$$PWD/zxing/zxing/oned/ITFReader.h \
|
||||
$$PWD/zxing/zxing/oned/EAN13Reader.h \
|
||||
$$PWD/zxing/zxing/oned/EAN8Reader.h \
|
||||
$$PWD/zxing/zxing/oned/EANManufacturerOrgSupport.h \
|
||||
$$PWD/zxing/zxing/oned/Code128Reader.h \
|
||||
$$PWD/zxing/zxing/oned/Code39Reader.h \
|
||||
$$PWD/zxing/zxing/oned/CodaBarReader.h \
|
||||
@ -157,6 +163,7 @@ SOURCES += $$PWD/CameraImageWrapper.cpp \
|
||||
$$PWD/zxing/zxing/ResultPointCallback.cpp \
|
||||
$$PWD/zxing/zxing/ResultPoint.cpp \
|
||||
$$PWD/zxing/zxing/Result.cpp \
|
||||
$$PWD/zxing/zxing/ResultMetadata.cpp \
|
||||
$$PWD/zxing/zxing/Reader.cpp \
|
||||
$$PWD/zxing/zxing/MultiFormatReader.cpp \
|
||||
$$PWD/zxing/zxing/LuminanceSource.cpp \
|
||||
@ -198,6 +205,9 @@ SOURCES += $$PWD/CameraImageWrapper.cpp \
|
||||
$$PWD/zxing/zxing/datamatrix/DataMatrixReader.cpp \
|
||||
$$PWD/zxing/zxing/oned/UPCEReader.cpp \
|
||||
$$PWD/zxing/zxing/oned/UPCEANReader.cpp \
|
||||
$$PWD/zxing/zxing/oned/UPCEANExtensionSupport.cpp \
|
||||
$$PWD/zxing/zxing/oned/UPCEANExtension2Support.cpp \
|
||||
$$PWD/zxing/zxing/oned/UPCEANExtension5Support.cpp \
|
||||
$$PWD/zxing/zxing/oned/UPCAReader.cpp \
|
||||
$$PWD/zxing/zxing/oned/OneDResultPoint.cpp \
|
||||
$$PWD/zxing/zxing/oned/OneDReader.cpp \
|
||||
@ -206,6 +216,7 @@ SOURCES += $$PWD/CameraImageWrapper.cpp \
|
||||
$$PWD/zxing/zxing/oned/ITFReader.cpp \
|
||||
$$PWD/zxing/zxing/oned/EAN13Reader.cpp \
|
||||
$$PWD/zxing/zxing/oned/EAN8Reader.cpp \
|
||||
$$PWD/zxing/zxing/oned/EANManufacturerOrgSupport.cpp \
|
||||
$$PWD/zxing/zxing/oned/Code128Reader.cpp \
|
||||
$$PWD/zxing/zxing/oned/Code39Reader.cpp \
|
||||
$$PWD/zxing/zxing/oned/CodaBarReader.cpp \
|
||||
|
@ -77,6 +77,7 @@ const zxing::DecodeHints DecodeHints::DEFAULT_HINT(
|
||||
|
||||
DecodeHints::DecodeHints() {
|
||||
hints = 0;
|
||||
allowedEanExtensions = {};
|
||||
}
|
||||
|
||||
DecodeHints::DecodeHints(const zxing::DecodeHintType &init) {
|
||||
@ -86,6 +87,7 @@ DecodeHints::DecodeHints(const zxing::DecodeHintType &init) {
|
||||
DecodeHints::DecodeHints(const DecodeHints &other) {
|
||||
hints = other.hints;
|
||||
callback = other.callback;
|
||||
allowedEanExtensions = other.allowedEanExtensions;
|
||||
}
|
||||
|
||||
void DecodeHints::addFormat(BarcodeFormat toadd) {
|
||||
@ -150,6 +152,14 @@ bool DecodeHints::getTryHarder() const {
|
||||
return (hints & TRYHARDER_HINT) != 0;
|
||||
}
|
||||
|
||||
void DecodeHints::setAllowedEanExtensions(std::set<int> toset) {
|
||||
allowedEanExtensions = toset;
|
||||
}
|
||||
|
||||
std::set<int> DecodeHints::getAllowedEanExtensions() const {
|
||||
return allowedEanExtensions;
|
||||
}
|
||||
|
||||
void DecodeHints::setResultPointCallback(Ref<ResultPointCallback> const& _callback) {
|
||||
callback = _callback;
|
||||
}
|
||||
@ -162,6 +172,7 @@ zxing::DecodeHints &zxing::DecodeHints::operator =(const zxing::DecodeHints &oth
|
||||
{
|
||||
hints = other.hints;
|
||||
callback = other.callback;
|
||||
allowedEanExtensions = other.allowedEanExtensions;
|
||||
return *this;
|
||||
}
|
||||
|
||||
@ -171,5 +182,27 @@ zxing::DecodeHints zxing::operator | (DecodeHints const& l, DecodeHints const& r
|
||||
if (!result.callback) {
|
||||
result.callback = r.callback;
|
||||
}
|
||||
|
||||
result.allowedEanExtensions = l.allowedEanExtensions;
|
||||
result.allowedEanExtensions.insert(r.allowedEanExtensions.begin(),
|
||||
r.allowedEanExtensions.end());
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
zxing::DecodeHints zxing::operator & (DecodeHints const& l, DecodeHints const& r) {
|
||||
DecodeHints result (l);
|
||||
result.hints &= r.hints;
|
||||
if (!result.callback) {
|
||||
result.callback = r.callback;
|
||||
}
|
||||
|
||||
std::set<int> intersect;
|
||||
std::set_intersection(l.allowedEanExtensions.begin(), l.allowedEanExtensions.end(),
|
||||
r.allowedEanExtensions.begin(), r.allowedEanExtensions.end(),
|
||||
std::inserter(intersect, intersect.begin()));
|
||||
|
||||
result.allowedEanExtensions = intersect;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -23,16 +23,20 @@
|
||||
#include <zxing/BarcodeFormat.h>
|
||||
#include <zxing/ResultPointCallback.h>
|
||||
|
||||
#include <set>
|
||||
|
||||
namespace zxing {
|
||||
|
||||
typedef unsigned int DecodeHintType;
|
||||
class DecodeHints;
|
||||
DecodeHints operator | (DecodeHints const&, DecodeHints const&);
|
||||
DecodeHints operator & (DecodeHints const&, DecodeHints const&);
|
||||
|
||||
class DecodeHints {
|
||||
private:
|
||||
DecodeHintType hints;
|
||||
Ref<ResultPointCallback> callback;
|
||||
std::set<int> allowedEanExtensions;
|
||||
|
||||
public:
|
||||
static const DecodeHintType AZTEC_HINT;
|
||||
@ -75,12 +79,16 @@ class DecodeHints {
|
||||
void setTryHarder(bool toset);
|
||||
bool getTryHarder() const;
|
||||
|
||||
void setAllowedEanExtensions(std::set<int> toset);
|
||||
std::set<int> getAllowedEanExtensions() const;
|
||||
|
||||
void setResultPointCallback(Ref<ResultPointCallback> const&);
|
||||
Ref<ResultPointCallback> getResultPointCallback() const;
|
||||
|
||||
DecodeHints& operator =(DecodeHints const &other);
|
||||
|
||||
friend DecodeHints operator| (DecodeHints const&, DecodeHints const&);
|
||||
friend DecodeHints operator& (DecodeHints const&, DecodeHints const&);
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -35,8 +35,9 @@ namespace zxing {
|
||||
Result::Result(Ref<String> text,
|
||||
ArrayRef<zxing::byte> rawBytes,
|
||||
ArrayRef< Ref<ResultPoint> > resultPoints,
|
||||
BarcodeFormat format, std::string charSet) :
|
||||
text_(text), rawBytes_(rawBytes), resultPoints_(resultPoints), format_(format), charSet_(charSet) {
|
||||
BarcodeFormat format, std::string charSet,
|
||||
ResultMetadata metadata) :
|
||||
text_(text), rawBytes_(rawBytes), resultPoints_(resultPoints), format_(format), charSet_(charSet), metadata_(metadata) {
|
||||
}
|
||||
|
||||
Result::~Result() {
|
||||
@ -67,4 +68,9 @@ std::string Result::getCharSet() const
|
||||
return charSet_;
|
||||
}
|
||||
|
||||
ResultMetadata &Result::getMetadata()
|
||||
{
|
||||
return metadata_;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include <zxing/common/Str.h>
|
||||
#include <zxing/common/Types.h>
|
||||
#include <zxing/ResultPoint.h>
|
||||
#include <zxing/ResultMetadata.h>
|
||||
#include <zxing/BarcodeFormat.h>
|
||||
|
||||
namespace zxing {
|
||||
@ -37,12 +38,14 @@ private:
|
||||
ArrayRef< Ref<ResultPoint> > resultPoints_;
|
||||
BarcodeFormat format_;
|
||||
std::string charSet_;
|
||||
ResultMetadata metadata_;
|
||||
|
||||
public:
|
||||
Result(Ref<String> text,
|
||||
ArrayRef<zxing::byte> rawBytes,
|
||||
ArrayRef< Ref<ResultPoint> > resultPoints,
|
||||
BarcodeFormat format, std::string charSet = "");
|
||||
BarcodeFormat format, std::string charSet = "",
|
||||
ResultMetadata metadata = ResultMetadata());
|
||||
~Result();
|
||||
Ref<String> getText();
|
||||
ArrayRef<zxing::byte> getRawBytes();
|
||||
@ -50,6 +53,7 @@ public:
|
||||
ArrayRef< Ref<ResultPoint> >& getResultPoints();
|
||||
BarcodeFormat getBarcodeFormat() const;
|
||||
std::string getCharSet() const;
|
||||
ResultMetadata& getMetadata();
|
||||
|
||||
friend std::ostream& operator<<(std::ostream &out, Result& result);
|
||||
};
|
||||
|
110
src/zxing/zxing/ResultMetadata.cpp
Normal file
110
src/zxing/zxing/ResultMetadata.cpp
Normal file
@ -0,0 +1,110 @@
|
||||
/*
|
||||
* Copyright 2008 ZXing 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.
|
||||
*
|
||||
* 2019-05-08 translation from Java into C++
|
||||
*/
|
||||
|
||||
#include <zxing/ResultMetadata.h>
|
||||
#include <zxing/common/ByteArray.h>
|
||||
|
||||
namespace zxing {
|
||||
|
||||
struct ResultMetadata::Value
|
||||
{
|
||||
virtual ~Value() {}
|
||||
virtual int toInteger(int fallback) const {
|
||||
return fallback;
|
||||
}
|
||||
virtual std::string toString() const {
|
||||
return std::string();
|
||||
}
|
||||
};
|
||||
|
||||
struct ResultMetadata::IntegerValue : public Value
|
||||
{
|
||||
int value;
|
||||
explicit IntegerValue(int v) : value(v) {}
|
||||
int toInteger(int) const override {
|
||||
return value;
|
||||
}
|
||||
};
|
||||
|
||||
struct ResultMetadata::StringValue : public Value
|
||||
{
|
||||
std::string value;
|
||||
explicit StringValue(std::string v) : value(std::move(v)) {}
|
||||
std::string toString() const override {
|
||||
return value;
|
||||
}
|
||||
};
|
||||
|
||||
int ResultMetadata::getInt(Key key, int fallbackValue) const
|
||||
{
|
||||
auto it = _contents.find(key);
|
||||
return it != _contents.end() ? it->second->toInteger(fallbackValue) : fallbackValue;
|
||||
}
|
||||
|
||||
std::string ResultMetadata::getString(Key key) const {
|
||||
auto it = _contents.find(key);
|
||||
return it != _contents.end() ? it->second->toString() : std::string();
|
||||
}
|
||||
|
||||
void ResultMetadata::put(Key key, int value) {
|
||||
_contents[key] = std::make_shared<IntegerValue>(value);
|
||||
}
|
||||
|
||||
void ResultMetadata::put(Key key, const std::string &value) {
|
||||
_contents[key] = std::make_shared<StringValue>(value);
|
||||
}
|
||||
|
||||
void ResultMetadata::putAll(const ResultMetadata& other) {
|
||||
_contents.insert(other._contents.begin(), other._contents.end());
|
||||
}
|
||||
|
||||
std::list<ResultMetadata::Key> ResultMetadata::keys() const
|
||||
{
|
||||
std::list<Key> keys;
|
||||
for(auto it = _contents.begin(); it != _contents.end(); ++it) {
|
||||
keys.push_back(it->first);
|
||||
}
|
||||
|
||||
return keys;
|
||||
}
|
||||
|
||||
bool ResultMetadata::empty() const
|
||||
{
|
||||
return _contents.empty();
|
||||
}
|
||||
|
||||
std::string ResultMetadata::keyToString(Key key) const
|
||||
{
|
||||
switch (key)
|
||||
{
|
||||
case OTHER: return "OTHER";
|
||||
case ORIENTATION: return "ORIENTATION";
|
||||
case BYTE_SEGMENTS: return "BYTE_SEGMENTS";
|
||||
case ERROR_CORRECTION_LEVEL: return "ERROR_CORRECTION_LEVEL";
|
||||
case ISSUE_NUMBER: return "ISSUE_NUMBER";
|
||||
case SUGGESTED_PRICE: return "SUGGESTED_PRICE";
|
||||
case POSSIBLE_COUNTRY: return "POSSIBLE_COUNTRY";
|
||||
case UPC_EAN_EXTENSION: return "UPC_EAN_EXTENSION";
|
||||
case PDF417_EXTRA_METADATA: return "PDF417_EXTRA_METADATA";
|
||||
case STRUCTURED_APPEND_SEQUENCE: return "STRUCTURED_APPEND_SEQUENCE";
|
||||
case STRUCTURED_APPEND_CODE_COUNT: return "STRUCTURED_APPEND_CODE_COUNT";
|
||||
case STRUCTURED_APPEND_PARITY: return "STRUCTURED_APPEND_PARITY";
|
||||
}
|
||||
}
|
||||
|
||||
} // zxing
|
137
src/zxing/zxing/ResultMetadata.h
Normal file
137
src/zxing/zxing/ResultMetadata.h
Normal file
@ -0,0 +1,137 @@
|
||||
#ifndef ZXING_RESULT_METADATA_H
|
||||
#define ZXING_RESULT_METADATA_H
|
||||
/*
|
||||
* Copyright 2008 ZXing 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.
|
||||
*
|
||||
* 2019-05-08 translation from Java into C++
|
||||
*/
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <list>
|
||||
|
||||
namespace zxing {
|
||||
|
||||
class ByteArray;
|
||||
|
||||
/**
|
||||
* Represents some type of metadata about the result of the decoding that the decoder
|
||||
* wishes to communicate back to the caller.
|
||||
*/
|
||||
class ResultMetadata
|
||||
{
|
||||
public:
|
||||
|
||||
enum Key {
|
||||
|
||||
/**
|
||||
* Unspecified, application-specific metadata. Maps to an unspecified {@link Object}.
|
||||
*/
|
||||
OTHER,
|
||||
|
||||
/**
|
||||
* Denotes the likely approximate orientation of the barcode in the image. This value
|
||||
* is given as degrees rotated clockwise from the normal, upright orientation.
|
||||
* For example a 1D barcode which was found by reading top-to-bottom would be
|
||||
* said to have orientation "90". This key maps to an {@link Integer} whose
|
||||
* value is in the range [0,360).
|
||||
*/
|
||||
ORIENTATION,
|
||||
|
||||
/**
|
||||
* <p>2D barcode formats typically encode text, but allow for a sort of 'byte mode'
|
||||
* which is sometimes used to encode binary data. While {@link Result} makes available
|
||||
* the complete raw bytes in the barcode for these formats, it does not offer the bytes
|
||||
* from the byte segments alone.</p>
|
||||
*/
|
||||
BYTE_SEGMENTS,
|
||||
|
||||
/**
|
||||
* Error correction level used, if applicable. The value type depends on the
|
||||
* format, but is typically a String.
|
||||
*/
|
||||
ERROR_CORRECTION_LEVEL,
|
||||
|
||||
/**
|
||||
* For some periodicals, indicates the issue number as an {@link Integer}.
|
||||
*/
|
||||
ISSUE_NUMBER,
|
||||
|
||||
/**
|
||||
* For some products, indicates the suggested retail price in the barcode as a
|
||||
* formatted {@link String}.
|
||||
*/
|
||||
SUGGESTED_PRICE,
|
||||
|
||||
/**
|
||||
* For some products, the possible country of manufacture as a {@link String} denoting the
|
||||
* ISO country code. Some map to multiple possible countries, like "US/CA".
|
||||
*/
|
||||
POSSIBLE_COUNTRY,
|
||||
|
||||
/**
|
||||
* For some products, the extension text
|
||||
*/
|
||||
UPC_EAN_EXTENSION,
|
||||
|
||||
/**
|
||||
* PDF417-specific metadata
|
||||
*/
|
||||
PDF417_EXTRA_METADATA,
|
||||
|
||||
/**
|
||||
* If the code format supports structured append and the current scanned code is part of one then the
|
||||
* sequence number is given with it.
|
||||
*/
|
||||
STRUCTURED_APPEND_SEQUENCE,
|
||||
|
||||
/**
|
||||
* If the code format supports structured append and the current scanned code is part of one then the
|
||||
* total code count is given with it.
|
||||
*/
|
||||
STRUCTURED_APPEND_CODE_COUNT,
|
||||
|
||||
/**
|
||||
* If the code format supports structured append and the current scanned code is part of one then the
|
||||
* parity is given with it.
|
||||
*/
|
||||
STRUCTURED_APPEND_PARITY
|
||||
};
|
||||
|
||||
int getInt(Key key, int fallbackValue = 0) const;
|
||||
std::string getString(Key key) const;
|
||||
|
||||
void put(Key key, int value);
|
||||
void put(Key key, const std::string& value);
|
||||
|
||||
void putAll(const ResultMetadata& other);
|
||||
|
||||
std::list<Key> keys() const;
|
||||
std::string keyToString(Key key) const;
|
||||
|
||||
bool empty() const;
|
||||
|
||||
private:
|
||||
struct Value;
|
||||
struct IntegerValue;
|
||||
struct StringValue;
|
||||
|
||||
std::map<Key, std::shared_ptr<Value>> _contents;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
42
src/zxing/zxing/common/ByteArray.h
Normal file
42
src/zxing/zxing/common/ByteArray.h
Normal file
@ -0,0 +1,42 @@
|
||||
#ifndef ZXING_BYTE_ARRAY_H
|
||||
#define ZXING_BYTE_ARRAY_H
|
||||
/*
|
||||
* Copyright 2008 ZXing 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.
|
||||
*
|
||||
* 2019-05-08 translation from Java into C++
|
||||
*/
|
||||
|
||||
#include <vector>
|
||||
#include <cstdint>
|
||||
|
||||
namespace zxing {
|
||||
|
||||
/**
|
||||
* ByteArray is an extension of std::vector<unsigned char>.
|
||||
*/
|
||||
class ByteArray : public std::vector<uint8_t>
|
||||
{
|
||||
public:
|
||||
ByteArray() {}
|
||||
ByteArray(std::initializer_list<uint8_t> list) : std::vector<uint8_t>(list) {}
|
||||
explicit ByteArray(int len) : std::vector<uint8_t>(len, 0) {}
|
||||
int length() const { return static_cast<int>(size()); }
|
||||
const char* charPtr() const { return reinterpret_cast<const char*>(data()); }
|
||||
char* charPtr() { return reinterpret_cast<char*>(data()); }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
168
src/zxing/zxing/oned/EANManufacturerOrgSupport.cpp
Normal file
168
src/zxing/zxing/oned/EANManufacturerOrgSupport.cpp
Normal file
@ -0,0 +1,168 @@
|
||||
/*
|
||||
* Copyright 2008 ZXing 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Records EAN prefix to GS1 Member Organization, where the member organization
|
||||
* correlates strongly with a country. This is an imperfect means of identifying
|
||||
* a country of origin by EAN-13 barcode value. See
|
||||
* <a href="http://en.wikipedia.org/wiki/List_of_GS1_country_codes">
|
||||
* http://en.wikipedia.org/wiki/List_of_GS1_country_codes</a>.
|
||||
*
|
||||
* @author Sean Owen
|
||||
*/
|
||||
|
||||
#include <zxing/oned/EANManufacturerOrgSupport.h>
|
||||
#include <zxing/common/Str.h>
|
||||
|
||||
#include <cstdlib>
|
||||
|
||||
namespace zxing {
|
||||
namespace oned {
|
||||
|
||||
struct Country {
|
||||
std::vector<int> range;
|
||||
std::string id;
|
||||
};
|
||||
|
||||
static Country Countries[] {
|
||||
{ {0,19}, "US/CA" },
|
||||
{ {30,39}, "US" },
|
||||
{ {60,139}, "US/CA" },
|
||||
{ {300,379}, "FR" },
|
||||
{ {380}, "BG" },
|
||||
{ {383}, "SI" },
|
||||
{ {385}, "HR" },
|
||||
{ {387}, "BA" },
|
||||
{ {400,440}, "DE" },
|
||||
{ {450,459}, "JP" },
|
||||
{ {460,469}, "RU" },
|
||||
{ {471}, "TW" },
|
||||
{ {474}, "EE" },
|
||||
{ {475}, "LV" },
|
||||
{ {476}, "AZ" },
|
||||
{ {477}, "LT" },
|
||||
{ {478}, "UZ" },
|
||||
{ {479}, "LK" },
|
||||
{ {480}, "PH" },
|
||||
{ {481}, "BY" },
|
||||
{ {482}, "UA" },
|
||||
{ {484}, "MD" },
|
||||
{ {485}, "AM" },
|
||||
{ {486}, "GE" },
|
||||
{ {487}, "KZ" },
|
||||
{ {489}, "HK" },
|
||||
{ {490,499}, "JP" },
|
||||
{ {500,509}, "GB" },
|
||||
{ {520}, "GR" },
|
||||
{ {528}, "LB" },
|
||||
{ {529}, "CY" },
|
||||
{ {531}, "MK" },
|
||||
{ {535}, "MT" },
|
||||
{ {539}, "IE" },
|
||||
{ {540,549}, "BE/LU" },
|
||||
{ {560}, "PT" },
|
||||
{ {569}, "IS" },
|
||||
{ {570,579}, "DK" },
|
||||
{ {590}, "PL" },
|
||||
{ {594}, "RO" },
|
||||
{ {599}, "HU" },
|
||||
{ {600,601}, "ZA" },
|
||||
{ {603}, "GH" },
|
||||
{ {608}, "BH" },
|
||||
{ {609}, "MU" },
|
||||
{ {611}, "MA" },
|
||||
{ {613}, "DZ" },
|
||||
{ {616}, "KE" },
|
||||
{ {618}, "CI" },
|
||||
{ {619}, "TN" },
|
||||
{ {621}, "SY" },
|
||||
{ {622}, "EG" },
|
||||
{ {624}, "LY" },
|
||||
{ {625}, "JO" },
|
||||
{ {626}, "IR" },
|
||||
{ {627}, "KW" },
|
||||
{ {628}, "SA" },
|
||||
{ {629}, "AE" },
|
||||
{ {640,649}, "FI" },
|
||||
{ {690,695}, "CN" },
|
||||
{ {700,709}, "NO" },
|
||||
{ {729}, "IL" },
|
||||
{ {730,739}, "SE" },
|
||||
{ {740}, "GT" },
|
||||
{ {741}, "SV" },
|
||||
{ {742}, "HN" },
|
||||
{ {743}, "NI" },
|
||||
{ {744}, "CR" },
|
||||
{ {745}, "PA" },
|
||||
{ {746}, "DO" },
|
||||
{ {750}, "MX" },
|
||||
{ {754,755}, "CA" },
|
||||
{ {759}, "VE" },
|
||||
{ {760,769}, "CH" },
|
||||
{ {770}, "CO" },
|
||||
{ {773}, "UY" },
|
||||
{ {775}, "PE" },
|
||||
{ {777}, "BO" },
|
||||
{ {779}, "AR" },
|
||||
{ {780}, "CL" },
|
||||
{ {784}, "PY" },
|
||||
{ {785}, "PE" },
|
||||
{ {786}, "EC" },
|
||||
{ {789,790}, "BR" },
|
||||
{ {800,839}, "IT" },
|
||||
{ {840,849}, "ES" },
|
||||
{ {850}, "CU" },
|
||||
{ {858}, "SK" },
|
||||
{ {859}, "CZ" },
|
||||
{ {860}, "YU" },
|
||||
{ {865}, "MN" },
|
||||
{ {867}, "KP" },
|
||||
{ {868,869}, "TR" },
|
||||
{ {870,879}, "NL" },
|
||||
{ {880}, "KR" },
|
||||
{ {885}, "TH" },
|
||||
{ {888}, "SG" },
|
||||
{ {890}, "IN" },
|
||||
{ {893}, "VN" },
|
||||
{ {896}, "PK" },
|
||||
{ {899}, "ID" },
|
||||
{ {900,919}, "AT" },
|
||||
{ {930,939}, "AU" },
|
||||
{ {940,949}, "AZ" },
|
||||
{ {955}, "MY" },
|
||||
{ {958}, "MO" }
|
||||
};
|
||||
|
||||
Ref<String> EANManufacturerOrgSupport::lookupCountryIdentifier(Ref<String>& productCode)
|
||||
{
|
||||
int prefix = std::atoi(productCode->getText().substr(0, 3).c_str());
|
||||
int size = (sizeof(Countries) / sizeof(Countries[0]));
|
||||
for (int i = 0; i < size; i++) {
|
||||
std::vector<int> range = Countries[i].range;
|
||||
int start = range[0];
|
||||
if (prefix < start) {
|
||||
return Ref<String>();
|
||||
}
|
||||
int end = range.size() == 1 ? start : range[1];
|
||||
if (prefix <= end) {
|
||||
return Ref<String>(new String(Countries[i].id));
|
||||
}
|
||||
}
|
||||
return Ref<String>();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
41
src/zxing/zxing/oned/EANManufacturerOrgSupport.h
Normal file
41
src/zxing/zxing/oned/EANManufacturerOrgSupport.h
Normal file
@ -0,0 +1,41 @@
|
||||
#ifndef ZXING_EAN_MANUFACTURER_ORG_SUPPORT_H
|
||||
#define ZXING_EAN_MANUFACTURER_ORG_SUPPORT_H
|
||||
/*
|
||||
* Copyright 2008 ZXing 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.
|
||||
*
|
||||
* 2019-05-08 translation from Java into C++
|
||||
*/
|
||||
|
||||
#include <zxing/common/Counted.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
namespace zxing {
|
||||
|
||||
class String;
|
||||
|
||||
namespace oned {
|
||||
|
||||
class EANManufacturerOrgSupport
|
||||
{
|
||||
public:
|
||||
static Ref<String> lookupCountryIdentifier(Ref<String> &productCode);
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -61,14 +61,14 @@ MultiFormatUPCEANReader::MultiFormatUPCEANReader(DecodeHints hints) : readers()
|
||||
|
||||
#include <typeinfo>
|
||||
|
||||
Ref<Result> MultiFormatUPCEANReader::decodeRow(int rowNumber, Ref<BitArray> row, zxing::DecodeHints /*hints*/) {
|
||||
Ref<Result> MultiFormatUPCEANReader::decodeRow(int rowNumber, Ref<BitArray> row, DecodeHints hints) {
|
||||
// Compute this location once and reuse it on multiple implementations
|
||||
UPCEANReader::Range startGuardPattern = UPCEANReader::findStartGuardPattern(row);
|
||||
for (int i = 0, e = int(readers.size()); i < e; i++) {
|
||||
Ref<UPCEANReader> reader = readers[i];
|
||||
Ref<Result> result;
|
||||
try {
|
||||
result = reader->decodeRow(rowNumber, row, startGuardPattern);
|
||||
result = reader->decodeRow(rowNumber, row, startGuardPattern, hints);
|
||||
} catch (ReaderException const& ignored) {
|
||||
(void)ignored;
|
||||
continue;
|
||||
|
96
src/zxing/zxing/oned/UPCEANExtension2Support.cpp
Normal file
96
src/zxing/zxing/oned/UPCEANExtension2Support.cpp
Normal file
@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Copyright 2008 ZXing 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.
|
||||
*
|
||||
* 2019-05-08 translation from Java into C++
|
||||
*/
|
||||
|
||||
#include <zxing/oned/UPCEANExtension2Support.h>
|
||||
#include <zxing/oned/UPCEANReader.h>
|
||||
#include <zxing/oned/OneDResultPoint.h>
|
||||
#include <zxing/common/BitArray.h>
|
||||
#include <zxing/Result.h>
|
||||
#include <zxing/NotFoundException.h>
|
||||
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
#include <cstdlib>
|
||||
|
||||
namespace zxing {
|
||||
namespace oned {
|
||||
|
||||
static int decodeMiddle(Ref<BitArray> row, int rowOffset_, std::string& resultString)
|
||||
{
|
||||
std::vector<int> counters(4);
|
||||
counters[0] = 0;
|
||||
counters[1] = 0;
|
||||
counters[2] = 0;
|
||||
counters[3] = 0;
|
||||
|
||||
int end = row->getSize();
|
||||
int rowOffset = rowOffset_;
|
||||
|
||||
int lgPatternFound = 0;
|
||||
|
||||
for (int x = 0; x < 2 && rowOffset < end; x++) {
|
||||
int bestMatch = UPCEANReader::decodeDigit(row, counters, rowOffset,
|
||||
UPCEANReader::L_AND_G_PATTERNS);
|
||||
resultString += static_cast<char>('0' + bestMatch % 10);
|
||||
for (int counter : counters) {
|
||||
rowOffset += counter;
|
||||
}
|
||||
if (bestMatch >= 10) {
|
||||
lgPatternFound |= 1 << (1 - x);
|
||||
}
|
||||
if (x != 1) {
|
||||
// Read off separator if not last
|
||||
rowOffset = row->getNextSet(rowOffset);
|
||||
rowOffset = row->getNextUnset(rowOffset);
|
||||
}
|
||||
}
|
||||
|
||||
if (resultString.length() != 2) {
|
||||
throw NotFoundException();
|
||||
}
|
||||
|
||||
if (std::atoi(resultString.c_str()) % 4 !=lgPatternFound) {
|
||||
throw NotFoundException();
|
||||
}
|
||||
|
||||
return rowOffset;
|
||||
}
|
||||
|
||||
Ref<Result> UPCEANExtension2Support::decodeRow(int rowNumber, Ref<BitArray> row, int extStartRangeBegin, int extStartRangeEnd)
|
||||
{
|
||||
std::string resultString;
|
||||
int range = decodeMiddle(row, extStartRangeEnd, resultString);
|
||||
|
||||
ResultMetadata metadata;
|
||||
metadata.put(ResultMetadata::ISSUE_NUMBER, std::atoi(resultString.c_str()));
|
||||
|
||||
ArrayRef< Ref<ResultPoint> > resultPoints(2);
|
||||
resultPoints[0] = Ref<OneDResultPoint>(new OneDResultPoint((extStartRangeBegin + extStartRangeEnd) / 2.0f,
|
||||
static_cast<float> (rowNumber)));
|
||||
resultPoints[1] = Ref<OneDResultPoint>(new OneDResultPoint(static_cast<float> (range),
|
||||
static_cast<float> (rowNumber)));
|
||||
return Ref<Result>(new Result(Ref<String>(new String(resultString)),
|
||||
ArrayRef<zxing::byte>(),
|
||||
resultPoints,
|
||||
BarcodeFormat::UPC_EAN_EXTENSION,
|
||||
"",
|
||||
metadata));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
38
src/zxing/zxing/oned/UPCEANExtension2Support.h
Normal file
38
src/zxing/zxing/oned/UPCEANExtension2Support.h
Normal file
@ -0,0 +1,38 @@
|
||||
#ifndef ZXING_UPCEAN_EXTENSION_2_SUPPORT_H
|
||||
#define ZXING_UPCEAN_EXTENSION_2_SUPPORT_H
|
||||
/*
|
||||
* Copyright 2008 ZXing 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.
|
||||
*
|
||||
* 2019-05-08 translation from Java into C++
|
||||
*/
|
||||
#include <zxing/common/Counted.h>
|
||||
|
||||
namespace zxing {
|
||||
|
||||
class Result;
|
||||
class BitArray;
|
||||
|
||||
namespace oned {
|
||||
|
||||
class UPCEANExtension2Support
|
||||
{
|
||||
public:
|
||||
static Ref<Result> decodeRow(int rowNumber, Ref<BitArray> row, int extStartRangeBegin, int extStartRangeEnd);
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
165
src/zxing/zxing/oned/UPCEANExtension5Support.cpp
Normal file
165
src/zxing/zxing/oned/UPCEANExtension5Support.cpp
Normal file
@ -0,0 +1,165 @@
|
||||
/*
|
||||
* Copyright 2008 ZXing 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.
|
||||
*
|
||||
* 2019-05-08 translation from Java into C++
|
||||
*/
|
||||
|
||||
#include <zxing/oned/UPCEANExtension5Support.h>
|
||||
#include <zxing/oned/UPCEANReader.h>
|
||||
#include <zxing/oned/OneDResultPoint.h>
|
||||
#include <zxing/common/BitArray.h>
|
||||
#include <zxing/Result.h>
|
||||
#include <zxing/NotFoundException.h>
|
||||
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
#include <cstdlib>
|
||||
|
||||
namespace zxing {
|
||||
namespace oned {
|
||||
|
||||
static int extensionChecksum(const std::string& s)
|
||||
{
|
||||
int length = static_cast<int>(s.length());
|
||||
int sum = 0;
|
||||
for (int i = length - 2; i >= 0; i -= 2) {
|
||||
sum += (int)s[i] - (int) '0';
|
||||
}
|
||||
sum *= 3;
|
||||
for (int i = length - 1; i >= 0; i -= 2) {
|
||||
sum += (int)s[i] - (int) '0';
|
||||
}
|
||||
sum *= 3;
|
||||
return sum % 10;
|
||||
}
|
||||
|
||||
static int determineCheckDigit(int lgPatternFound)
|
||||
{
|
||||
static const int CHECK_DIGIT_ENCODINGS[] = {
|
||||
0x18, 0x14, 0x12, 0x11, 0x0C, 0x06, 0x03, 0x0A, 0x09, 0x05
|
||||
};
|
||||
for (int d = 0; d < 10; d++) {
|
||||
if (lgPatternFound == CHECK_DIGIT_ENCODINGS[d]) {
|
||||
return d;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int decodeMiddle(Ref<BitArray> row, int rowOffset_, std::string& resultString)
|
||||
{
|
||||
std::vector<int> counters(4);
|
||||
counters[0] = 0;
|
||||
counters[1] = 0;
|
||||
counters[2] = 0;
|
||||
counters[3] = 0;
|
||||
|
||||
int end = row->getSize();
|
||||
int rowOffset = rowOffset_;
|
||||
|
||||
int lgPatternFound = 0;
|
||||
|
||||
for (int x = 0; x < 5 && rowOffset < end; x++) {
|
||||
int bestMatch = UPCEANReader::decodeDigit(row, counters, rowOffset,
|
||||
UPCEANReader::L_AND_G_PATTERNS);
|
||||
resultString += static_cast<char>('0' + bestMatch % 10);
|
||||
for (int counter : counters) {
|
||||
rowOffset += counter;
|
||||
}
|
||||
if (bestMatch >= 10) {
|
||||
lgPatternFound |= 1 << (4 - x);
|
||||
}
|
||||
if (x != 4) {
|
||||
// Read off separator if not last
|
||||
rowOffset = row->getNextSet(rowOffset);
|
||||
rowOffset = row->getNextUnset(rowOffset);
|
||||
}
|
||||
}
|
||||
|
||||
if (resultString.length() != 5) {
|
||||
throw NotFoundException();
|
||||
}
|
||||
|
||||
int checkDigit = determineCheckDigit(lgPatternFound);
|
||||
if (extensionChecksum(resultString) != checkDigit) {
|
||||
throw NotFoundException();
|
||||
}
|
||||
|
||||
return rowOffset;
|
||||
}
|
||||
|
||||
static std::string parseExtension5String(const std::string& raw)
|
||||
{
|
||||
std::string currency;
|
||||
switch (raw.front()) {
|
||||
case '0':
|
||||
currency = "\xa3";
|
||||
break;
|
||||
case '5':
|
||||
currency = "$";
|
||||
break;
|
||||
case '9':
|
||||
// Reference: http://www.jollytech.com
|
||||
if (raw == "90000") {
|
||||
// No suggested retail price
|
||||
return std::string();
|
||||
}
|
||||
if (raw == "99991") {
|
||||
// Complementary
|
||||
return "0.00";
|
||||
}
|
||||
if (raw == "99990") {
|
||||
return "Used";
|
||||
}
|
||||
// Otherwise... unknown currency?
|
||||
currency = "";
|
||||
break;
|
||||
default:
|
||||
currency = "";
|
||||
break;
|
||||
}
|
||||
int rawAmount = std::atoi(raw.substr(1).c_str());
|
||||
std::stringstream buf;
|
||||
buf << currency << std::fixed << std::setprecision(2) << (float(rawAmount) / 100);
|
||||
return buf.str();
|
||||
}
|
||||
|
||||
Ref<Result> UPCEANExtension5Support::decodeRow(int rowNumber, Ref<BitArray> row, int extStartRangeBegin, int extStartRangeEnd)
|
||||
{
|
||||
std::string resultString;
|
||||
int range = decodeMiddle(row, extStartRangeEnd, resultString);
|
||||
|
||||
ResultMetadata metadata;
|
||||
std::string value = parseExtension5String(resultString);
|
||||
if (!value.empty()) {
|
||||
metadata.put(ResultMetadata::SUGGESTED_PRICE, value);
|
||||
}
|
||||
|
||||
ArrayRef< Ref<ResultPoint> > resultPoints(2);
|
||||
resultPoints[0] = Ref<OneDResultPoint>(new OneDResultPoint((extStartRangeBegin + extStartRangeEnd) / 2.0f,
|
||||
static_cast<float> (rowNumber)));
|
||||
resultPoints[1] = Ref<OneDResultPoint>(new OneDResultPoint(static_cast<float> (range),
|
||||
static_cast<float> (rowNumber)));
|
||||
|
||||
return Ref<Result>(new Result(Ref<String>(new String(resultString)),
|
||||
ArrayRef<zxing::byte>(),
|
||||
resultPoints,
|
||||
BarcodeFormat::UPC_EAN_EXTENSION,
|
||||
"",
|
||||
metadata));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
38
src/zxing/zxing/oned/UPCEANExtension5Support.h
Normal file
38
src/zxing/zxing/oned/UPCEANExtension5Support.h
Normal file
@ -0,0 +1,38 @@
|
||||
#ifndef ZXING_UPCEAN_EXTENSION_5_SUPPORT_H
|
||||
#define ZXING_UPCEAN_EXTENSION_5_SUPPORT_H
|
||||
/*
|
||||
* Copyright 2008 ZXing 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.
|
||||
*
|
||||
* 2019-05-08 translation from Java into C++
|
||||
*/
|
||||
#include <zxing/common/Counted.h>
|
||||
|
||||
namespace zxing {
|
||||
|
||||
class Result;
|
||||
class BitArray;
|
||||
|
||||
namespace oned {
|
||||
|
||||
class UPCEANExtension5Support
|
||||
{
|
||||
public:
|
||||
static Ref<Result> decodeRow(int rowNumber, Ref<BitArray> row, int extStartRangeBegin, int extStartRangeEnd);
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
44
src/zxing/zxing/oned/UPCEANExtensionSupport.cpp
Normal file
44
src/zxing/zxing/oned/UPCEANExtensionSupport.cpp
Normal file
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright 2008 ZXing 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.
|
||||
*
|
||||
* 2019-05-08 translation from Java into C++
|
||||
*/
|
||||
|
||||
#include <zxing/oned/UPCEANExtensionSupport.h>
|
||||
#include <zxing/oned/UPCEANExtension5Support.h>
|
||||
#include <zxing/oned/UPCEANExtension2Support.h>
|
||||
#include <zxing/oned/UPCEANReader.h>
|
||||
#include <zxing/Result.h>
|
||||
#include <zxing/common/BitArray.h>
|
||||
#include <zxing/NotFoundException.h>
|
||||
|
||||
namespace zxing {
|
||||
namespace oned {
|
||||
|
||||
static const std::vector<int> EXTENSION_START_PATTERN = { 1, 1, 2 };
|
||||
|
||||
Ref<Result> UPCEANExtensionSupport::decodeRow(int rowNumber, Ref<BitArray> row, int rowOffset)
|
||||
{
|
||||
auto extStartRange = UPCEANReader::findGuardPattern(row, rowOffset, false, EXTENSION_START_PATTERN);
|
||||
|
||||
try {
|
||||
return UPCEANExtension5Support::decodeRow(rowNumber, row, extStartRange[0], extStartRange[1]);
|
||||
} catch (NotFoundException const& /*nfe*/) {
|
||||
return UPCEANExtension2Support::decodeRow(rowNumber, row, extStartRange[0], extStartRange[1]);
|
||||
}
|
||||
}
|
||||
|
||||
} // oned
|
||||
} // zxing
|
38
src/zxing/zxing/oned/UPCEANExtensionSupport.h
Normal file
38
src/zxing/zxing/oned/UPCEANExtensionSupport.h
Normal file
@ -0,0 +1,38 @@
|
||||
#ifndef ZXING_UPCEAN_EXTENSION_SUPPORT_H
|
||||
#define ZXING_UPCEAN_EXTENSION_SUPPORT_H
|
||||
/*
|
||||
* Copyright 2008 ZXing 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.
|
||||
*
|
||||
* 2019-05-08 translation from Java into C++
|
||||
*/
|
||||
#include <zxing/common/Counted.h>
|
||||
|
||||
namespace zxing {
|
||||
|
||||
class Result;
|
||||
class BitArray;
|
||||
|
||||
namespace oned {
|
||||
|
||||
class UPCEANExtensionSupport
|
||||
{
|
||||
public:
|
||||
static Ref<Result> decodeRow(int rowNumber, Ref<BitArray> row, int rowOffset);
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -118,13 +118,14 @@ UPCEANReader::L_AND_G_PATTERNS (VECTOR_INIT(L_AND_G_PATTERNS_));
|
||||
|
||||
UPCEANReader::UPCEANReader() {}
|
||||
|
||||
Ref<Result> UPCEANReader::decodeRow(int rowNumber, Ref<BitArray> row, zxing::DecodeHints /*hints*/) {
|
||||
return decodeRow(rowNumber, row, findStartGuardPattern(row));
|
||||
Ref<Result> UPCEANReader::decodeRow(int rowNumber, Ref<BitArray> row, DecodeHints hints) {
|
||||
return decodeRow(rowNumber, row, findStartGuardPattern(row), hints);
|
||||
}
|
||||
|
||||
Ref<Result> UPCEANReader::decodeRow(int rowNumber,
|
||||
Ref<BitArray> row,
|
||||
Range const& startGuardRange) {
|
||||
Range const& startGuardRange,
|
||||
DecodeHints hints) {
|
||||
string& result = decodeRowStringBuffer;
|
||||
result.clear();
|
||||
int endStart = decodeMiddle(row, startGuardRange, result);
|
||||
@ -153,11 +154,50 @@ Ref<Result> UPCEANReader::decodeRow(int rowNumber,
|
||||
float left = (float) (startGuardRange[1] + startGuardRange[0]) / 2.0f;
|
||||
float right = (float) (endRange[1] + endRange[0]) / 2.0f;
|
||||
BarcodeFormat format = getBarcodeFormat();
|
||||
|
||||
ArrayRef< Ref<ResultPoint> > resultPoints(2);
|
||||
resultPoints[0] = Ref<ResultPoint>(new OneDResultPoint(left, (float) rowNumber));
|
||||
resultPoints[1] = Ref<ResultPoint>(new OneDResultPoint(right, (float) rowNumber));
|
||||
resultPoints[0] = Ref<ResultPoint>(new OneDResultPoint(left, static_cast<float> (rowNumber)));
|
||||
resultPoints[1] = Ref<ResultPoint>(new OneDResultPoint(right, static_cast<float> (rowNumber)));
|
||||
|
||||
Ref<Result> decodeResult (new Result(resultString, ArrayRef<zxing::byte>(), resultPoints, format));
|
||||
// Java extension and man stuff
|
||||
int extensionLength = 0;
|
||||
|
||||
try {
|
||||
Ref<Result> extensionResult = extensionReader.decodeRow(rowNumber, row, endRange[1]);
|
||||
if (extensionResult) {
|
||||
decodeResult->getMetadata().put(ResultMetadata::UPC_EAN_EXTENSION, extensionResult->getText()->getText());
|
||||
decodeResult->getMetadata().putAll(extensionResult->getMetadata());
|
||||
extensionLength = extensionResult->getText()->length();
|
||||
|
||||
for (const Ref<ResultPoint>& resultPoint: extensionResult->getResultPoints()->values()) {
|
||||
decodeResult->getResultPoints()->push_back(resultPoint);
|
||||
}
|
||||
}
|
||||
} catch (NotFoundException const& /*nfe*/) {
|
||||
// continue
|
||||
}
|
||||
|
||||
std::set<int> allowedExtensions = hints.getAllowedEanExtensions();
|
||||
if (allowedExtensions.size() > 0) {
|
||||
bool valid = false;
|
||||
for (int length: allowedExtensions) {
|
||||
if (extensionLength == length) {
|
||||
valid = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!valid) {
|
||||
throw NotFoundException();
|
||||
}
|
||||
}
|
||||
|
||||
if (format == BarcodeFormat::EAN_13 || format == BarcodeFormat::UPC_A) {
|
||||
Ref<String> countryID = eanManSupport.lookupCountryIdentifier(resultString);
|
||||
if (countryID) {
|
||||
decodeResult->getMetadata().put(ResultMetadata::POSSIBLE_COUNTRY, countryID->getText());
|
||||
}
|
||||
}
|
||||
|
||||
return decodeResult;
|
||||
}
|
||||
|
||||
|
@ -19,6 +19,8 @@
|
||||
*/
|
||||
|
||||
#include <zxing/oned/OneDReader.h>
|
||||
#include <zxing/oned/UPCEANExtensionSupport.h>
|
||||
#include <zxing/oned/EANManufacturerOrgSupport.h>
|
||||
#include <zxing/common/BitArray.h>
|
||||
#include <zxing/Result.h>
|
||||
|
||||
@ -28,8 +30,8 @@ namespace oned {
|
||||
class UPCEANReader : public OneDReader {
|
||||
private:
|
||||
std::string decodeRowStringBuffer;
|
||||
// UPCEANExtensionSupport extensionReader;
|
||||
// EANManufacturerOrgSupport eanManSupport;
|
||||
UPCEANExtensionSupport extensionReader;
|
||||
EANManufacturerOrgSupport eanManSupport;
|
||||
|
||||
static const int MAX_AVG_VARIANCE;
|
||||
static const int MAX_INDIVIDUAL_VARIANCE;
|
||||
@ -47,7 +49,7 @@ class UPCEANReader : public OneDReader {
|
||||
std::vector<int>& counters);
|
||||
|
||||
|
||||
protected:
|
||||
public:
|
||||
static const std::vector<int> START_END_PATTERN;
|
||||
static const std::vector<int> MIDDLE_PATTERN;
|
||||
|
||||
@ -67,7 +69,7 @@ public:
|
||||
std::string& resultString) = 0;
|
||||
|
||||
virtual Ref<Result> decodeRow(int rowNumber, Ref<BitArray> row, DecodeHints hints);
|
||||
virtual Ref<Result> decodeRow(int rowNumber, Ref<BitArray> row, Range const& range);
|
||||
virtual Ref<Result> decodeRow(int rowNumber, Ref<BitArray> row, Range const& range, DecodeHints hints = DecodeHints());
|
||||
|
||||
static int decodeDigit(Ref<BitArray> row,
|
||||
std::vector<int>& counters,
|
||||
|
Loading…
x
Reference in New Issue
Block a user