From 8d4cda030e445d2b64cc327af125b538e014ecb0 Mon Sep 17 00:00:00 2001 From: xiphon Date: Mon, 21 Dec 2020 19:58:27 +0000 Subject: QR-Code-scanner: integrate QUIRC library, implement QrDecoder, drop ZBar --- src/QR-Code-scanner/Decoder.cpp | 71 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 src/QR-Code-scanner/Decoder.cpp (limited to 'src/QR-Code-scanner/Decoder.cpp') 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 + +#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 QrDecoder::decode(const QImage &image) +{ + if (image.format() == QImage::Format_Grayscale8) + { + return decodeGrayscale8(image); + } + return decodeGrayscale8(image.convertToFormat(QImage::Format_Grayscale8)); +} + +std::vector 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 result; + result.reserve(static_cast(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; +} -- cgit v1.2.3