aboutsummaryrefslogtreecommitdiff
path: root/src/QR-Code-scanner
diff options
context:
space:
mode:
authorxiphon <xiphon@protonmail.com>2020-12-21 19:58:27 +0000
committerxiphon <xiphon@protonmail.com>2020-12-23 15:08:42 +0000
commit8d4cda030e445d2b64cc327af125b538e014ecb0 (patch)
tree846a62bdd48dde1e5eb636b7e127ab1bfe3153ef /src/QR-Code-scanner
parentdf771470c28c1efbb5402a755da0ab0dffaecd5f (diff)
downloadmonzero-gui-8d4cda030e445d2b64cc327af125b538e014ecb0.tar.gz
monzero-gui-8d4cda030e445d2b64cc327af125b538e014ecb0.tar.xz
monzero-gui-8d4cda030e445d2b64cc327af125b538e014ecb0.zip
QR-Code-scanner: integrate QUIRC library, implement QrDecoder, drop ZBar
Diffstat (limited to 'src/QR-Code-scanner')
-rw-r--r--src/QR-Code-scanner/CMakeLists.txt23
-rw-r--r--src/QR-Code-scanner/Decoder.cpp71
-rw-r--r--src/QR-Code-scanner/Decoder.h21
-rw-r--r--src/QR-Code-scanner/QrCodeScanner.cpp3
-rw-r--r--src/QR-Code-scanner/QrCodeScanner.h3
-rw-r--r--src/QR-Code-scanner/QrScanThread.cpp55
-rw-r--r--src/QR-Code-scanner/QrScanThread.h13
7 files changed, 123 insertions, 66 deletions
diff --git a/src/QR-Code-scanner/CMakeLists.txt b/src/QR-Code-scanner/CMakeLists.txt
index 9ca31c61..15e288df 100644
--- a/src/QR-Code-scanner/CMakeLists.txt
+++ b/src/QR-Code-scanner/CMakeLists.txt
@@ -1,4 +1,21 @@
-file(GLOB_RECURSE SRC_SOURCES *.cpp)
-file(GLOB_RECURSE SRC_HEADERS *.h)
-
+add_library(qrdecoder STATIC
+ Decoder.cpp
+)
+target_link_libraries(qrdecoder
+ PUBLIC
+ Qt5::Gui
+ PRIVATE
+ quirc
+)
+if(WITH_SCANNER)
+ add_library(qrscanner
+ QrCodeScanner.cpp
+ QrScanThread.cpp
+ )
+ target_link_libraries(qrscanner
+ PUBLIC
+ Qt5::Multimedia
+ qrdecoder
+ )
+endif()
diff --git a/src/QR-Code-scanner/Decoder.cpp b/src/QR-Code-scanner/Decoder.cpp
new file mode 100644
index 00000000..a814969b
--- /dev/null
+++ b/src/QR-Code-scanner/Decoder.cpp
@@ -0,0 +1,71 @@
+#include "Decoder.h"
+
+#include <limits>
+
+#include "quirc.h"
+
+QrDecoder::QrDecoder()
+ : m_qr(quirc_new())
+{
+ if (m_qr == nullptr)
+ {
+ throw std::runtime_error("QUIRC: failed to allocate memory");
+ }
+}
+
+QrDecoder::~QrDecoder()
+{
+ quirc_destroy(m_qr);
+}
+
+std::vector<std::string> QrDecoder::decode(const QImage &image)
+{
+ if (image.format() == QImage::Format_Grayscale8)
+ {
+ return decodeGrayscale8(image);
+ }
+ return decodeGrayscale8(image.convertToFormat(QImage::Format_Grayscale8));
+}
+
+std::vector<std::string> QrDecoder::decodeGrayscale8(const QImage &image)
+{
+ if (quirc_resize(m_qr, image.width(), image.height()) < 0)
+ {
+ throw std::runtime_error("QUIRC: failed to allocate video memory");
+ }
+
+ uint8_t *rawImage = quirc_begin(m_qr, nullptr, nullptr);
+ if (rawImage == nullptr)
+ {
+ throw std::runtime_error("QUIRC: failed to get image buffer");
+ }
+#if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)
+ std::copy(image.constBits(), image.constBits() + image.sizeInBytes(), rawImage);
+#else
+ std::copy(image.constBits(), image.constBits() + image.byteCount(), rawImage);
+#endif
+ quirc_end(m_qr);
+
+ const int count = quirc_count(m_qr);
+ if (count < 0)
+ {
+ throw std::runtime_error("QUIRC: failed to get the number of recognized QR-codes");
+ }
+
+ std::vector<std::string> result;
+ result.reserve(static_cast<size_t>(count));
+ for (int index = 0; index < count; ++index)
+ {
+ quirc_code code;
+ quirc_extract(m_qr, index, &code);
+
+ quirc_data data;
+ const quirc_decode_error_t err = quirc_decode(&code, &data);
+ if (err == QUIRC_SUCCESS)
+ {
+ result.emplace_back(&data.payload[0], &data.payload[data.payload_len]);
+ }
+ }
+
+ return result;
+}
diff --git a/src/QR-Code-scanner/Decoder.h b/src/QR-Code-scanner/Decoder.h
new file mode 100644
index 00000000..e25c3936
--- /dev/null
+++ b/src/QR-Code-scanner/Decoder.h
@@ -0,0 +1,21 @@
+#include <QImage>
+
+struct quirc;
+
+class QrDecoder
+{
+public:
+ QrDecoder(const QrDecoder &) = delete;
+ QrDecoder &operator=(const QrDecoder &) = delete;
+
+ QrDecoder();
+ ~QrDecoder();
+
+ std::vector<std::string> decode(const QImage &image);
+
+private:
+ std::vector<std::string> decodeGrayscale8(const QImage &image);
+
+private:
+ quirc *m_qr;
+};
diff --git a/src/QR-Code-scanner/QrCodeScanner.cpp b/src/QR-Code-scanner/QrCodeScanner.cpp
index 55e396fe..2e8bde9f 100644
--- a/src/QR-Code-scanner/QrCodeScanner.cpp
+++ b/src/QR-Code-scanner/QrCodeScanner.cpp
@@ -27,7 +27,6 @@
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "QrCodeScanner.h"
-#include <WalletManager.h>
#include <QVideoProbe>
#include <QCamera>
@@ -40,7 +39,7 @@ QrCodeScanner::QrCodeScanner(QObject *parent)
m_probe = new QVideoProbe(this);
m_thread = new QrScanThread(this);
m_thread->start();
- QObject::connect(m_thread, SIGNAL(decoded(int, QString)), this, SIGNAL(decoded(int, QString)));
+ QObject::connect(m_thread, SIGNAL(decoded(QString)), this, SIGNAL(decoded(QString)));
QObject::connect(m_thread, SIGNAL(notifyError(const QString &, bool)), this, SIGNAL(notifyError(const QString &, bool)));
connect(m_probe, SIGNAL(videoFrameProbed(QVideoFrame)), this, SLOT(processFrame(QVideoFrame)));
}
diff --git a/src/QR-Code-scanner/QrCodeScanner.h b/src/QR-Code-scanner/QrCodeScanner.h
index 9420693d..10cf7766 100644
--- a/src/QR-Code-scanner/QrCodeScanner.h
+++ b/src/QR-Code-scanner/QrCodeScanner.h
@@ -56,8 +56,7 @@ public Q_SLOTS:
Q_SIGNALS:
void enabledChanged();
- void decoded(int type, const QString &data);
- void decode(int type, const QString &data);
+ void decoded(const QString &data);
void notifyError(const QString &error, bool warning = false);
protected:
diff --git a/src/QR-Code-scanner/QrScanThread.cpp b/src/QR-Code-scanner/QrScanThread.cpp
index 15f4c030..6421321e 100644
--- a/src/QR-Code-scanner/QrScanThread.cpp
+++ b/src/QR-Code-scanner/QrScanThread.cpp
@@ -38,62 +38,15 @@ QrScanThread::QrScanThread(QObject *parent)
: QThread(parent)
,m_running(true)
{
- m_scanner.set_handler(*this);
}
-void QrScanThread::image_callback(zbar::Image &image)
-{
- qDebug() << "image_callback : Found Code ! " ;
- for(zbar::Image::SymbolIterator sym = image.symbol_begin();
- sym != image.symbol_end();
- ++sym)
- if(!sym->get_count()) {
- QString data = QString::fromStdString(sym->get_data());
- emit decoded(sym->get_type(), data);
- }
-}
-
-void QrScanThread::processZImage(zbar::Image &image)
-{
- m_scanner.recycle_image(image);
- zbar::Image tmp = image.convert(*(long*)"Y800");
- m_scanner.scan(tmp);
- image.set_symbols(tmp.get_symbols());
-}
-
-bool QrScanThread::zimageFromQImage(const QImage &qimg, zbar::Image &dst)
-{
- switch( qimg.format() ){
- case QImage::Format_RGB32 :
- case QImage::Format_ARGB32 :
- case QImage::Format_ARGB32_Premultiplied :
- break;
- default :
- emit notifyError(QString("Invalid QImage Format !"));
- return false;
- }
- unsigned int bpl( qimg.bytesPerLine() ), width( bpl / 4), height( qimg.height());
- dst.set_size(width, height);
- dst.set_format("BGR4");
-#if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)
- unsigned long datalen = qimg.sizeInBytes();
-#else
- unsigned long datalen = qimg.byteCount();
-#endif
- dst.set_data(qimg.bits(), datalen);
- if((width * 4 != bpl) || (width * height * 4 > datalen)){
- emit notifyError(QString("QImage to Zbar::Image failed !"));
- return false;
- }
- return true;
-}
void QrScanThread::processQImage(const QImage &qimg)
{
try {
- m_image = QSharedPointer<zbar::Image>(new zbar::Image());
- if( ! zimageFromQImage(qimg, *m_image) )
- return;
- processZImage(*m_image);
+ for (const std::string &code : m_decoder.decode(qimg))
+ {
+ emit decoded(QString::fromStdString(code));
+ }
}
catch(std::exception &e) {
qDebug() << "ERROR: " << e.what();
diff --git a/src/QR-Code-scanner/QrScanThread.h b/src/QR-Code-scanner/QrScanThread.h
index b6daa29f..7dfffc55 100644
--- a/src/QR-Code-scanner/QrScanThread.h
+++ b/src/QR-Code-scanner/QrScanThread.h
@@ -35,9 +35,10 @@
#include <QEvent>
#include <QVideoFrame>
#include <QCamera>
-#include <zbar.h>
-class QrScanThread : public QThread, public zbar::Image::Handler
+#include "Decoder.h"
+
+class QrScanThread : public QThread
{
Q_OBJECT
@@ -47,20 +48,16 @@ public:
virtual void stop();
Q_SIGNALS:
- void decoded(int type, const QString &data);
+ void decoded(const QString &data);
void notifyError(const QString &error, bool warning = false);
protected:
virtual void run();
void processVideoFrame(const QVideoFrame &);
void processQImage(const QImage &);
- void processZImage(zbar::Image &image);
- virtual void image_callback(zbar::Image &image);
- bool zimageFromQImage(const QImage&, zbar::Image &);
private:
- zbar::ImageScanner m_scanner;
- QSharedPointer<zbar::Image> m_image;
+ QrDecoder m_decoder;
bool m_running;
QMutex m_mutex;
QWaitCondition m_waitCondition;