update zxing

This commit is contained in:
arm64v8a 2023-02-13 22:30:16 +09:00
parent af01bc7a89
commit fbffd4e606
2 changed files with 253 additions and 195 deletions

View File

@ -1,28 +1,24 @@
#pragma once
/* /*
* Copyright 2020 Axel Waggershauser * Copyright 2020 Axel Waggershauser
*
* 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.
*/ */
// SPDX-License-Identifier: Apache-2.0
#pragma once
#include "ZXing/ReadBarcode.h" #include "ZXing/ReadBarcode.h"
#include <QImage> #include <QImage>
#include <QDebug> #include <QDebug>
#include <QMetaType> #include <QMetaType>
#include <QScopeGuard>
#ifdef QT_MULTIMEDIA_LIB #ifdef QT_MULTIMEDIA_LIB
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
#include <QAbstractVideoFilter> #include <QAbstractVideoFilter>
#else
#include <QVideoFrame>
#include <QVideoSink>
#endif
#include <QElapsedTimer> #include <QElapsedTimer>
#endif #endif
@ -30,167 +26,176 @@
namespace ZXingQt { namespace ZXingQt {
Q_NAMESPACE Q_NAMESPACE
//TODO: find a better way to export these enums to QML than to duplicate their definition //TODO: find a better way to export these enums to QML than to duplicate their definition
// #ifdef Q_MOC_RUN produces meta information in the moc output but it does end up working in qml // #ifdef Q_MOC_RUN produces meta information in the moc output but it does end up working in qml
#ifdef QT_QML_LIB #ifdef QT_QML_LIB
enum class BarcodeFormat enum class BarcodeFormat
{ {
None = 0, ///< Used as a return value if no valid barcode has been detected None = 0, ///< Used as a return value if no valid barcode has been detected
Aztec = (1 << 0), ///< Aztec (2D) Aztec = (1 << 0), ///< Aztec
Codabar = (1 << 1), ///< Codabar (1D) Codabar = (1 << 1), ///< Codabar
Code39 = (1 << 2), ///< Code39 (1D) Code39 = (1 << 2), ///< Code39
Code93 = (1 << 3), ///< Code93 (1D) Code93 = (1 << 3), ///< Code93
Code128 = (1 << 4), ///< Code128 (1D) Code128 = (1 << 4), ///< Code128
DataBar = (1 << 5), ///< GS1 DataBar, formerly known as RSS 14 DataBar = (1 << 5), ///< GS1 DataBar, formerly known as RSS 14
DataBarExpanded = (1 << 6), ///< GS1 DataBar Expanded, formerly known as RSS EXPANDED DataBarExpanded = (1 << 6), ///< GS1 DataBar Expanded, formerly known as RSS EXPANDED
DataMatrix = (1 << 7), ///< DataMatrix (2D) DataMatrix = (1 << 7), ///< DataMatrix
EAN8 = (1 << 8), ///< EAN-8 (1D) EAN8 = (1 << 8), ///< EAN-8
EAN13 = (1 << 9), ///< EAN-13 (1D) EAN13 = (1 << 9), ///< EAN-13
ITF = (1 << 10), ///< ITF (Interleaved Two of Five) (1D) ITF = (1 << 10), ///< ITF (Interleaved Two of Five)
MaxiCode = (1 << 11), ///< MaxiCode (2D) MaxiCode = (1 << 11), ///< MaxiCode
PDF417 = (1 << 12), ///< PDF417 (1D) or (2D) PDF417 = (1 << 12), ///< PDF417 or
QRCode = (1 << 13), ///< QR Code (2D) QRCode = (1 << 13), ///< QR Code
UPCA = (1 << 14), ///< UPC-A (1D) UPCA = (1 << 14), ///< UPC-A
UPCE = (1 << 15), ///< UPC-E (1D) UPCE = (1 << 15), ///< UPC-E
MicroQRCode = (1 << 16), ///< Micro QR Code (2D) MicroQRCode = (1 << 16), ///< Micro QR Code
OneDCodes = Codabar | Code39 | Code93 | Code128 | EAN8 | EAN13 | ITF | DataBar | DataBarExpanded | UPCA | UPCE, LinearCodes = Codabar | Code39 | Code93 | Code128 | EAN8 | EAN13 | ITF | DataBar | DataBarExpanded | UPCA | UPCE,
TwoDCodes = Aztec | DataMatrix | MaxiCode | PDF417 | QRCode | MicroQRCode, MatrixCodes = Aztec | DataMatrix | MaxiCode | PDF417 | QRCode | MicroQRCode,
}; };
enum class DecodeStatus enum class ContentType { Text, Binary, Mixed, GS1, ISO15434, UnknownECI };
#else
using ZXing::BarcodeFormat;
using ZXing::ContentType;
#endif
using ZXing::DecodeHints;
using ZXing::Binarizer;
using ZXing::BarcodeFormats;
Q_ENUM_NS(BarcodeFormat)
Q_ENUM_NS(ContentType)
template<typename T, typename = decltype(ZXing::ToString(T()))>
QDebug operator<<(QDebug dbg, const T& v)
{ {
NoError = 0, return dbg.noquote() << QString::fromStdString(ToString(v));
NotFound, }
FormatError,
ChecksumError, class Position : public ZXing::Quadrilateral<QPoint>
{
Q_GADGET
Q_PROPERTY(QPoint topLeft READ topLeft)
Q_PROPERTY(QPoint topRight READ topRight)
Q_PROPERTY(QPoint bottomRight READ bottomRight)
Q_PROPERTY(QPoint bottomLeft READ bottomLeft)
using Base = ZXing::Quadrilateral<QPoint>;
public:
using Base::Base;
}; };
#else
using ZXing::BarcodeFormat;
using ZXing::DecodeStatus;
#endif
using ZXing::DecodeHints; class Result : private ZXing::Result
using ZXing::Binarizer; {
using ZXing::BarcodeFormats; Q_GADGET
Q_ENUM_NS(BarcodeFormat) Q_PROPERTY(BarcodeFormat format READ format)
Q_ENUM_NS(DecodeStatus) Q_PROPERTY(QString formatName READ formatName)
Q_PROPERTY(QString text READ text)
Q_PROPERTY(QByteArray bytes READ bytes)
Q_PROPERTY(bool isValid READ isValid)
Q_PROPERTY(ContentType contentType READ contentType)
Q_PROPERTY(Position position READ position)
template<typename T, typename = decltype(ZXing::ToString(T()))> QString _text;
QDebug operator<<(QDebug dbg, const T& v) QByteArray _bytes;
{ Position _position;
return dbg.noquote() << QString::fromStdString(ToString(v));
}
class Position : public ZXing::Quadrilateral<QPoint> public:
{ Result() = default; // required for qmetatype machinery
Q_GADGET
Q_PROPERTY(QPoint topLeft READ topLeft) explicit Result(ZXing::Result&& r) : ZXing::Result(std::move(r)) {
Q_PROPERTY(QPoint topRight READ topRight) _text = QString::fromStdString(ZXing::Result::text());
Q_PROPERTY(QPoint bottomRight READ bottomRight) _bytes = QByteArray(reinterpret_cast<const char*>(ZXing::Result::bytes().data()), Size(ZXing::Result::bytes()));
Q_PROPERTY(QPoint bottomLeft READ bottomLeft) auto& pos = ZXing::Result::position();
auto qp = [&pos](int i) { return QPoint(pos[i].x, pos[i].y); };
_position = {qp(0), qp(1), qp(2), qp(3)};
}
using Base = ZXing::Quadrilateral<QPoint>; using ZXing::Result::isValid;
public: BarcodeFormat format() const { return static_cast<BarcodeFormat>(ZXing::Result::format()); }
using Base::Base; ContentType contentType() const { return static_cast<ContentType>(ZXing::Result::contentType()); }
}; QString formatName() const { return QString::fromStdString(ZXing::ToString(ZXing::Result::format())); }
const QString& text() const { return _text; }
const QByteArray& bytes() const { return _bytes; }
const Position& position() const { return _position; }
class Result : private ZXing::Result // For debugging/development
{ int runTime = 0;
Q_GADGET Q_PROPERTY(int runTime MEMBER runTime)
};
Q_PROPERTY(BarcodeFormat format READ format) inline QList<Result> QListResults(ZXing::Results&& zxres)
Q_PROPERTY(QString formatName READ formatName) {
Q_PROPERTY(QString text READ text) QList<Result> res;
Q_PROPERTY(QByteArray rawBytes READ rawBytes) for (auto&& r : zxres)
Q_PROPERTY(bool isValid READ isValid) res.push_back(Result(std::move(r)));
Q_PROPERTY(DecodeStatus status READ status) return res;
Q_PROPERTY(Position position READ position) }
QString _text; inline QList<Result> ReadBarcodes(const QImage& img, const DecodeHints& hints = {})
QByteArray _rawBytes;
Position _position;
public:
Result() : ZXing::Result(ZXing::DecodeStatus::NotFound) {} // required for qmetatype machinery
explicit Result(ZXing::Result&& r) : ZXing::Result(std::move(r)) {
_text = QString::fromWCharArray(ZXing::Result::text().c_str());
_rawBytes = QByteArray(reinterpret_cast<const char*>(ZXing::Result::rawBytes().data()),
Size(ZXing::Result::rawBytes()));
auto& pos = ZXing::Result::position();
auto qp = [&pos](int i) { return QPoint(pos[i].x, pos[i].y); };
_position = {qp(0), qp(1), qp(2), qp(3)};
}
using ZXing::Result::isValid;
BarcodeFormat format() const { return static_cast<BarcodeFormat>(ZXing::Result::format()); }
DecodeStatus status() const { return static_cast<DecodeStatus>(ZXing::Result::status()); }
QString formatName() const { return QString::fromStdString(ZXing::ToString(ZXing::Result::format())); }
const QString& text() const { return _text; }
const QByteArray& rawBytes() const { return _rawBytes; }
const Position& position() const { return _position; }
// For debugging/development
int runTime = 0;
Q_PROPERTY(int runTime MEMBER runTime)
};
inline Result ReadBarcode(const QImage& img, const DecodeHints& hints = {})
{
using namespace ZXing;
auto ImgFmtFromQImg = [](const QImage& img) {
switch (img.format()) {
case QImage::Format_ARGB32:
case QImage::Format_RGB32:
#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
return ImageFormat::BGRX;
#else
return ImageFormat::XRGB;
#endif
case QImage::Format_RGB888: return ImageFormat::RGB;
case QImage::Format_RGBX8888:
case QImage::Format_RGBA8888: return ImageFormat::RGBX;
case QImage::Format_Grayscale8: return ImageFormat::Lum;
default: return ImageFormat::None;
}
};
auto exec = [&](const QImage& img) {
return Result(ZXing::ReadBarcode(
{img.bits(), img.width(), img.height(), ImgFmtFromQImg(img), static_cast<int>(img.bytesPerLine())}, hints));
};
return ImgFmtFromQImg(img) == ImageFormat::None ? exec(img.convertToFormat(QImage::Format_Grayscale8)) : exec(img);
}
#ifdef QT_MULTIMEDIA_LIB
inline Result ReadBarcode(const QVideoFrame& frame, const DecodeHints& hints = {})
{ {
using namespace ZXing; using namespace ZXing;
auto img = frame; // shallow copy just get access to non-const map() function auto ImgFmtFromQImg = [](const QImage& img) {
if (!frame.isValid() || !img.map(QAbstractVideoBuffer::ReadOnly)){ switch (img.format()) {
qWarning() << "invalid QVideoFrame: could not map memory"; case QImage::Format_ARGB32:
return {}; case QImage::Format_RGB32:
} #if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
//TODO c++17: SCOPE_EXIT([&] { img.unmap(); }); return ImageFormat::BGRX;
#else
return ImageFormat::XRGB;
#endif
case QImage::Format_RGB888: return ImageFormat::RGB;
case QImage::Format_RGBX8888:
case QImage::Format_RGBA8888: return ImageFormat::RGBX;
case QImage::Format_Grayscale8: return ImageFormat::Lum;
default: return ImageFormat::None;
}
};
auto exec = [&](const QImage& img) {
return QListResults(ZXing::ReadBarcodes(
{img.bits(), img.width(), img.height(), ImgFmtFromQImg(img), static_cast<int>(img.bytesPerLine())}, hints));
};
return ImgFmtFromQImg(img) == ImageFormat::None ? exec(img.convertToFormat(QImage::Format_Grayscale8)) : exec(img);
}
inline Result ReadBarcode(const QImage& img, const DecodeHints& hints = {})
{
auto res = ReadBarcodes(img, DecodeHints(hints).setMaxNumberOfSymbols(1));
return !res.isEmpty() ? res.takeFirst() : Result();
}
#ifdef QT_MULTIMEDIA_LIB
inline QList<Result> ReadBarcodes(const QVideoFrame& frame, const DecodeHints& hints = {})
{
using namespace ZXing;
ImageFormat fmt = ImageFormat::None; ImageFormat fmt = ImageFormat::None;
int pixStride = 0; int pixStride = 0;
int pixOffset = 0; int pixOffset = 0;
switch (img.pixelFormat()) { #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
case QVideoFrame::Format_ARGB32: #define FORMAT(F5, F6) QVideoFrame::Format_##F5
case QVideoFrame::Format_ARGB32_Premultiplied: #define FIRST_PLANE
case QVideoFrame::Format_RGB32: #else
#define FORMAT(F5, F6) QVideoFrameFormat::Format_##F6
#define FIRST_PLANE 0
#endif
switch (frame.pixelFormat()) {
case FORMAT(ARGB32, ARGB8888):
case FORMAT(ARGB32_Premultiplied, ARGB8888_Premultiplied):
case FORMAT(RGB32, RGBX8888):
#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN #if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
fmt = ImageFormat::BGRX; fmt = ImageFormat::BGRX;
#else #else
@ -198,11 +203,9 @@ enum class DecodeStatus
#endif #endif
break; break;
case QVideoFrame::Format_RGB24: fmt = ImageFormat::RGB; break; case FORMAT(BGRA32, BGRA8888):
case FORMAT(BGRA32_Premultiplied, BGRA8888_Premultiplied):
case QVideoFrame::Format_BGRA32: case FORMAT(BGR32, BGRX8888):
case QVideoFrame::Format_BGRA32_Premultiplied:
case QVideoFrame::Format_BGR32:
#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN #if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
fmt = ImageFormat::RGBX; fmt = ImageFormat::RGBX;
#else #else
@ -210,10 +213,17 @@ enum class DecodeStatus
#endif #endif
break; break;
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
case QVideoFrame::Format_RGB24: fmt = ImageFormat::RGB; break;
case QVideoFrame::Format_BGR24: fmt = ImageFormat::BGR; break; case QVideoFrame::Format_BGR24: fmt = ImageFormat::BGR; break;
case QVideoFrame::Format_YUV444: fmt = ImageFormat::Lum, pixStride = 3; break;
#else
case QVideoFrameFormat::Format_P010:
case QVideoFrameFormat::Format_P016: fmt = ImageFormat::Lum, pixStride = 1; break;
#endif
case QVideoFrame::Format_AYUV444: case FORMAT(AYUV444, AYUV):
case QVideoFrame::Format_AYUV444_Premultiplied: case FORMAT(AYUV444_Premultiplied, AYUV_Premultiplied):
#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN #if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
fmt = ImageFormat::Lum, pixStride = 4, pixOffset = 3; fmt = ImageFormat::Lum, pixStride = 4, pixOffset = 3;
#else #else
@ -221,23 +231,22 @@ enum class DecodeStatus
#endif #endif
break; break;
case QVideoFrame::Format_YUV444: fmt = ImageFormat::Lum, pixStride = 3; break; case FORMAT(YUV420P, YUV420P):
case QVideoFrame::Format_YUV420P: case FORMAT(NV12, NV12):
case QVideoFrame::Format_NV12: case FORMAT(NV21, NV21):
case QVideoFrame::Format_NV21: case FORMAT(IMC1, IMC1):
case QVideoFrame::Format_IMC1: case FORMAT(IMC2, IMC2):
case QVideoFrame::Format_IMC2: case FORMAT(IMC3, IMC3):
case QVideoFrame::Format_IMC3: case FORMAT(IMC4, IMC4):
case QVideoFrame::Format_IMC4: case FORMAT(YV12, YV12): fmt = ImageFormat::Lum; break;
case QVideoFrame::Format_YV12: fmt = ImageFormat::Lum; break; case FORMAT(UYVY, UYVY): fmt = ImageFormat::Lum, pixStride = 2, pixOffset = 1; break;
case QVideoFrame::Format_UYVY: fmt = ImageFormat::Lum, pixStride = 2, pixOffset = 1; break; case FORMAT(YUYV, YUYV): fmt = ImageFormat::Lum, pixStride = 2; break;
case QVideoFrame::Format_YUYV: fmt = ImageFormat::Lum, pixStride = 2; break;
case QVideoFrame::Format_Y8: fmt = ImageFormat::Lum; break; case FORMAT(Y8, Y8): fmt = ImageFormat::Lum; break;
case QVideoFrame::Format_Y16: fmt = ImageFormat::Lum, pixStride = 2, pixOffset = 1; break; case FORMAT(Y16, Y16): fmt = ImageFormat::Lum, pixStride = 2, pixOffset = 1; break;
#if (QT_VERSION >= QT_VERSION_CHECK(5, 13, 0)) #if (QT_VERSION >= QT_VERSION_CHECK(5, 13, 0))
case QVideoFrame::Format_ABGR32: case FORMAT(ABGR32, ABGR8888):
#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN #if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
fmt = ImageFormat::RGBX; fmt = ImageFormat::RGBX;
#else #else
@ -246,24 +255,47 @@ enum class DecodeStatus
break; break;
#endif #endif
#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)) #if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
case QVideoFrame::Format_YUV422P: fmt = ImageFormat::Lum; break; case FORMAT(YUV422P, YUV422P): fmt = ImageFormat::Lum; break;
#endif #endif
default: break; default: break;
} }
Result res;
if (fmt != ImageFormat::None) { if (fmt != ImageFormat::None) {
res = Result( auto img = frame; // shallow copy just get access to non-const map() function
ZXing::ReadBarcode({img.bits() + pixOffset, img.width(), img.height(), fmt, img.bytesPerLine(), pixStride}, #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
hints)); if (!img.isValid() || !img.map(QAbstractVideoBuffer::ReadOnly)){
} else { #else
if (QVideoFrame::imageFormatFromPixelFormat(img.pixelFormat()) != QImage::Format_Invalid) if (!img.isValid() || !img.map(QVideoFrame::ReadOnly)){
res = ReadBarcode(img.image(), hints); #endif
qWarning() << "invalid QVideoFrame: could not map memory";
return {};
}
QScopeGuard unmap([&] { img.unmap(); });
return QListResults(ZXing::ReadBarcodes(
{img.bits(FIRST_PLANE) + pixOffset, img.width(), img.height(), fmt, img.bytesPerLine(FIRST_PLANE), pixStride}, hints));
} }
else {
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
if (QVideoFrame::imageFormatFromPixelFormat(frame.pixelFormat()) != QImage::Format_Invalid) {
qWarning() << "unsupported QVideoFrame::pixelFormat";
return {};
}
auto qimg = frame.image();
#else
auto qimg = frame.toImage();
#endif
if (qimg.format() != QImage::Format_Invalid)
return ReadBarcodes(qimg, hints);
qWarning() << "failed to convert QVideoFrame to QImage";
return {};
}
}
img.unmap(); inline Result ReadBarcode(const QVideoFrame& frame, const DecodeHints& hints = {})
{
return res; auto res = ReadBarcodes(frame, DecodeHints(hints).setMaxNumberOfSymbols(1));
return !res.isEmpty() ? res.takeFirst() : Result();
} }
#define ZQ_PROPERTY(Type, name, setter) \ #define ZQ_PROPERTY(Type, name, setter) \
@ -279,14 +311,21 @@ public: \
} \ } \
Q_SIGNAL void name##Changed(); Q_SIGNAL void name##Changed();
class VideoFilter : public QAbstractVideoFilter, private DecodeHints
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
class BarcodeReader : public QAbstractVideoFilter, private DecodeHints
#else
class BarcodeReader : public QObject, private DecodeHints
#endif
{ {
Q_OBJECT Q_OBJECT
public: public:
VideoFilter(QObject* parent = nullptr) : QAbstractVideoFilter(parent) {} #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
BarcodeReader(QObject* parent = nullptr) : QAbstractVideoFilter(parent) {}
QVideoFilterRunnable* createFilterRunnable() override; #else
BarcodeReader(QObject* parent = nullptr) : QObject(parent) {}
#endif
// TODO: find out how to properly expose QFlags to QML // TODO: find out how to properly expose QFlags to QML
// simply using ZQ_PROPERTY(BarcodeFormats, formats, setFormats) // simply using ZQ_PROPERTY(BarcodeFormats, formats, setFormats)
@ -309,9 +348,10 @@ public:
ZQ_PROPERTY(bool, tryRotate, setTryRotate) ZQ_PROPERTY(bool, tryRotate, setTryRotate)
ZQ_PROPERTY(bool, tryHarder, setTryHarder) ZQ_PROPERTY(bool, tryHarder, setTryHarder)
ZQ_PROPERTY(bool, tryDownscale, setTryDownscale)
public slots: public slots:
Result process(const QVideoFrame& image) ZXingQt::Result process(const QVideoFrame& image)
{ {
QElapsedTimer t; QElapsedTimer t;
t.start(); t.start();
@ -327,18 +367,41 @@ public slots:
} }
signals: signals:
void newResult(Result result); void newResult(ZXingQt::Result result);
void foundBarcode(Result result); void foundBarcode(ZXingQt::Result result);
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
public:
QVideoFilterRunnable *createFilterRunnable() override;
#else
private:
QVideoSink *_sink = nullptr;
public:
void setVideoSink(QVideoSink* sink) {
if (_sink == sink)
return;
if (_sink)
disconnect(_sink, nullptr, this, nullptr);
_sink = sink;
connect(_sink, &QVideoSink::videoFrameChanged, this, &BarcodeReader::process);
}
Q_PROPERTY(QVideoSink* videoSink WRITE setVideoSink)
#endif
}; };
#undef ZX_PROPERTY #undef ZX_PROPERTY
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
class VideoFilterRunnable : public QVideoFilterRunnable class VideoFilterRunnable : public QVideoFilterRunnable
{ {
VideoFilter* _filter = nullptr; BarcodeReader* _filter = nullptr;
public: public:
explicit VideoFilterRunnable(VideoFilter* filter) : _filter(filter) {} explicit VideoFilterRunnable(BarcodeReader* filter) : _filter(filter) {}
QVideoFrame run(QVideoFrame* input, const QVideoSurfaceFormat& /*surfaceFormat*/, RunFlags /*flags*/) override QVideoFrame run(QVideoFrame* input, const QVideoSurfaceFormat& /*surfaceFormat*/, RunFlags /*flags*/) override
{ {
@ -347,10 +410,11 @@ public:
} }
}; };
inline QVideoFilterRunnable* VideoFilter::createFilterRunnable() inline QVideoFilterRunnable* BarcodeReader::createFilterRunnable()
{ {
return new VideoFilterRunnable(this); return new VideoFilterRunnable(this);
} }
#endif
#endif // QT_MULTIMEDIA_LIB #endif // QT_MULTIMEDIA_LIB
@ -369,7 +433,7 @@ namespace ZXingQt {
inline void registerQmlAndMetaTypes() inline void registerQmlAndMetaTypes()
{ {
qRegisterMetaType<ZXingQt::BarcodeFormat>("BarcodeFormat"); qRegisterMetaType<ZXingQt::BarcodeFormat>("BarcodeFormat");
qRegisterMetaType<ZXingQt::DecodeStatus>("DecodeStatus"); qRegisterMetaType<ZXingQt::ContentType>("ContentType");
// supposedly the Q_DECLARE_METATYPE should be used with the overload without a custom name // supposedly the Q_DECLARE_METATYPE should be used with the overload without a custom name
// but then the qml side complains about "unregistered type" // but then the qml side complains about "unregistered type"
@ -378,7 +442,7 @@ inline void registerQmlAndMetaTypes()
qmlRegisterUncreatableMetaObject( qmlRegisterUncreatableMetaObject(
ZXingQt::staticMetaObject, "ZXing", 1, 0, "ZXing", "Access to enums & flags only"); ZXingQt::staticMetaObject, "ZXing", 1, 0, "ZXing", "Access to enums & flags only");
qmlRegisterType<ZXingQt::VideoFilter>("ZXing", 1, 0, "VideoFilter"); qmlRegisterType<ZXingQt::BarcodeReader>("ZXing", 1, 0, "BarcodeReader");
} }
} // namespace ZXingQt } // namespace ZXingQt

View File

@ -27,8 +27,8 @@ clean() {
rm -rf dl.zip yaml-* zxing-* protobuf rm -rf dl.zip yaml-* zxing-* protobuf
} }
#### ZXing 1.3.0 #### #### ZXing v2.0.0 ####
curl -L -o dl.zip https://github.com/nu-book/zxing-cpp/archive/refs/tags/v1.3.0.zip curl -L -o dl.zip https://github.com/nu-book/zxing-cpp/archive/refs/tags/v2.0.0.zip
unzip dl.zip unzip dl.zip
cd zxing-* cd zxing-*
@ -40,12 +40,6 @@ ninja && ninja install
cd ../.. cd ../..
#### exit if NKR_PACKAGE ####
if [ ! -z $NKR_PACKAGE ]; then
clean
exit
fi
#### yaml-cpp #### #### yaml-cpp ####
curl -L -o dl.zip https://github.com/jbeder/yaml-cpp/archive/refs/tags/yaml-cpp-0.7.0.zip curl -L -o dl.zip https://github.com/jbeder/yaml-cpp/archive/refs/tags/yaml-cpp-0.7.0.zip
unzip dl.zip unzip dl.zip