diff options
| author | Alexander Blair <snipa@jagtech.io> | 2021-01-03 18:45:13 -0800 |
|---|---|---|
| committer | Alexander Blair <snipa@jagtech.io> | 2021-01-03 18:45:26 -0800 |
| commit | bbe371654258c25d034c07783e5ae776c2f60d90 (patch) | |
| tree | 51e2161b29317061a4ae2f02cee4d70c9071a81c /src/QR-Code-scanner | |
| parent | 8e6a2cde0fd0e8c2a71456ea8bb36db49116d705 (diff) | |
| parent | 8d4cda030e445d2b64cc327af125b538e014ecb0 (diff) | |
| download | monzero-gui-bbe371654258c25d034c07783e5ae776c2f60d90.tar.gz monzero-gui-bbe371654258c25d034c07783e5ae776c2f60d90.tar.xz monzero-gui-bbe371654258c25d034c07783e5ae776c2f60d90.zip | |
Merge pull request #3277
8d4cda03 QR-Code-scanner: integrate QUIRC library, implement QrDecoder, drop ZBar (xiphon)
Diffstat (limited to 'src/QR-Code-scanner')
| -rw-r--r-- | src/QR-Code-scanner/CMakeLists.txt | 23 | ||||
| -rw-r--r-- | src/QR-Code-scanner/Decoder.cpp | 71 | ||||
| -rw-r--r-- | src/QR-Code-scanner/Decoder.h | 21 | ||||
| -rw-r--r-- | src/QR-Code-scanner/QrCodeScanner.cpp | 3 | ||||
| -rw-r--r-- | src/QR-Code-scanner/QrCodeScanner.h | 3 | ||||
| -rw-r--r-- | src/QR-Code-scanner/QrScanThread.cpp | 55 | ||||
| -rw-r--r-- | src/QR-Code-scanner/QrScanThread.h | 13 |
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; |
