Commit 4f77b020 authored by Volker Krause's avatar Volker Krause
Browse files

Consider vector path complexity for determining plausible barcode formats

So far we only used a simple lower bound, which is too restrictive for
e.g. 1D codes. Instead, use the complexity in the same way as we use
size and aspect ratio to determine possible code formats.
parent adcef3cc
......@@ -15,6 +15,9 @@ enum {
MinTargetImageWidth = 36,
MaxTargetImageHeight = 252,
MaxTargetImageWidth2D = 252,
// vector path complexity limits
MinPathElementCount2D = 400,
MaxPathElementCount2D = 4000,
};
BarcodeDecoder::BarcodeTypes PdfBarcodeUtil::maybeBarcode(const PdfImage &img, BarcodeDecoder::BarcodeTypes hint)
......@@ -33,5 +36,18 @@ BarcodeDecoder::BarcodeTypes PdfBarcodeUtil::maybeBarcode(const PdfImage &img, B
hint = BarcodeDecoder::isPlausibleSize(img.sourceWidth(), img.sourceHeight(), hint);
hint = BarcodeDecoder::isPlausibleAspectRatio(w, h, hint);
if (img.isVectorImage()) {
hint = isPlausiblePath(img.pathElementsCount(), hint);
}
return hint;
}
BarcodeDecoder::BarcodeTypes PdfBarcodeUtil::isPlausiblePath(int elementCount, BarcodeDecoder::BarcodeTypes hint)
{
if (elementCount < MinPathElementCount2D || elementCount > MaxPathElementCount2D) {
hint &= ~BarcodeDecoder::Any2D;
}
return hint;
}
......@@ -16,7 +16,10 @@ class PdfImage;
namespace PdfBarcodeUtil
{
/** Quick pre-check without image decoding if @p img might be a barcode. */
BarcodeDecoder::BarcodeTypes maybeBarcode(const PdfImage &img, BarcodeDecoder::BarcodeTypes hint = BarcodeDecoder::Any2D);
BarcodeDecoder::BarcodeTypes maybeBarcode(const PdfImage &img, BarcodeDecoder::BarcodeTypes hint);
/** Check whether a vector path with @p elementCount could be a barcode. */
BarcodeDecoder::BarcodeTypes isPlausiblePath(int elementCount, BarcodeDecoder::BarcodeTypes hint);
}
}
......
......@@ -5,6 +5,7 @@
*/
#include "pdfextractoroutputdevice_p.h"
#include "pdfbarcodeutil_p.h"
#include "pdfimage.h"
#include "pdfimage_p.h"
#include "popplerutils_p.h"
......@@ -219,7 +220,7 @@ void PdfExtractorOutputDevice::finalize()
void PdfExtractorOutputDevice::addVectorImage(const PdfVectorPicture &pic)
{
if (pic.pathElementsCount() < 400) { // not complex enough for a barcode
if (PdfBarcodeUtil::isPlausiblePath(pic.pathElementsCount(), BarcodeDecoder::Any) == BarcodeDecoder::None) {
return;
}
......
......@@ -214,3 +214,13 @@ int PdfImage::objectId() const
{
return d->m_refNum;
}
bool PdfImage::isVectorImage() const
{
return !d->m_vectorPicture.isNull();
}
int PdfImage::pathElementsCount() const
{
return d->m_vectorPicture.pathElementsCount();
}
......@@ -71,6 +71,14 @@ public:
*/
int objectId() const;
/** Returns whether this is a raster or vector image. */
bool isVectorImage() const;
/** If this is a vector image, this returns the number
* of vector path elemets.
*/
int pathElementsCount() const;
private:
friend class PdfExtractorOutputDevice;
friend class PdfPagePrivate;
......
......@@ -35,6 +35,11 @@ PdfVectorPicture::PdfVectorPicture(const PdfVectorPicture&) = default;
PdfVectorPicture::~PdfVectorPicture() = default;
PdfVectorPicture& PdfVectorPicture::operator=(const PdfVectorPicture&) = default;
bool PdfVectorPicture::isNull() const
{
return d->strokes.empty();
}
void PdfVectorPicture::setStrokes(std::vector<PdfVectorPicture::PathStroke> &&strokes)
{
d.detach();
......
......@@ -27,6 +27,8 @@ public:
~PdfVectorPicture();
PdfVectorPicture& operator=(const PdfVectorPicture&);
bool isNull() const;
struct PathStroke {
QPainterPath path;
QPen pen;
......
Supports Markdown
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