Merge pull request #18 from nickdiego/upstream-fixes

Fix some critical bugs in QZXingFilter
This commit is contained in:
Nikolaos Ftylitakis 2017-01-22 17:58:23 +02:00 committed by GitHub
commit 154451e968
2 changed files with 31 additions and 8 deletions

View File

@ -39,6 +39,10 @@ QZXingFilter::QZXingFilter(QObject *parent)
QZXingFilter::~QZXingFilter() QZXingFilter::~QZXingFilter()
{ {
if(!processThread.isFinished()) {
processThread.cancel();
processThread.waitForFinished();
}
if(decoder_p) if(decoder_p)
delete decoder_p; delete decoder_p;
} }
@ -82,6 +86,10 @@ QZXingFilterRunnable::QZXingFilterRunnable(QZXingFilter * filter)
{ {
} }
QZXingFilterRunnable::~QZXingFilterRunnable()
{
filter = nullptr;
}
QVideoFrame QZXingFilterRunnable::run(QVideoFrame * input, const QVideoSurfaceFormat &surfaceFormat, RunFlags flags) QVideoFrame QZXingFilterRunnable::run(QVideoFrame * input, const QVideoSurfaceFormat &surfaceFormat, RunFlags flags)
{ {
@ -118,6 +126,11 @@ QVideoFrame QZXingFilterRunnable::run(QVideoFrame * input, const QVideoSurfaceFo
return * input; return * input;
} }
static bool isRectValid(const QRect& rect)
{
return rect.x() > 0 && rect.y() > 0 && rect.isValid();
}
static QImage rgbDataToGrayscale(const uchar* data, const int width, const int height, static QImage rgbDataToGrayscale(const uchar* data, const int width, const int height,
const int alpha, const int red, const int alpha, const int red,
const int green, const int blue, const int green, const int blue,
@ -126,10 +139,10 @@ static QImage rgbDataToGrayscale(const uchar* data, const int width, const int h
{ {
const int stride = (alpha < 0) ? 3 : 4; const int stride = (alpha < 0) ? 3 : 4;
const int startX = captureRect.x(); const int startX = isRectValid(captureRect) ? captureRect.x() : 0;
const int startY = captureRect.y(); const int startY = isRectValid(captureRect) ? captureRect.y() : 0;
const int targetWidth = captureRect.isNull() ? width : captureRect.width(); const int targetWidth = isRectValid(captureRect) ? captureRect.width() : width;
const int targetHeight = captureRect.isNull() ? height : captureRect.height(); const int targetHeight = isRectValid(captureRect) ? captureRect.height() : height;
const int endX = width - startX - targetWidth; const int endX = width - startX - targetWidth;
const int skipX = (endX + startX) * stride; const int skipX = (endX + startX) * stride;
@ -261,7 +274,7 @@ void QZXingFilterRunnable::processVideoFrameProbed(SimpleVideoFrame & videoFrame
// const QString path = QStandardPaths::writableLocation(QStandardPaths::PicturesLocation) + "/qrtest/test_" + QString::number(i % 100) + ".png"; // const QString path = QStandardPaths::writableLocation(QStandardPaths::PicturesLocation) + "/qrtest/test_" + QString::number(i % 100) + ".png";
// qDebug() << "saving image" << i << "at:" << path << image.save(path); // qDebug() << "saving image" << i << "at:" << path << image.save(path);
QString tag = filter->decoder_p->decodeImage(image, image.width(), image.height()); QString tag = decode(image);
const bool tryHarder = filter->decoder_p->getTryHarder(); const bool tryHarder = filter->decoder_p->getTryHarder();
/// The frames we get from the camera may be reflected horizontally or vertically /// The frames we get from the camera may be reflected horizontally or vertically
@ -269,14 +282,20 @@ void QZXingFilterRunnable::processVideoFrameProbed(SimpleVideoFrame & videoFrame
/// TODO: Maybe there is a better way to know this orientation beforehand? Or should we try decoding all of them? /// TODO: Maybe there is a better way to know this orientation beforehand? Or should we try decoding all of them?
if (tag.isEmpty() && tryHarder) { if (tag.isEmpty() && tryHarder) {
image = image.mirrored(true, false); image = image.mirrored(true, false);
tag = filter->decoder_p->decodeImage(image, image.width(), image.height()); tag = decode(image);
} }
if (tag.isEmpty() && tryHarder) { if (tag.isEmpty() && tryHarder) {
image = image.mirrored(false, true); image = image.mirrored(false, true);
tag = filter->decoder_p->decodeImage(image, image.width(), image.height()); tag = decode(image);
} }
if (tag.isEmpty() && tryHarder) { if (tag.isEmpty() && tryHarder) {
image = image.mirrored(true, true); image = image.mirrored(true, true);
tag = filter->decoder_p->decodeImage(image, image.width(), image.height()); tag = decode(image);
} }
} }
QString QZXingFilterRunnable::decode(const QImage &image)
{
return (filter != nullptr) ?
filter->decoder_p->decodeImage(image, image.width(), image.height()) : QString();
}

View File

@ -103,10 +103,14 @@ class QZXingFilterRunnable : public QObject, public QVideoFilterRunnable
public: public:
explicit QZXingFilterRunnable(QZXingFilter * filter); explicit QZXingFilterRunnable(QZXingFilter * filter);
virtual ~QZXingFilterRunnable();
/// This method is called whenever we get a new frame. It runs in the UI thread. /// This method is called whenever we get a new frame. It runs in the UI thread.
QVideoFrame run(QVideoFrame * input, const QVideoSurfaceFormat &surfaceFormat, RunFlags flags); QVideoFrame run(QVideoFrame * input, const QVideoSurfaceFormat &surfaceFormat, RunFlags flags);
void processVideoFrameProbed(SimpleVideoFrame & videoFrame, const QRect& captureRect); void processVideoFrameProbed(SimpleVideoFrame & videoFrame, const QRect& captureRect);
private:
QString decode(const QImage &image);
private: private:
QZXingFilter * filter; QZXingFilter * filter;
}; };