Commit b922233f authored by Volker Krause's avatar Volker Krause
Browse files

Barcode decoder implementation using the new ZXing ReadBarcode API

This avoids the need for our own binarizer implementation and thus
potentially an image copy, as ZXing can now consume at least some
image formats directly from the raw QImage data, which means less
code and slightly more performance for us. This however needs latest
ZXing master, so we'll only really benefit from this with ZXing's next
release.
parent 305cc32a
Pipeline #42878 failed with stage
in 3 minutes and 11 seconds
......@@ -18,6 +18,9 @@
#include <ZXing/DecodeHints.h>
#include <ZXing/MultiFormatReader.h>
#include <ZXing/Result.h>
#ifdef ZXING_USE_READBARCODE
#include <ZXing/ReadBarcode.h>
#endif
#endif
using namespace KItinerary;
......@@ -161,17 +164,58 @@ BarcodeDecoder::BarcodeType formatToType(ZXing::BarcodeFormat format)
return BarcodeDecoder::None;
}
#ifdef ZXING_USE_READBARCODE
static ZXing::ImageFormat zxingImageFormat(QImage::Format format)
{
switch (format) {
case QImage::Format_ARGB32:
case QImage::Format_RGB32:
#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
return ZXing::ImageFormat::BGRX;
#else
return ZXing::ImageFormat::XRGB;
#endif
case QImage::Format_RGB888:
return ZXing::ImageFormat::RGB;
case QImage::Format_RGBX8888:
case QImage::Format_RGBA8888:
return ZXing::ImageFormat::RGBX;
case QImage::Format_Grayscale8:
return ZXing::ImageFormat::Lum;
default:
return ZXing::ImageFormat::None;
}
Q_UNREACHABLE();
}
static ZXing::Result zxingReadBarcode(const QImage &img, const ZXing::DecodeHints &hints)
{
return ZXing::ReadBarcode({img.bits(), img.width(), img.height(), zxingImageFormat(img.format()), img.bytesPerLine()}, hints);
}
#endif
void BarcodeDecoder::decodeZxing(const QImage &img, BarcodeDecoder::BarcodeTypes format, BarcodeDecoder::Result &result) const
{
QImagePureBinarizer binarizer(img);
ZXing::DecodeHints hints;
#if ZXING_VERSION >= QT_VERSION_CHECK(1, 1, 0)
hints.setFormats(typeToFormats(format));
#else
hints.setPossibleFormats(typeToFormats(format));
#endif
#ifdef ZXING_USE_READBARCODE
hints.setBinarizer(ZXing::Binarizer::FixedThreshold);
hints.setIsPure(true);
// convert if img is in a format ZXing can't handle directly
const auto res = zxingImageFormat(img.format()) == ZXing::ImageFormat::None ?
zxingReadBarcode(img.convertToFormat(QImage::Format_Grayscale8), hints) : zxingReadBarcode(img, hints);
#else
QImagePureBinarizer binarizer(img);
ZXing::MultiFormatReader reader(hints);
const auto res = reader.read(binarizer);
#endif
if (res.isValid()) {
// detect content type
result.contentType = Result::Any;
......
......@@ -22,6 +22,14 @@
#define ZXING_VERSION_PATCH @ZXing_VERSION_PATCH@
#define ZXING_VERSION ((@ZXing_VERSION_MAJOR@<<16)|(@ZXing_VERSION_MINOR@<<8)|(@ZXing_VERSION_PATCH@))
// QT_VERSION_CHECK isn't available in here for the below check
#define K_VERSION_CHECK(major, minor, patch) ((major<<16)|(minor<<8)|(patch))
// this might compile with older versions too, but it only actually works post 1.1.1
#if ZXING_VERSION > K_VERSION_CHECK(1, 1, 1)
#define ZXING_USE_READBARCODE
#endif
#cmakedefine HAVE_KCAL
#cmakedefine HAVE_LIBXML2
#cmakedefine HAVE_PHONENUMBER
......
......@@ -5,7 +5,7 @@
*/
#include "qimagepurebinarizer.h"
#ifdef HAVE_ZXING
#if defined(HAVE_ZXING) && !defined(ZXING_USE_READBARCODE)
#include <ZXing/BitArray.h>
......
......@@ -8,7 +8,7 @@
#define KITINERARY_QIMAGEPUREBINARIZER_H
#include "config-kitinerary.h"
#ifdef HAVE_ZXING
#if defined(HAVE_ZXING) && !defined(ZXING_USE_READBARCODE)
#include <QImage>
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment