qt5/src/poppler-page.cc       |    8 ++++----
 qt5/tests/CMakeLists.txt      |    1 +
 qt5/tests/check_overprint.cpp |   41 +++++++++++++++++++++++++++++++++++++++++
 qt6/src/poppler-page.cc       |    8 ++++----
 qt6/tests/CMakeLists.txt      |    1 +
 qt6/tests/check_overprint.cpp |   38 ++++++++++++++++++++++++++++++++++++++
 6 files changed, 89 insertions(+), 8 deletions(-)

New commits:
commit 6ebe45e8dceae11d02c74df47c34f4490a45a15e
Author: Kevin Ottens <kevin.ott...@enioka.com>
Date:   Wed Jun 21 15:10:48 2023 +0200

    Don't crash when overprint preview is enabled with the Qt bindings
    
    When overprint preview is enabled, the image data row size changes
    during conversion to XBGR. The Qt bindings were assuming this row
    size was constant which led to badly broken QImages at conversion
    time (generating garbage if displayed or even crashing).
    
    This commit simply add regression tests for the case and gets the
    row size after bitmap conversion.

diff --git a/qt5/src/poppler-page.cc b/qt5/src/poppler-page.cc
index b2cea93b..43c7d9fd 100644
--- a/qt5/src/poppler-page.cc
+++ b/qt5/src/poppler-page.cc
@@ -129,10 +129,6 @@ public:
     {
         SplashBitmap *b = getBitmap();
 
-        const int bw = b->getWidth();
-        const int bh = b->getHeight();
-        const int brs = b->getRowSize();
-
         // If we use DeviceN8, convert to XBGR8.
         // If requested, also transfer Splash's internal alpha channel.
         const SplashBitmap::ConversionMode mode = ignorePaperColor ? 
SplashBitmap::conversionAlphaPremultiplied : SplashBitmap::conversionOpaque;
@@ -140,6 +136,10 @@ public:
         const QImage::Format format = ignorePaperColor ? 
QImage::Format_ARGB32_Premultiplied : QImage::Format_RGB32;
 
         if (b->convertToXBGR(mode)) {
+            const int bw = b->getWidth();
+            const int bh = b->getHeight();
+            const int brs = b->getRowSize();
+
             SplashColorPtr data = takeImageData ? b->takeData() : 
b->getDataPtr();
 
             if (QSysInfo::ByteOrder == QSysInfo::BigEndian) {
diff --git a/qt5/tests/CMakeLists.txt b/qt5/tests/CMakeLists.txt
index 9de870ee..e610413a 100644
--- a/qt5/tests/CMakeLists.txt
+++ b/qt5/tests/CMakeLists.txt
@@ -74,6 +74,7 @@ qt5_add_qtest(check_qt5_signature_basics 
check_signature_basics.cpp)
 qt5_add_qtest(check_qt5_utf8document check_utf8document.cpp)
 qt5_add_qtest(check_qt5_distinguished_name_parser 
check_distinguished_name_parser.cpp)
 qt5_add_qtest(check_qt5_cidfontswidthsbuilder check_cidfontswidthsbuilder.cpp)
+qt5_add_qtest(check_qt5_overprint check_overprint.cpp)
 if (NOT WIN32)
   qt5_add_qtest(check_qt5_pagelabelinfo check_pagelabelinfo.cpp)
   qt5_add_qtest(check_qt5_strings check_strings.cpp)
diff --git a/qt5/tests/check_overprint.cpp b/qt5/tests/check_overprint.cpp
new file mode 100644
index 00000000..3035c652
--- /dev/null
+++ b/qt5/tests/check_overprint.cpp
@@ -0,0 +1,41 @@
+#include <QtTest/QtTest>
+
+#include <poppler-qt5.h>
+
+#include <memory>
+
+class TestOverprint : public QObject
+{
+    Q_OBJECT
+public:
+    explicit TestOverprint(QObject *parent = nullptr) : QObject(parent) { }
+private slots:
+    void checkOverprintImageRendering();
+};
+
+void TestOverprint::checkOverprintImageRendering()
+{
+    Poppler::Document *doc = Poppler::Document::load(TESTDATADIR 
"/tests/mask-seams.pdf");
+    QVERIFY(doc);
+
+    doc->setRenderHint(Poppler::Document::OverprintPreview, true);
+
+    Poppler::Page *page = doc->page(0);
+    QVERIFY(page);
+
+    constexpr int width = 600;
+    constexpr int height = 400;
+
+    QImage img = page->renderToImage(300.0, 300.0, 0, 0, width, height);
+    QCOMPARE(img.format(), QImage::Format_RGB32);
+    QCOMPARE(img.width(), width);
+    QCOMPARE(img.height(), height);
+    QCOMPARE(img.bytesPerLine(), width * 4);
+    QCOMPARE(img.sizeInBytes(), width * height * 4);
+
+    delete page;
+    delete doc;
+}
+
+QTEST_GUILESS_MAIN(TestOverprint)
+#include "check_overprint.moc"
diff --git a/qt6/src/poppler-page.cc b/qt6/src/poppler-page.cc
index dd1cb0e5..40062e81 100644
--- a/qt6/src/poppler-page.cc
+++ b/qt6/src/poppler-page.cc
@@ -128,10 +128,6 @@ public:
     {
         SplashBitmap *b = getBitmap();
 
-        const int bw = b->getWidth();
-        const int bh = b->getHeight();
-        const int brs = b->getRowSize();
-
         // If we use DeviceN8, convert to XBGR8.
         // If requested, also transfer Splash's internal alpha channel.
         const SplashBitmap::ConversionMode mode = ignorePaperColor ? 
SplashBitmap::conversionAlphaPremultiplied : SplashBitmap::conversionOpaque;
@@ -139,6 +135,10 @@ public:
         const QImage::Format format = ignorePaperColor ? 
QImage::Format_ARGB32_Premultiplied : QImage::Format_RGB32;
 
         if (b->convertToXBGR(mode)) {
+            const int bw = b->getWidth();
+            const int bh = b->getHeight();
+            const int brs = b->getRowSize();
+
             SplashColorPtr data = takeImageData ? b->takeData() : 
b->getDataPtr();
 
             if (QSysInfo::ByteOrder == QSysInfo::BigEndian) {
diff --git a/qt6/tests/CMakeLists.txt b/qt6/tests/CMakeLists.txt
index 577aad7f..95fa89dd 100644
--- a/qt6/tests/CMakeLists.txt
+++ b/qt6/tests/CMakeLists.txt
@@ -66,6 +66,7 @@ qt6_add_qtest(check_qt6_signature_basics 
check_signature_basics.cpp)
 qt6_add_qtest(check_qt6_utf8document check_utf8document.cpp)
 qt6_add_qtest(check_qt6_distinguished_name_parser 
check_distinguished_name_parser.cpp)
 qt6_add_qtest(check_qt6_cidfontswidthsbuilder check_cidfontswidthsbuilder.cpp)
+qt6_add_qtest(check_qt6_overprint check_overprint.cpp)
 if (NOT WIN32)
   qt6_add_qtest(check_qt6_pagelabelinfo check_pagelabelinfo.cpp)
   qt6_add_qtest(check_qt6_strings check_strings.cpp)
diff --git a/qt6/tests/check_overprint.cpp b/qt6/tests/check_overprint.cpp
new file mode 100644
index 00000000..1b551567
--- /dev/null
+++ b/qt6/tests/check_overprint.cpp
@@ -0,0 +1,38 @@
+#include <QtTest/QtTest>
+
+#include <poppler-qt6.h>
+
+#include <memory>
+
+class TestOverprint : public QObject
+{
+    Q_OBJECT
+public:
+    explicit TestOverprint(QObject *parent = nullptr) : QObject(parent) { }
+private slots:
+    void checkOverprintImageRendering();
+};
+
+void TestOverprint::checkOverprintImageRendering()
+{
+    std::unique_ptr<Poppler::Document> doc = 
Poppler::Document::load(TESTDATADIR "/tests/mask-seams.pdf");
+    QVERIFY(doc);
+
+    doc->setRenderHint(Poppler::Document::OverprintPreview, true);
+
+    std::unique_ptr<Poppler::Page> page = doc->page(0);
+    QVERIFY(page);
+
+    constexpr int width = 600;
+    constexpr int height = 400;
+
+    QImage img = page->renderToImage(300.0, 300.0, 0, 0, width, height);
+    QCOMPARE(img.format(), QImage::Format_RGB32);
+    QCOMPARE(img.width(), width);
+    QCOMPARE(img.height(), height);
+    QCOMPARE(img.bytesPerLine(), width * 4);
+    QCOMPARE(img.sizeInBytes(), width * height * 4);
+}
+
+QTEST_GUILESS_MAIN(TestOverprint)
+#include "check_overprint.moc"

Reply via email to