summaryrefslogtreecommitdiffstats
path: root/tests/auto/gui/image/qimagereader/tst_qimagereader.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tests/auto/gui/image/qimagereader/tst_qimagereader.cpp')
-rw-r--r--tests/auto/gui/image/qimagereader/tst_qimagereader.cpp286
1 files changed, 192 insertions, 94 deletions
diff --git a/tests/auto/gui/image/qimagereader/tst_qimagereader.cpp b/tests/auto/gui/image/qimagereader/tst_qimagereader.cpp
index 42a2efe5a8..96af8b4e9b 100644
--- a/tests/auto/gui/image/qimagereader/tst_qimagereader.cpp
+++ b/tests/auto/gui/image/qimagereader/tst_qimagereader.cpp
@@ -1,6 +1,5 @@
// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
-
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QTest>
@@ -11,7 +10,7 @@
#include <QImageReader>
#include <QImageWriter>
#include <QPixmap>
-#include <QSet>
+#include <QScopeGuard>
#include <QTcpSocket>
#include <QTcpServer>
#include <QTimer>
@@ -63,6 +62,9 @@ private slots:
void setScaledSize_data();
void setScaledSize();
+ void setScaledSizeOneDimension_data();
+ void setScaledSizeOneDimension();
+
void setClipRect_data();
void setClipRect();
@@ -301,25 +303,52 @@ void tst_QImageReader::jpegRgbCmyk()
QImage image1(prefix + QLatin1String("YCbCr_cmyk.jpg"));
QImage image2(prefix + QLatin1String("YCbCr_cmyk.png"));
- if (image1 != image2) {
- // first, do some obvious tests
- QCOMPARE(image1.height(), image2.height());
- QCOMPARE(image1.width(), image2.width());
- QCOMPARE(image1.format(), image2.format());
- QCOMPARE(image1.format(), QImage::Format_RGB32);
-
- // compare all the pixels with a slack of 3. This ignores rounding errors
- // in libjpeg/libpng, where some versions sacrifice accuracy for speed.
- for (int h = 0; h < image1.height(); ++h) {
- const uchar *s1 = image1.constScanLine(h);
- const uchar *s2 = image2.constScanLine(h);
- for (int w = 0; w < image1.width() * 4; ++w) {
- if (*s1 != *s2) {
- QVERIFY2(qAbs(*s1 - *s2) <= 3, qPrintable(QString("images differ in line %1, col %2 (image1: %3, image2: %4)").arg(h).arg(w).arg(*s1, 0, 16).arg(*s2, 0, 16)));
- }
- s1++;
- s2++;
- }
+ QVERIFY(!image1.isNull());
+ QVERIFY(!image2.isNull());
+
+ QCOMPARE(image1.height(), image2.height());
+ QCOMPARE(image1.width(), image2.width());
+
+ QCOMPARE(image1.format(), QImage::Format_CMYK8888);
+ QCOMPARE(image2.format(), QImage::Format_RGB32);
+
+ // compare all the pixels with a slack of 3. This ignores rounding errors
+ // in libjpeg/libpng, where some versions sacrifice accuracy for speed.
+ const auto fuzzyCompareColors = [](const QColor &c1, const QColor &c2) {
+ int c1rgba[4];
+ int c2rgba[4];
+
+ c1.getRgb(c1rgba + 0,
+ c1rgba + 1,
+ c1rgba + 2,
+ c1rgba + 3);
+
+ c2.getRgb(c2rgba + 0,
+ c2rgba + 1,
+ c2rgba + 2,
+ c2rgba + 3);
+
+ const auto fuzzyCompare = [](int a, int b) {
+ return qAbs(a - b) <= 3;
+ };
+
+ return fuzzyCompare(c1rgba[0], c2rgba[0]) &&
+ fuzzyCompare(c1rgba[1], c2rgba[1]) &&
+ fuzzyCompare(c1rgba[2], c2rgba[2]) &&
+ fuzzyCompare(c1rgba[3], c2rgba[3]);
+ };
+
+ for (int h = 0; h < image1.height(); ++h) {
+ const uchar *sl1 = image1.constScanLine(h);
+ const uchar *sl2 = image2.constScanLine(h);
+ for (int w = 0; w < image1.width(); ++w) {
+ const uchar *s1 = sl1 + w * 4;
+ const uchar *s2 = sl2 + w * 4;
+
+ QColor c1 = QColor::fromCmyk(s1[0], s1[1], s1[2], s1[3]);
+ QColor c2 = QColor::fromRgb(s2[2], s2[1], s2[0]);
+ QVERIFY2(fuzzyCompareColors(c1, c2),
+ qPrintable(QString("images differ in line %1, col %2").arg(h).arg(w)));
}
}
}
@@ -372,6 +401,60 @@ void tst_QImageReader::setScaledSize()
QCOMPARE(image.size(), newSize);
}
+void tst_QImageReader::setScaledSizeOneDimension_data()
+{
+ QTest::addColumn<QString>("fileName");
+ QTest::addColumn<QByteArray>("format");
+
+ QTest::newRow("PNG: kollada") << QString("kollada") << QByteArray("png");
+ QTest::newRow("JPEG: beavis") << QString("beavis") << QByteArray("jpeg");
+ QTest::newRow("GIF: earth") << QString("earth") << QByteArray("gif");
+ QTest::newRow("SVG: rect") << QString("rect") << QByteArray("svg");
+ QTest::newRow("BMP: colorful") << QString("colorful") << QByteArray("bmp");
+ QTest::newRow("XPM: marble") << QString("marble") << QByteArray("xpm");
+ QTest::newRow("PPM: teapot") << QString("teapot") << QByteArray("ppm");
+ QTest::newRow("XBM: gnus") << QString("gnus") << QByteArray("xbm");
+}
+
+void tst_QImageReader::setScaledSizeOneDimension()
+{
+ QFETCH(QString, fileName);
+ QFETCH(QByteArray, format);
+
+ SKIP_IF_UNSUPPORTED(format);
+
+ const QSize originalSize = QImageReader(prefix + fileName).size();
+ QVERIFY(!originalSize.isEmpty());
+
+ auto testScaledSize = [&] (const QSize &scaledSize) {
+ QSize expectedSize = scaledSize;
+ if (scaledSize.width() <= 0)
+ expectedSize.setWidth(qRound(originalSize.width() *
+ (qreal(scaledSize.height()) / originalSize.height())));
+ else if (scaledSize.height() <= 0)
+ expectedSize.setHeight(qRound(originalSize.height() *
+ (qreal(scaledSize.width()) / originalSize.width())));
+
+ QImageReader reader(prefix + fileName);
+ reader.setScaledSize(scaledSize);
+ QImage image = reader.read();
+ QVERIFY(!image.isNull());
+ QCOMPARE(image.size(), expectedSize);
+ };
+
+ // downscale
+ testScaledSize(QSize(originalSize.width() / 2, 0));
+ testScaledSize(QSize(originalSize.width() / 2, -1));
+ testScaledSize(QSize(0, originalSize.height() / 2));
+ testScaledSize(QSize(-1, originalSize.height() / 2));
+
+ // upscale
+ testScaledSize(QSize(originalSize.width() * 2, 0));
+ testScaledSize(QSize(originalSize.width() * 2, -1));
+ testScaledSize(QSize(0, originalSize.height() * 2));
+ testScaledSize(QSize(-1, originalSize.height() * 2));
+}
+
void tst_QImageReader::task255627_setNullScaledSize_data()
{
setScaledSize_data();
@@ -533,7 +616,7 @@ void tst_QImageReader::imageFormat_data()
QTest::newRow("ppm-4") << QString("test.ppm") << QByteArray("ppm") << QImage::Format_RGB32;
QTest::newRow("jpeg-1") << QString("beavis.jpg") << QByteArray("jpeg") << QImage::Format_Grayscale8;
- QTest::newRow("jpeg-2") << QString("YCbCr_cmyk.jpg") << QByteArray("jpeg") << QImage::Format_RGB32;
+ QTest::newRow("jpeg-2") << QString("YCbCr_cmyk.jpg") << QByteArray("jpeg") << QImage::Format_CMYK8888;
QTest::newRow("jpeg-3") << QString("YCbCr_rgb.jpg") << QByteArray("jpeg") << QImage::Format_RGB32;
QTest::newRow("gif-1") << QString("earth.gif") << QByteArray("gif") << QImage::Format_Invalid;
@@ -594,41 +677,31 @@ void tst_QImageReader::multiWordNamedColorXPM()
QCOMPARE(image.pixel(0, 2), qRgb(255, 250, 205)); // lemon chiffon
}
-void tst_QImageReader::supportedFormats()
+namespace {
+template <typename ForwardIterator>
+bool is_sorted_unique(ForwardIterator first, ForwardIterator last)
{
- QList<QByteArray> formats = QImageReader::supportedImageFormats();
- QList<QByteArray> sortedFormats = formats;
- std::sort(sortedFormats.begin(), sortedFormats.end());
-
- // check that the list is sorted
- QCOMPARE(formats, sortedFormats);
-
- QSet<QByteArray> formatSet;
- foreach (QByteArray format, formats)
- formatSet << format;
+ // a range is sorted with no dups iff each *i < *(i+1), so check that none are >=:
+ return std::adjacent_find(first, last, std::greater_equal<>{}) == last;
+}
+}
- // check that the list does not contain duplicates
- QCOMPARE(formatSet.size(), formats.size());
+void tst_QImageReader::supportedFormats()
+{
+ const QList<QByteArray> formats = QImageReader::supportedImageFormats();
+ auto printOnFailure = qScopeGuard([&] { qDebug() << formats; });
+ QVERIFY(is_sorted_unique(formats.begin(), formats.end()));
+ printOnFailure.dismiss();
}
void tst_QImageReader::supportedMimeTypes()
{
- QList<QByteArray> mimeTypes = QImageReader::supportedMimeTypes();
- QList<QByteArray> sortedMimeTypes = mimeTypes;
- std::sort(sortedMimeTypes.begin(), sortedMimeTypes.end());
-
- // check that the list is sorted
- QCOMPARE(mimeTypes, sortedMimeTypes);
-
- QSet<QByteArray> mimeTypeSet;
- foreach (QByteArray mimeType, mimeTypes)
- mimeTypeSet << mimeType;
-
+ const QList<QByteArray> mimeTypes = QImageReader::supportedMimeTypes();
+ auto printOnFailure = qScopeGuard([&] { qDebug() << mimeTypes; });
+ QVERIFY(is_sorted_unique(mimeTypes.begin(), mimeTypes.end()));
// check the list as a minimum contains image/bmp
- QVERIFY(mimeTypeSet.contains("image/bmp"));
-
- // check that the list does not contain duplicates
- QCOMPARE(mimeTypeSet.size(), mimeTypes.size());
+ QVERIFY(mimeTypes.contains("image/bmp"));
+ printOnFailure.dismiss();
}
void tst_QImageReader::setBackgroundColor_data()
@@ -673,7 +746,7 @@ void tst_QImageReader::supportsAnimation_data()
QTest::newRow("BMP: colorful") << QString("colorful.bmp") << false;
QTest::newRow("BMP: font") << QString("font.bmp") << false;
QTest::newRow("BMP: signed char") << QString("crash-signed-char.bmp") << false;
- QTest::newRow("BMP: test32bfv4") << QString("test32bfv4.bmp") << false;;
+ QTest::newRow("BMP: test32bfv4") << QString("test32bfv4.bmp") << false;
QTest::newRow("BMP: test32v5") << QString("test32v5.bmp") << false;
QTest::newRow("XPM: marble") << QString("marble.xpm") << false;
QTest::newRow("PNG: kollada") << QString("kollada.png") << false;
@@ -1623,43 +1696,56 @@ void tst_QImageReader::supportsOption_data()
QTest::addColumn<QIntList>("options");
QTest::newRow("png") << QString("black.png")
- << (QIntList() << QImageIOHandler::Gamma
- << QImageIOHandler::Description
- << QImageIOHandler::Quality
- << QImageIOHandler::CompressionRatio
- << QImageIOHandler::Size
- << QImageIOHandler::ScaledSize);
+ << QIntList{
+ QImageIOHandler::Gamma,
+ QImageIOHandler::Description,
+ QImageIOHandler::Quality,
+ QImageIOHandler::CompressionRatio,
+ QImageIOHandler::Size,
+ QImageIOHandler::ScaledSize,
+ QImageIOHandler::ImageFormat,
+ };
}
void tst_QImageReader::supportsOption()
{
QFETCH(QString, fileName);
- QFETCH(QIntList, options);
-
- QSet<QImageIOHandler::ImageOption> allOptions;
- allOptions << QImageIOHandler::Size
- << QImageIOHandler::ClipRect
- << QImageIOHandler::Description
- << QImageIOHandler::ScaledClipRect
- << QImageIOHandler::ScaledSize
- << QImageIOHandler::CompressionRatio
- << QImageIOHandler::Gamma
- << QImageIOHandler::Quality
- << QImageIOHandler::Name
- << QImageIOHandler::SubType
- << QImageIOHandler::IncrementalReading
- << QImageIOHandler::Endianness
- << QImageIOHandler::Animation
- << QImageIOHandler::BackgroundColor;
+ QFETCH(const QIntList, options);
QImageReader reader(prefix + fileName);
- for (int i = 0; i < options.size(); ++i) {
- QVERIFY(reader.supportsOption(QImageIOHandler::ImageOption(options.at(i))));
- allOptions.remove(QImageIOHandler::ImageOption(options.at(i)));
- }
- foreach (QImageIOHandler::ImageOption option, allOptions)
- QVERIFY(!reader.supportsOption(option));
+ for (int i = 0; ; ++i) {
+ // this switch ensures the compiler warns when we miss an enumerator [-Wswitch]
+ // do _not_ add a default case!
+ switch (const auto o = QImageIOHandler::ImageOption(i)) {
+ case QImageIOHandler::Size:
+ case QImageIOHandler::ClipRect:
+ case QImageIOHandler::Description:
+ case QImageIOHandler::ScaledClipRect:
+ case QImageIOHandler::ScaledSize:
+ case QImageIOHandler::CompressionRatio:
+ case QImageIOHandler::Gamma:
+ case QImageIOHandler::Quality:
+ case QImageIOHandler::Name:
+ case QImageIOHandler::SubType:
+ case QImageIOHandler::IncrementalReading:
+ case QImageIOHandler::Endianness:
+ case QImageIOHandler::Animation:
+ case QImageIOHandler::BackgroundColor:
+ case QImageIOHandler::ImageFormat:
+ case QImageIOHandler::SupportedSubTypes:
+ case QImageIOHandler::OptimizedWrite:
+ case QImageIOHandler::ProgressiveScanWrite:
+ case QImageIOHandler::ImageTransformation:
+ {
+ auto printOnFailure = qScopeGuard([&] { qDebug("failed at %d", i); });
+ QCOMPARE(reader.supportsOption(o), options.contains(i));
+ printOnFailure.dismiss();
+ continue; // ... as long as `i` represents a valid ImageOption value
+ }
+ }
+ break; // ... once `i` no longer represents a valid ImageOption value
+ }
}
void tst_QImageReader::autoDetectImageFormat()
@@ -1828,13 +1914,13 @@ void tst_QImageReader::testIgnoresFormatAndExtension()
SKIP_IF_UNSUPPORTED(expected.toLatin1());
- QList<QByteArray> formats = QImageReader::supportedImageFormats();
+ const QList<QByteArray> formats = QImageReader::supportedImageFormats();
QString fileNameBase = prefix + name + QLatin1Char('.');
QString tempPath = m_temporaryDir.path();
if (!tempPath.endsWith(QLatin1Char('/')))
tempPath += QLatin1Char('/');
- foreach (const QByteArray &f, formats) {
+ for (const QByteArray &f : formats) {
if (f == extension.toLocal8Bit())
continue;
@@ -1984,19 +2070,31 @@ void tst_QImageReader::preserveTexts_data()
for (int c = 0xa0; c <= 0xff; c++)
latin1set.append(QLatin1Char(c));
- QStringList fileNames;
- fileNames << QLatin1String(":/images/kollada.png")
- << QLatin1String(":/images/txts.jpg");
- foreach (const QString &fileName, fileNames) {
- QTest::newRow("Simple") << fileName << "simpletext";
- QTest::newRow("Whitespace") << fileName << " A text with whitespace ";
- QTest::newRow("Newline") << fileName << "A text\nwith newlines\n";
- QTest::newRow("Double newlines") << fileName << "A text\n\nwith double newlines\n\n";
- QTest::newRow("Long") << fileName << QString("A rather long text, at least after many repetitions. ").repeated(100);
- QTest::newRow("All Latin1 chars") << fileName << latin1set;
+ const QList<QLatin1StringView> fileNames{
+ QLatin1StringView(":/images/kollada.png"),
+ QLatin1StringView(":/images/txts.jpg")
+ // Common prefix of length 9 before file names: ":/images/", skipped below by + 9.
+ };
+ for (const auto &fileName : fileNames) {
+ QTest::addRow("Simple %s", fileName.data() + 9)
+ << QString(fileName) << "simpletext";
+ QTest::addRow("Whitespace %s", fileName.data() + 9)
+ << QString(fileName) << " A text with whitespace ";
+ QTest::addRow("Newline %s", fileName.data() + 9)
+ << QString(fileName) << "A text\nwith newlines\n";
+ QTest::addRow("Double newlines %s", fileName.data() + 9)
+ << QString(fileName) << "A text\n\nwith double newlines\n\n";
+ QTest::addRow("Long %s", fileName.data() + 9)
+ << QString(fileName)
+ << QString("A rather long text, at least after many repetitions. ").repeated(100);
+ QTest::addRow("All Latin1 chars %s", fileName.data() + 9)
+ << QString(fileName) << latin1set;
#if 0
// Depends on iTXt support in libpng
- QTest::newRow("Multibyte string") << fileName << QString::fromUtf8("\341\233\222\341\233\226\341\232\251\341\232\271\341\232\242\341\233\232\341\232\240");
+ QTest::addRow("Multibyte string %s", fileName.data() + 9)
+ << QString(fileName)
+ << QString::fromUtf8("\341\233\222\341\233\226\341\232\251\341\232"
+ "\271\341\232\242\341\233\232\341\232\240");
#endif
}
}