summaryrefslogtreecommitdiffstats
path: root/tests/auto/gui/image
diff options
context:
space:
mode:
Diffstat (limited to 'tests/auto/gui/image')
-rw-r--r--tests/auto/gui/image/CMakeLists.txt8
-rw-r--r--tests/auto/gui/image/qicoimageformat/CMakeLists.txt40
-rw-r--r--tests/auto/gui/image/qicoimageformat/icons/masked/24bpp.icobin0 -> 12862 bytes
-rw-r--r--tests/auto/gui/image/qicoimageformat/icons/masked/24bpp.pngbin0 -> 3911 bytes
-rw-r--r--tests/auto/gui/image/qicoimageformat/icons/masked/32bpp.icobin0 -> 16958 bytes
-rw-r--r--tests/auto/gui/image/qicoimageformat/icons/masked/32bpp.pngbin0 -> 5536 bytes
-rw-r--r--tests/auto/gui/image/qicoimageformat/tst_qicoimageformat.cpp58
-rw-r--r--tests/auto/gui/image/qicon/CMakeLists.txt17
-rw-r--r--tests/auto/gui/image/qicon/icons/fallbacktheme/16x16/edit-cut.pngbin0 -> 267 bytes
-rw-r--r--tests/auto/gui/image/qicon/icons/fallbacktheme/index.theme8
-rw-r--r--tests/auto/gui/image/qicon/icons/hicolor/16x16/hicolor-icon.pngbin0 -> 267 bytes
-rw-r--r--tests/auto/gui/image/qicon/icons/hicolor/index.theme11
-rw-r--r--tests/auto/gui/image/qicon/icons/testtheme/index.theme2
-rw-r--r--tests/auto/gui/image/qicon/icons/themeparent/index.theme1
-rw-r--r--tests/auto/gui/image/qicon/tst_qicon.cpp84
-rw-r--r--tests/auto/gui/image/qiconhighdpi/CMakeLists.txt11
-rw-r--r--tests/auto/gui/image/qiconhighdpi/tst_qiconhighdpi.cpp47
-rw-r--r--tests/auto/gui/image/qimage/CMakeLists.txt49
-rw-r--r--tests/auto/gui/image/qimage/images/CGATS001Compat-v2-micro.iccbin0 -> 8464 bytes
-rw-r--r--tests/auto/gui/image/qimage/tst_qimage.cpp313
-rw-r--r--tests/auto/gui/image/qimageiohandler/CMakeLists.txt11
-rw-r--r--tests/auto/gui/image/qimageiohandler/tst_qimageiohandler.cpp29
-rw-r--r--tests/auto/gui/image/qimagereader/BLACKLIST8
-rw-r--r--tests/auto/gui/image/qimagereader/CMakeLists.txt32
-rw-r--r--tests/auto/gui/image/qimagereader/images/image.pbm10
-rw-r--r--tests/auto/gui/image/qimagereader/tst_qimagereader.cpp344
-rw-r--r--tests/auto/gui/image/qimagewriter/CMakeLists.txt41
-rw-r--r--tests/auto/gui/image/qimagewriter/tst_qimagewriter.cpp31
-rw-r--r--tests/auto/gui/image/qmovie/CMakeLists.txt22
-rw-r--r--tests/auto/gui/image/qmovie/multiframe/Obj_N2_Internal_Mem.icobin0 -> 25214 bytes
-rw-r--r--tests/auto/gui/image/qmovie/tst_qmovie.cpp124
-rw-r--r--tests/auto/gui/image/qpicture/CMakeLists.txt11
-rw-r--r--tests/auto/gui/image/qpicture/tst_qpicture.cpp29
-rw-r--r--tests/auto/gui/image/qpixmap/CMakeLists.txt15
-rw-r--r--tests/auto/gui/image/qpixmap/tst_qpixmap.cpp31
-rw-r--r--tests/auto/gui/image/qpixmapcache/CMakeLists.txt11
-rw-r--r--tests/auto/gui/image/qpixmapcache/tst_qpixmapcache.cpp192
37 files changed, 990 insertions, 600 deletions
diff --git a/tests/auto/gui/image/CMakeLists.txt b/tests/auto/gui/image/CMakeLists.txt
index 27916d0409..9cc6d4d2bf 100644
--- a/tests/auto/gui/image/CMakeLists.txt
+++ b/tests/auto/gui/image/CMakeLists.txt
@@ -1,6 +1,7 @@
-# Generated from image.pro.
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
-# QTBUG-87669 # special case
+# QTBUG-87669
if(TARGET Qt::Network AND NOT ANDROID)
add_subdirectory(qimagereader)
endif()
@@ -17,7 +18,8 @@ add_subdirectory(qiconhighdpi)
if(QT_FEATURE_private_tests)
add_subdirectory(qpixmapcache)
endif()
-# QTBUG-87669 # special case
+
+# QTBUG-87669
if(NOT ANDROID)
add_subdirectory(qicon)
endif()
diff --git a/tests/auto/gui/image/qicoimageformat/CMakeLists.txt b/tests/auto/gui/image/qicoimageformat/CMakeLists.txt
index 704c51a6be..17ec68df4e 100644
--- a/tests/auto/gui/image/qicoimageformat/CMakeLists.txt
+++ b/tests/auto/gui/image/qicoimageformat/CMakeLists.txt
@@ -1,9 +1,16 @@
-# Generated from qicoimageformat.pro.
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qicoimageformat Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qicoimageformat LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
# Collect test data
file(GLOB_RECURSE test_data_glob
RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
@@ -13,37 +20,8 @@ list(APPEND test_data ${test_data_glob})
qt_internal_add_test(tst_qicoimageformat
SOURCES
tst_qicoimageformat.cpp
- PUBLIC_LIBRARIES
+ LIBRARIES
Qt::Gui
TESTDATA ${test_data}
)
-## Scopes:
-#####################################################################
-
-if(ANDROID)
- # Resources:
- set(qicoimageformat_resource_files
- "icons/invalid/35floppy.ico"
- "icons/valid/35FLOPPY.ICO"
- "icons/valid/AddPerfMon.ico"
- "icons/valid/App.ico"
- "icons/valid/Obj_N2_Internal_Mem.ico"
- "icons/valid/Qt.ico"
- "icons/valid/Status_Play.ico"
- "icons/valid/TIMER01.ICO"
- "icons/valid/WORLD.ico"
- "icons/valid/WORLDH.ico"
- "icons/valid/abcardWindow.ico"
- "icons/valid/semitransparent.ico"
- "icons/valid/trolltechlogo_tiny.ico"
- "icons/valid/yellow.cur"
- )
-
- qt_internal_add_resource(tst_qicoimageformat "qicoimageformat"
- PREFIX
- "/"
- FILES
- ${qicoimageformat_resource_files}
- )
-endif()
diff --git a/tests/auto/gui/image/qicoimageformat/icons/masked/24bpp.ico b/tests/auto/gui/image/qicoimageformat/icons/masked/24bpp.ico
new file mode 100644
index 0000000000..7e9cfa2414
--- /dev/null
+++ b/tests/auto/gui/image/qicoimageformat/icons/masked/24bpp.ico
Binary files differ
diff --git a/tests/auto/gui/image/qicoimageformat/icons/masked/24bpp.png b/tests/auto/gui/image/qicoimageformat/icons/masked/24bpp.png
new file mode 100644
index 0000000000..f0a19c05e3
--- /dev/null
+++ b/tests/auto/gui/image/qicoimageformat/icons/masked/24bpp.png
Binary files differ
diff --git a/tests/auto/gui/image/qicoimageformat/icons/masked/32bpp.ico b/tests/auto/gui/image/qicoimageformat/icons/masked/32bpp.ico
new file mode 100644
index 0000000000..a22248d76a
--- /dev/null
+++ b/tests/auto/gui/image/qicoimageformat/icons/masked/32bpp.ico
Binary files differ
diff --git a/tests/auto/gui/image/qicoimageformat/icons/masked/32bpp.png b/tests/auto/gui/image/qicoimageformat/icons/masked/32bpp.png
new file mode 100644
index 0000000000..a6ceac73fa
--- /dev/null
+++ b/tests/auto/gui/image/qicoimageformat/icons/masked/32bpp.png
Binary files differ
diff --git a/tests/auto/gui/image/qicoimageformat/tst_qicoimageformat.cpp b/tests/auto/gui/image/qicoimageformat/tst_qicoimageformat.cpp
index 37d5f4998c..136f56facf 100644
--- a/tests/auto/gui/image/qicoimageformat/tst_qicoimageformat.cpp
+++ b/tests/auto/gui/image/qicoimageformat/tst_qicoimageformat.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QTest>
#include <QtGui>
#include <QtCore>
@@ -52,6 +27,8 @@ private slots:
void pngCompression();
void write_data();
void write();
+ void icoMask_data();
+ void icoMask();
private:
QString m_IconPath;
@@ -344,6 +321,33 @@ void tst_QIcoImageFormat::write()
}
}
+void tst_QIcoImageFormat::icoMask_data()
+{
+ QTest::addColumn<QString>("inFile");
+ QTest::addColumn<QString>("outFile");
+
+ QTest::newRow("24bpp") << "masked/24bpp.ico" << "masked/24bpp.png";
+ QTest::newRow("32bpp") << "masked/32bpp.ico" << "masked/32bpp.png";
+}
+
+void tst_QIcoImageFormat::icoMask()
+{
+ QFETCH(QString, inFile);
+ QFETCH(QString, outFile);
+
+ QImage inImage;
+ QImageReader inReader(m_IconPath + QLatin1Char('/') + inFile);
+ inReader.read(&inImage);
+
+ QImage outImage;
+ QImageReader outReader(m_IconPath + QLatin1Char('/') + outFile);
+ outReader.read(&outImage);
+ outImage.setColorSpace(inImage.colorSpace());
+ outImage = outImage.convertToFormat(inImage.format());
+
+ QCOMPARE(inImage, outImage);
+}
+
QTEST_MAIN(tst_QIcoImageFormat)
#include "tst_qicoimageformat.moc"
diff --git a/tests/auto/gui/image/qicon/CMakeLists.txt b/tests/auto/gui/image/qicon/CMakeLists.txt
index 5f6b139205..c693c559cc 100644
--- a/tests/auto/gui/image/qicon/CMakeLists.txt
+++ b/tests/auto/gui/image/qicon/CMakeLists.txt
@@ -1,9 +1,16 @@
-# Generated from qicon.pro.
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qicon Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qicon LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
# Collect test data
file(GLOB_RECURSE test_data_glob
RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
@@ -33,7 +40,7 @@ list(APPEND test_data ${test_data_glob})
qt_internal_add_test(tst_qicon
SOURCES
tst_qicon.cpp
- PUBLIC_LIBRARIES
+ LIBRARIES
Qt::Gui
TESTDATA ${test_data}
)
@@ -55,6 +62,10 @@ set(tst_qicon_resource_files
"./icons/themeparent/index.theme"
"./icons/themeparent/scalable/actions/address-book-new.svg"
"./icons/themeparent/scalable/actions/appointment-new.svg"
+ "./icons/fallbacktheme/index.theme"
+ "./icons/fallbacktheme/16x16/edit-cut.png"
+ "./icons/hicolor/index.theme"
+ "./icons/hicolor/16x16/hicolor-icon.png"
"./second_icons/testtheme/32x32/actions/appointment-new.png"
"./styles/commonstyle/images/standardbutton-open-128.png"
"./styles/commonstyle/images/standardbutton-open-16.png"
@@ -91,6 +102,6 @@ qt_internal_add_resource(tst_qicon "qmake_immediate"
#####################################################################
qt_internal_extend_target(tst_qicon CONDITION TARGET Qt::Widgets
- PUBLIC_LIBRARIES
+ LIBRARIES
Qt::Widgets
)
diff --git a/tests/auto/gui/image/qicon/icons/fallbacktheme/16x16/edit-cut.png b/tests/auto/gui/image/qicon/icons/fallbacktheme/16x16/edit-cut.png
new file mode 100644
index 0000000000..661ef1ad03
--- /dev/null
+++ b/tests/auto/gui/image/qicon/icons/fallbacktheme/16x16/edit-cut.png
Binary files differ
diff --git a/tests/auto/gui/image/qicon/icons/fallbacktheme/index.theme b/tests/auto/gui/image/qicon/icons/fallbacktheme/index.theme
new file mode 100644
index 0000000000..809d296669
--- /dev/null
+++ b/tests/auto/gui/image/qicon/icons/fallbacktheme/index.theme
@@ -0,0 +1,8 @@
+[Icon Theme]
+Name=fallbacktheme
+
+Directories=16x16
+
+[16x16]
+Size=16
+Type=Fixed
diff --git a/tests/auto/gui/image/qicon/icons/hicolor/16x16/hicolor-icon.png b/tests/auto/gui/image/qicon/icons/hicolor/16x16/hicolor-icon.png
new file mode 100644
index 0000000000..661ef1ad03
--- /dev/null
+++ b/tests/auto/gui/image/qicon/icons/hicolor/16x16/hicolor-icon.png
Binary files differ
diff --git a/tests/auto/gui/image/qicon/icons/hicolor/index.theme b/tests/auto/gui/image/qicon/icons/hicolor/index.theme
new file mode 100644
index 0000000000..e5e5cef9b1
--- /dev/null
+++ b/tests/auto/gui/image/qicon/icons/hicolor/index.theme
@@ -0,0 +1,11 @@
+[Icon Theme]
+Name=hicolor
+
+# Provide a minimal hicolor theme, so that our hicolor fallback
+# lookup during testing will find that theme on all systems.
+
+Directories=16x16
+
+[16x16]
+Size=16
+Type=Fixed
diff --git a/tests/auto/gui/image/qicon/icons/testtheme/index.theme b/tests/auto/gui/image/qicon/icons/testtheme/index.theme
index e18736ab43..53664b14b2 100644
--- a/tests/auto/gui/image/qicon/icons/testtheme/index.theme
+++ b/tests/auto/gui/image/qicon/icons/testtheme/index.theme
@@ -1,7 +1,7 @@
[Icon Theme]
_Name=Test
_Comment=Test Theme
-Inherits=crystalsvg, themeparent
+Inherits=themeparent
Example=x-directory-normal
# KDE Specific Stuff
diff --git a/tests/auto/gui/image/qicon/icons/themeparent/index.theme b/tests/auto/gui/image/qicon/icons/themeparent/index.theme
index e536a0bf2f..96267addd6 100644
--- a/tests/auto/gui/image/qicon/icons/themeparent/index.theme
+++ b/tests/auto/gui/image/qicon/icons/themeparent/index.theme
@@ -1,7 +1,6 @@
[Icon Theme]
_Name=Test
_Comment=Test Theme
-Inherits=gnome,crystalsvg
Example=x-directory-normal
# KDE Specific Stuff
diff --git a/tests/auto/gui/image/qicon/tst_qicon.cpp b/tests/auto/gui/image/qicon/tst_qicon.cpp
index 3363f86809..99b4a0589e 100644
--- a/tests/auto/gui/image/qicon/tst_qicon.cpp
+++ b/tests/auto/gui/image/qicon/tst_qicon.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QTest>
#include <QImageReader>
@@ -66,6 +41,7 @@ private slots:
void streamAvailableSizes();
void fromTheme();
void fromThemeCache();
+ void fromThemeConstant();
#ifndef QT_NO_WIDGETS
void task184901_badCache();
@@ -216,21 +192,21 @@ void tst_QIcon::isNull() {
// test string constructor with empty string
QIcon iconEmptyString = QIcon(QString());
QVERIFY(iconEmptyString.isNull());
- QVERIFY(!iconEmptyString.actualSize(QSize(32, 32)).isValid());;
+ QVERIFY(!iconEmptyString.actualSize(QSize(32, 32)).isValid());
// test string constructor with non-existing file
QIcon iconNoFile = QIcon("imagedoesnotexist");
- QVERIFY(!iconNoFile.isNull());
+ QVERIFY(iconNoFile.isNull());
QVERIFY(!iconNoFile.actualSize(QSize(32, 32)).isValid());
// test string constructor with non-existing file with suffix
QIcon iconNoFileSuffix = QIcon("imagedoesnotexist.png");
- QVERIFY(!iconNoFileSuffix.isNull());
+ QVERIFY(iconNoFileSuffix.isNull());
QVERIFY(!iconNoFileSuffix.actualSize(QSize(32, 32)).isValid());
// test string constructor with existing file but unsupported format
QIcon iconUnsupportedFormat = QIcon(m_sourceFileName);
- QVERIFY(!iconUnsupportedFormat.isNull());
+ QVERIFY(iconUnsupportedFormat.isNull());
QVERIFY(!iconUnsupportedFormat.actualSize(QSize(32, 32)).isValid());
// test string constructor with existing file and supported format
@@ -577,6 +553,10 @@ void tst_QIcon::availableSizes()
void tst_QIcon::name()
{
+ const auto reset = qScopeGuard([]{
+ QIcon::setThemeName({});
+ QIcon::setThemeSearchPaths({});
+ });
{
// No name if icon does not come from a theme
QIcon icon(":/image.png");
@@ -654,6 +634,7 @@ void tst_QIcon::task184901_badCache()
void tst_QIcon::fromTheme()
{
+ const bool abIconFromPlatform = !QIcon::fromTheme("address-book-new").isNull();
QString firstSearchPath = QLatin1String(":/icons");
QString secondSearchPath = QLatin1String(":/second_icons");
QIcon::setThemeSearchPaths(QStringList() << firstSearchPath << secondSearchPath);
@@ -742,14 +723,44 @@ void tst_QIcon::fromTheme()
QCOMPARE(i.availableSizes(), abIcon.availableSizes());
}
+ // Setting or changing the fallback theme should invalidate earlier lookups.
+ // We can only test this if the system doesn't provide an icon, because once
+ // we got a valid icon, it will be cached, and even if we proxy to a different
+ // engine when a fallback theme is set, the cacheKey of the icon will be the
+ // same.
+ const QIcon editCut = QIcon::fromTheme("edit-cut");
+ if (editCut.isNull()) {
+ QIcon::setFallbackThemeName("fallbacktheme");
+ QVERIFY(!QIcon::fromTheme("edit-cut").isNull());
+ }
+
// Make sure setting the theme name clears the state
QIcon::setThemeName("");
abIcon = QIcon::fromTheme("address-book-new");
- QVERIFY(abIcon.isNull());
+ QCOMPARE_NE(abIcon.isNull(), abIconFromPlatform);
+
+ // Test fallback icon behavior for empty theme names.
+ // Can only reliably test this on systems that don't have a
+ // named system icon theme.
+ QIcon::setThemeName(""); // Reset user-theme
+ if (QIcon::themeName().isEmpty()) {
+ // Test icon from fallback theme even when theme name is empty
+ QIcon::setFallbackThemeName("fallbacktheme");
+ QVERIFY(!QIcon::fromTheme("edit-cut").isNull());
+
+ // Test icon from fallback path even when theme name is empty
+ fallbackIcon = QIcon::fromTheme("red");
+ QVERIFY(!fallbackIcon.isNull());
+ QVERIFY(QIcon::hasThemeIcon("red"));
+ QCOMPARE(fallbackIcon.availableSizes().size(), 1);
+ }
// Passing a full path to fromTheme is not very useful, but should work anyway
QIcon fullPathIcon = QIcon::fromTheme(m_pngImageFileName);
QVERIFY(!fullPathIcon.isNull());
+
+ // Restore to system fallback theme
+ QIcon::setFallbackThemeName("");
}
static inline QString findGtkUpdateIconCache()
@@ -810,7 +821,7 @@ void tst_QIcon::fromThemeCache()
QTest::qWait(1000); // wait enough to have a different modification time in seconds
QVERIFY(QFile(QStringLiteral(":/styles/commonstyle/images/standardbutton-save-16.png"))
.copy(dir.path() + QLatin1String("/testcache/16x16/actions/button-save.png")));
- QVERIFY(QFileInfo(cacheName).lastModified() < QFileInfo(dir.path() + QLatin1String("/testcache/16x16/actions")).lastModified());
+ QVERIFY(QFileInfo(cacheName).lastModified(QTimeZone::UTC) < QFileInfo(dir.path() + QLatin1String("/testcache/16x16/actions")).lastModified(QTimeZone::UTC));
QIcon::setThemeSearchPaths(QStringList() << dir.path()); // reload themes
QVERIFY(!QIcon::fromTheme("button-open").isNull());
@@ -831,13 +842,18 @@ void tst_QIcon::fromThemeCache()
QCOMPARE(process.exitStatus(), QProcess::NormalExit);
QCOMPARE(process.exitCode(), 0);
#endif // QT_CONFIG(process)
- QVERIFY(QFileInfo(cacheName).lastModified() >= QFileInfo(dir.path() + QLatin1String("/testcache/16x16/actions")).lastModified());
+ QVERIFY(QFileInfo(cacheName).lastModified(QTimeZone::UTC) >= QFileInfo(dir.path() + QLatin1String("/testcache/16x16/actions")).lastModified(QTimeZone::UTC));
QIcon::setThemeSearchPaths(QStringList() << dir.path()); // reload themes
QVERIFY(!QIcon::fromTheme("button-open").isNull());
QVERIFY(!QIcon::fromTheme("button-open-fallback").isNull());
QVERIFY(QIcon::fromTheme("notexist-fallback").isNull());
}
+void tst_QIcon::fromThemeConstant()
+{
+ const QIcon icon = QIcon::fromTheme(QIcon::ThemeIcon::EditCut);
+}
+
void tst_QIcon::task223279_inconsistentAddFile()
{
QIcon icon1;
diff --git a/tests/auto/gui/image/qiconhighdpi/CMakeLists.txt b/tests/auto/gui/image/qiconhighdpi/CMakeLists.txt
index 989cf1f44d..f0ccb97c8a 100644
--- a/tests/auto/gui/image/qiconhighdpi/CMakeLists.txt
+++ b/tests/auto/gui/image/qiconhighdpi/CMakeLists.txt
@@ -1,9 +1,16 @@
-# Generated from qiconhighdpi.pro.
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qiconhighdpi Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qiconhighdpi LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
# Collect test data
file(GLOB_RECURSE test_data_glob
RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
@@ -13,7 +20,7 @@ list(APPEND test_data ${test_data_glob})
qt_internal_add_test(tst_qiconhighdpi
SOURCES
tst_qiconhighdpi.cpp
- PUBLIC_LIBRARIES
+ LIBRARIES
Qt::Gui
TESTDATA ${test_data}
)
diff --git a/tests/auto/gui/image/qiconhighdpi/tst_qiconhighdpi.cpp b/tests/auto/gui/image/qiconhighdpi/tst_qiconhighdpi.cpp
index 3282776ee6..34f0132865 100644
--- a/tests/auto/gui/image/qiconhighdpi/tst_qiconhighdpi.cpp
+++ b/tests/auto/gui/image/qiconhighdpi/tst_qiconhighdpi.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QTest>
#include <qicon.h>
@@ -42,6 +17,7 @@ private slots:
void addPixmap_data();
void addPixmap();
void ninePatch();
+ void preferUpscale();
};
tst_QIconHighDpi::tst_QIconHighDpi()
@@ -236,6 +212,23 @@ void tst_QIconHighDpi::ninePatch()
}
}
+void tst_QIconHighDpi::preferUpscale()
+{
+ QIcon icon;
+
+ // manual pixmap adder for full control of devicePixelRatio
+ auto addPixmapWithDpr = [&icon](const QString &path, qreal dpr) {
+ QImage image(path);
+ image.setDevicePixelRatio(dpr);
+ icon.addPixmap(QPixmap::fromImage(image));
+ };
+
+ addPixmapWithDpr(":/icons/testtheme/22x22/actions/appointment-new.png", 1);
+ addPixmapWithDpr(":/icons/testtheme/22x22@2/actions/appointment-new.png", 2);
+
+ QCOMPARE(icon.pixmap(QSize(22, 22), 1.25f).devicePixelRatio(), 1.25f);
+}
+
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
diff --git a/tests/auto/gui/image/qimage/CMakeLists.txt b/tests/auto/gui/image/qimage/CMakeLists.txt
index 4c95b32e48..8d0842026d 100644
--- a/tests/auto/gui/image/qimage/CMakeLists.txt
+++ b/tests/auto/gui/image/qimage/CMakeLists.txt
@@ -1,9 +1,16 @@
-# Generated from qimage.pro.
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qimage Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qimage LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
# Collect test data
file(GLOB_RECURSE test_data_glob
RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
@@ -13,54 +20,20 @@ list(APPEND test_data ${test_data_glob})
qt_internal_add_test(tst_qimage
SOURCES
tst_qimage.cpp
- PUBLIC_LIBRARIES
+ LIBRARIES
Qt::CorePrivate
Qt::Gui
Qt::GuiPrivate
TESTDATA ${test_data}
)
-## Scopes:
-#####################################################################
-
-if(ANDROID)
- # Resources:
- set(qimage_resource_files
- "images/image.bmp"
- "images/image.gif"
- "images/image.ico"
- "images/image.jpg"
- "images/image.pbm"
- "images/image.pgm"
- "images/image.png"
- "images/image.ppm"
- "images/image.xbm"
- "images/image.xpm"
- "images/jpeg_exif_orientation_value_1.jpg"
- "images/jpeg_exif_orientation_value_2.jpg"
- "images/jpeg_exif_orientation_value_3.jpg"
- "images/jpeg_exif_orientation_value_4.jpg"
- "images/jpeg_exif_orientation_value_5.jpg"
- "images/jpeg_exif_orientation_value_6.jpg"
- "images/jpeg_exif_orientation_value_7.jpg"
- "images/jpeg_exif_orientation_value_8.jpg"
- )
-
- qt_internal_add_resource(tst_qimage "qimage"
- PREFIX
- "/"
- FILES
- ${qimage_resource_files}
- )
-endif()
-
qt_internal_extend_target(tst_qimage CONDITION WIN32
- PUBLIC_LIBRARIES
+ LIBRARIES
gdi32
user32
)
qt_internal_extend_target(tst_qimage CONDITION APPLE
- PUBLIC_LIBRARIES
+ LIBRARIES
${FWCoreGraphics}
)
diff --git a/tests/auto/gui/image/qimage/images/CGATS001Compat-v2-micro.icc b/tests/auto/gui/image/qimage/images/CGATS001Compat-v2-micro.icc
new file mode 100644
index 0000000000..b5a73495bf
--- /dev/null
+++ b/tests/auto/gui/image/qimage/images/CGATS001Compat-v2-micro.icc
Binary files differ
diff --git a/tests/auto/gui/image/qimage/tst_qimage.cpp b/tests/auto/gui/image/qimage/tst_qimage.cpp
index 6f9e0641ac..1d0cdfcc4e 100644
--- a/tests/auto/gui/image/qimage/tst_qimage.cpp
+++ b/tests/auto/gui/image/qimage/tst_qimage.cpp
@@ -1,38 +1,15 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QTest>
#include <QBuffer>
+#include <QMatrix4x4>
#include <qimage.h>
#include <qimagereader.h>
#include <qlist.h>
+#include <qset.h>
#include <qtransform.h>
#include <qrandom.h>
#include <stdio.h>
@@ -91,6 +68,7 @@ private slots:
void rotate_data();
void rotate();
+ void rotateBigImage();
void copy();
@@ -130,6 +108,8 @@ private slots:
void smoothScaleAlpha();
void smoothScaleFormats_data();
void smoothScaleFormats();
+ void smoothScaleNoConversion_data();
+ void smoothScaleNoConversion();
void transformed_data();
void transformed();
@@ -189,6 +169,11 @@ private slots:
void largeInplaceRgbConversion_data();
void largeInplaceRgbConversion();
+ void colorSpaceRgbConversion_data();
+ void colorSpaceRgbConversion();
+ void colorSpaceCmykConversion_data();
+ void colorSpaceCmykConversion();
+
void deepCopyWhenPaintingActive();
void scaled_QTBUG19157();
@@ -250,12 +235,18 @@ private slots:
void largeFillScale();
void largeRasterScale();
+ void metadataChangeWithReadOnlyPixels();
+ void scaleIndexed();
+
#if defined(Q_OS_WIN)
void toWinHBITMAP_data();
void toWinHBITMAP();
void fromMonoHBITMAP();
#endif // Q_OS_WIN
+ void tofromPremultipliedFormat_data();
+ void tofromPremultipliedFormat();
+
private:
const QString m_prefix;
};
@@ -335,7 +326,9 @@ static QLatin1String formatToString(QImage::Format format)
return QLatin1String("RGBA32FPx4");
case QImage::Format_RGBA32FPx4_Premultiplied:
return QLatin1String("RGBA32FPx4pm");
- default:
+ case QImage::Format_CMYK8888:
+ return QLatin1String("CMYK8888");
+ case QImage::NImageFormats:
break;
};
Q_UNREACHABLE();
@@ -1153,10 +1146,9 @@ void tst_QImage::rotate_data()
QTest::addColumn<QImage::Format>("format");
QTest::addColumn<int>("degrees");
- QList<int> degrees;
- degrees << 0 << 90 << 180 << 270;
+ constexpr int degrees[] = {0, 90, 180, 270};
- foreach (int d, degrees) {
+ for (int d : degrees) {
const QString dB = QString::number(d);
for (int i = QImage::Format_Indexed8; i < QImage::NImageFormats; i++) {
QImage::Format format = static_cast<QImage::Format>(i);
@@ -1234,6 +1226,23 @@ void tst_QImage::rotate()
QCOMPARE(original, dest);
}
+void tst_QImage::rotateBigImage()
+{
+ // QTBUG-105088
+ QImage big_image(3840, 2160, QImage::Format_ARGB32_Premultiplied);
+ QTransform t;
+ t.translate(big_image.width() / 2.0, big_image.height() / 2.0);
+ t.rotate(-89, Qt::YAxis, big_image.width());
+ t.translate(-big_image.width() / 2.0, -big_image.height() / 2.0);
+ QVERIFY(!big_image.transformed(t).isNull());
+
+ QMatrix4x4 m;
+ m.translate(big_image.width() / 2.0, big_image.height() / 2.0);
+ m.projectedRotate(89, 0, 1, 0, big_image.width());
+ m.translate(-big_image.width() / 2.0, -big_image.height() / 2.0);
+ QVERIFY(!big_image.transformed(m.toTransform()).isNull());
+}
+
void tst_QImage::copy()
{
// Task 99250
@@ -1505,6 +1514,8 @@ void tst_QImage::setPixelWithAlpha_data()
continue;
if (c == QImage::Format_Alpha8)
continue;
+ if (c == QImage::Format_CMYK8888)
+ continue;
QTest::newRow(qPrintable(formatToString(QImage::Format(c)))) << QImage::Format(c);
}
}
@@ -2062,6 +2073,24 @@ void tst_QImage::smoothScaleFormats()
QVERIFY(rotated.hasAlphaChannel());
}
+void tst_QImage::smoothScaleNoConversion_data()
+{
+ QTest::addColumn<QImage::Format>("format");
+ QTest::addRow("Mono") << QImage::Format_Mono;
+ QTest::addRow("MonoLSB") << QImage::Format_MonoLSB;
+ QTest::addRow("Indexed8") << QImage::Format_Indexed8;
+}
+
+void tst_QImage::smoothScaleNoConversion()
+{
+ QFETCH(QImage::Format, format);
+ QImage img(128, 128, format);
+ img.fill(1);
+ img.setColorTable(QList<QRgb>() << qRgba(255,0,0,255) << qRgba(0,0,0,0));
+ img = img.scaled(QSize(48, 48), Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
+ QVERIFY(img.hasAlphaChannel());
+}
+
static int count(const QImage &img, int x, int y, int dx, int dy, QRgb pixel)
{
int i = 0;
@@ -2548,7 +2577,8 @@ void tst_QImage::rgbSwapped_data()
for (int i = QImage::Format_Indexed8; i < QImage::NImageFormats; ++i) {
if (i == QImage::Format_Alpha8
|| i == QImage::Format_Grayscale8
- || i == QImage::Format_Grayscale16) {
+ || i == QImage::Format_Grayscale16
+ || i == QImage::Format_CMYK8888) {
continue;
}
QTest::addRow("%s", formatToString(QImage::Format(i)).data()) << QImage::Format(i);
@@ -2642,20 +2672,20 @@ void tst_QImage::mirrored_data()
QTest::newRow("Format_Mono, horizontal+vertical") << QImage::Format_Mono << true << true << 16 << 16;
QTest::newRow("Format_MonoLSB, horizontal+vertical") << QImage::Format_MonoLSB << true << true << 16 << 16;
- QTest::newRow("Format_RGB32, vertical") << QImage::Format_RGB32 << true << false << 8 << 16;
- QTest::newRow("Format_ARGB32, vertical") << QImage::Format_ARGB32 << true << false << 16 << 8;
+ QTest::newRow("Format_RGB32, vertical, narrow") << QImage::Format_RGB32 << true << false << 8 << 16;
+ QTest::newRow("Format_ARGB32, vertical, short") << QImage::Format_ARGB32 << true << false << 16 << 8;
QTest::newRow("Format_Mono, vertical, non-aligned") << QImage::Format_Mono << true << false << 19 << 25;
QTest::newRow("Format_MonoLSB, vertical, non-aligned") << QImage::Format_MonoLSB << true << false << 19 << 25;
// Non-aligned horizontal 1-bit needs special handling so test this.
QTest::newRow("Format_Mono, horizontal, non-aligned") << QImage::Format_Mono << false << true << 13 << 17;
- QTest::newRow("Format_Mono, horizontal, non-aligned") << QImage::Format_Mono << false << true << 19 << 25;
- QTest::newRow("Format_Mono, horizontal+vertical, non-aligned") << QImage::Format_Mono << true << true << 25 << 47;
+ QTest::newRow("Format_Mono, horizontal, non-aligned, big") << QImage::Format_Mono << false << true << 19 << 25;
+ QTest::newRow("Format_Mono, horizontal+vertical, non-aligned, big") << QImage::Format_Mono << true << true << 25 << 47;
QTest::newRow("Format_Mono, horizontal+vertical, non-aligned") << QImage::Format_Mono << true << true << 21 << 16;
QTest::newRow("Format_MonoLSB, horizontal, non-aligned") << QImage::Format_MonoLSB << false << true << 13 << 17;
- QTest::newRow("Format_MonoLSB, horizontal, non-aligned") << QImage::Format_MonoLSB << false << true << 19 << 25;
- QTest::newRow("Format_MonoLSB, horizontal+vertical, non-aligned") << QImage::Format_MonoLSB << true << true << 25 << 47;
+ QTest::newRow("Format_MonoLSB, horizontal, non-aligned, big") << QImage::Format_MonoLSB << false << true << 19 << 25;
+ QTest::newRow("Format_MonoLSB, horizontal+vertical, non-aligned, big") << QImage::Format_MonoLSB << true << true << 25 << 47;
QTest::newRow("Format_MonoLSB, horizontal+vertical, non-aligned") << QImage::Format_MonoLSB << true << true << 21 << 16;
}
@@ -3030,13 +3060,15 @@ void tst_QImage::inplaceRgbConversion_data()
for (int i = QImage::Format_RGB32; i < QImage::NImageFormats; ++i) {
if (i == QImage::Format_Alpha8
|| i == QImage::Format_Grayscale8
- || i == QImage::Format_Grayscale16) {
+ || i == QImage::Format_Grayscale16
+ || i == QImage::Format_CMYK8888) {
continue;
}
for (int j = QImage::Format_RGB32; j < QImage::NImageFormats; ++j) {
if (j == QImage::Format_Alpha8
|| j == QImage::Format_Grayscale8
- || j == QImage::Format_Grayscale16) {
+ || j == QImage::Format_Grayscale16
+ || j == QImage::Format_CMYK8888) {
continue;
}
if (i == j)
@@ -3217,6 +3249,144 @@ void tst_QImage::largeInplaceRgbConversion()
}
}
+void tst_QImage::colorSpaceRgbConversion_data()
+{
+ QTest::addColumn<QImage::Format>("fromFormat");
+ QTest::addColumn<QImage::Format>("toFormat");
+
+ // The various possible code paths for color space conversions compatible with RGB color spaces:
+ QImage::Format formats[] = {
+ QImage::Format_RGB32,
+ QImage::Format_ARGB32,
+ QImage::Format_ARGB32_Premultiplied,
+ QImage::Format_RGBX64,
+ QImage::Format_RGBA64,
+ QImage::Format_RGBA64_Premultiplied,
+ QImage::Format_RGBX32FPx4,
+ QImage::Format_RGBA32FPx4,
+ QImage::Format_RGBA32FPx4_Premultiplied,
+ QImage::Format_Grayscale8,
+ QImage::Format_Grayscale16,
+ };
+
+ for (auto fromFormat : formats) {
+ const QLatin1String formatI = formatToString(fromFormat);
+ for (auto toFormat : formats) {
+ QTest::addRow("%s -> %s", formatI.data(), formatToString(toFormat).data())
+ << fromFormat << toFormat;
+ }
+ }
+}
+
+void tst_QImage::colorSpaceRgbConversion()
+{
+ // Test that all color space conversions work
+ QFETCH(QImage::Format, fromFormat);
+ QFETCH(QImage::Format, toFormat);
+
+ bool srcGrayscale = fromFormat == QImage::Format_Grayscale8 || fromFormat == QImage::Format_Grayscale16;
+ bool dstGrayscale = toFormat == QImage::Format_Grayscale8 || toFormat == QImage::Format_Grayscale16;
+
+ QImage image(16, 16, fromFormat);
+ image.setColorSpace(QColorSpace::SRgb);
+
+ for (int i = 0; i < image.height(); ++i) {
+ for (int j = 0; j < image.width(); ++j) {
+ if (srcGrayscale || dstGrayscale)
+ image.setPixel(j, i, qRgb((i + j) * 8, (i + j) * 8, (i + j) * 8));
+ else
+ image.setPixel(j, i, qRgb(j * 16, i * 16, (i + j) * 8));
+ }
+ }
+
+ QImage imageConverted = image.convertedToColorSpace(QColorSpace::DisplayP3, toFormat);
+ QCOMPARE(imageConverted.format(), toFormat);
+ QCOMPARE(imageConverted.size(), image.size());
+ if (dstGrayscale) {
+ int gray = 0;
+ for (int x = 0; x < image.width(); ++x) {
+ int newGray = qGray(imageConverted.pixel(x, 6));
+ QCOMPARE_GE(newGray, gray);
+ gray = newGray;
+ }
+ } else {
+ int red = 0;
+ int blue = 0;
+ for (int x = 0; x < image.width(); ++x) {
+ int newRed = qRed(imageConverted.pixel(x, 5));
+ int newBlue = qBlue(imageConverted.pixel(x, 7));
+ QCOMPARE_GE(newBlue, blue);
+ QCOMPARE_GE(newRed, red);
+ blue = newBlue;
+ red = newRed;
+ }
+ }
+}
+
+
+void tst_QImage::colorSpaceCmykConversion_data()
+{
+ QTest::addColumn<QImage::Format>("toFormat");
+
+ QImage::Format formats[] = {
+ QImage::Format_RGB32,
+ QImage::Format_ARGB32,
+ QImage::Format_ARGB32_Premultiplied,
+ QImage::Format_RGBX64,
+ QImage::Format_RGBA64,
+ QImage::Format_RGBA64_Premultiplied,
+ QImage::Format_RGBX32FPx4,
+ QImage::Format_RGBA32FPx4,
+ QImage::Format_RGBA32FPx4_Premultiplied,
+ QImage::Format_Grayscale8,
+ QImage::Format_Grayscale16,
+ };
+
+ for (auto toFormat : formats)
+ QTest::addRow("CMYK8888 -> %s", formatToString(toFormat).data()) << toFormat;
+}
+
+void tst_QImage::colorSpaceCmykConversion()
+{
+ QFETCH(QImage::Format, toFormat);
+
+ bool dstGrayscale = toFormat == QImage::Format_Grayscale8 || toFormat == QImage::Format_Grayscale16;
+
+ QImage image(16, 16, QImage::Format_CMYK8888);
+ QFile iccProfile(m_prefix +"CGATS001Compat-v2-micro.icc");
+ iccProfile.open(QIODevice::ReadOnly);
+ image.setColorSpace(QColorSpace::fromIccProfile(iccProfile.readAll()));
+ QVERIFY(image.colorSpace().isValid());
+
+ for (int i = 0; i < image.height(); ++i) {
+ for (int j = 0; j < image.width(); ++j) {
+ if (dstGrayscale)
+ image.setPixel(j, i, qRgb((i + j) * 8, (i + j) * 8, (i + j) * 8));
+ else
+ image.setPixel(j, i, qRgb(j * 16, i * 16, (i + j) * 8));
+ }
+ }
+
+ QImage imageConverted = image.convertedToColorSpace(QColorSpace::SRgb, toFormat);
+ QCOMPARE(imageConverted.format(), toFormat);
+ QCOMPARE(imageConverted.size(), image.size());
+ if (dstGrayscale) {
+ int gray = 0;
+ for (int x = 0; x < image.width(); ++x) {
+ int newGray = qGray(imageConverted.pixel(x, 6));
+ QCOMPARE_GE(newGray, gray);
+ gray = newGray;
+ }
+ } else {
+ int red = 0;
+ for (int x = 0; x < image.width(); ++x) {
+ int newRed = qRed(imageConverted.pixel(x, 5));
+ QCOMPARE_GE(newRed, red);
+ red = newRed;
+ }
+ }
+}
+
void tst_QImage::deepCopyWhenPaintingActive()
{
QImage image(64, 64, QImage::Format_ARGB32_Premultiplied);
@@ -3325,7 +3495,8 @@ void tst_QImage::invertPixelsRGB_data()
for (int i = QImage::Format_RGB32; i < QImage::NImageFormats; ++i) {
if (i == QImage::Format_Alpha8
|| i == QImage::Format_Grayscale8
- || i == QImage::Format_Grayscale16) {
+ || i == QImage::Format_Grayscale16
+ || i == QImage::Format_CMYK8888) {
continue;
}
QTest::addRow("%s", formatToString(QImage::Format(i)).data()) << QImage::Format(i);
@@ -3457,6 +3628,9 @@ void tst_QImage::exifInvalidData()
void tst_QImage::exifReadComments()
{
+#ifdef QT_NO_IMAGEIO_TEXT_LOADING
+ QSKIP("Reading text from image file is configured off");
+#endif
QImage image;
QVERIFY(image.load(m_prefix + "jpeg_exif_utf8_comment.jpg"));
QVERIFY(!image.isNull());
@@ -3850,7 +4024,7 @@ void tst_QImage::reinterpretAsFormat_data()
QTest::newRow("rgb32 -> argb32") << QImage::Format_RGB32 << QImage::Format_ARGB32 << QColor(Qt::cyan) << QColor(Qt::cyan);
QTest::newRow("argb32pm -> rgb32") << QImage::Format_ARGB32_Premultiplied << QImage::Format_RGB32 << QColor(Qt::transparent) << QColor(Qt::black);
QTest::newRow("argb32 -> rgb32") << QImage::Format_ARGB32 << QImage::Format_RGB32 << QColor(255, 0, 0, 127) << QColor(255, 0, 0);
- QTest::newRow("argb32pm -> rgb32") << QImage::Format_ARGB32_Premultiplied << QImage::Format_RGB32 << QColor(255, 0, 0, 127) << QColor(127, 0, 0);
+ QTest::newRow("argb32pm (red) -> rgb32") << QImage::Format_ARGB32_Premultiplied << QImage::Format_RGB32 << QColor(255, 0, 0, 127) << QColor(127, 0, 0);
}
void tst_QImage::reinterpretAsFormat()
@@ -3945,7 +4119,10 @@ void tst_QImage::hugeQImage()
#if Q_PROCESSOR_WORDSIZE < 8
QSKIP("Test only makes sense on 64-bit machines");
#else
- QImage image(25000, 25000, QImage::Format_RGB32);
+ std::unique_ptr<char[]> enough(new (std::nothrow) char[qsizetype(25000)*25000*4]);
+ if (!enough)
+ QSKIP("Could not allocate enough memory");
+ QImage image((uchar*)enough.get(), 25000, 25000, QImage::Format_RGB32);
QVERIFY(!image.isNull());
QCOMPARE(image.height(), 25000);
@@ -4059,6 +4236,34 @@ void tst_QImage::largeRasterScale()
// image.save("largeRasterScale.png", "PNG");
}
+void tst_QImage::metadataChangeWithReadOnlyPixels()
+{
+ const QRgb data[3] = { qRgb(255, 0, 0), qRgb(0, 255, 0), qRgb(0, 0, 255) };
+ QImage image((const uchar *)data, 3, 1, QImage::Format_RGB32);
+
+ QCOMPARE(image.constBits(), (const uchar *)data);
+ image.setDotsPerMeterX(100);
+ QCOMPARE(image.constBits(), (const uchar *)data);
+
+ QImage image2 = image;
+ QCOMPARE(image2.constBits(), (const uchar *)data);
+ image2.setDotsPerMeterX(200);
+ // Pixels and metadata has the same sharing mechanism, so a change of a shared
+ // image metadata forces pixel detach (remove this sub-test if that ever changes).
+ QVERIFY(image2.constBits() != (const uchar *)data);
+ QCOMPARE(image.constBits(), (const uchar *)data);
+}
+
+void tst_QImage::scaleIndexed()
+{
+ QImage image(10, 10, QImage::Format_Indexed8);
+ image.setColor(0, qRgb(0,0,0));
+ image.setColor(1, qRgb(1,1,1));
+ image.fill(1);
+ image.setDevicePixelRatio(2);
+ QImage image2 = image.scaled(20, 20, Qt::KeepAspectRatio, Qt::SmoothTransformation); // do not crash
+}
+
#if defined(Q_OS_WIN)
static inline QColor COLORREFToQColor(COLORREF cr)
@@ -4171,5 +4376,27 @@ void tst_QImage::fromMonoHBITMAP() // QTBUG-72343, corruption for mono bitmaps
#endif // Q_OS_WIN
+void tst_QImage::tofromPremultipliedFormat_data()
+{
+ QTest::addColumn<QImage::Format>("unpremul");
+ QTest::addColumn<QImage::Format>("premul");
+
+ // Test all available formats with both premultiplied and unpremultiplied versions
+ QTest::newRow("argb32") << QImage::Format_ARGB32 << QImage::Format_ARGB32_Premultiplied;
+ QTest::newRow("rgba8888") << QImage::Format_RGBA8888 << QImage::Format_RGBA8888_Premultiplied;
+ QTest::newRow("rgba64") << QImage::Format_RGBA64 << QImage::Format_RGBA64_Premultiplied;
+ QTest::newRow("rgba16fpx4") << QImage::Format_RGBA16FPx4 << QImage::Format_RGBA16FPx4_Premultiplied;
+ QTest::newRow("rgba32fpx4") << QImage::Format_RGBA32FPx4 << QImage::Format_RGBA32FPx4_Premultiplied;
+}
+
+void tst_QImage::tofromPremultipliedFormat()
+{
+ QFETCH(QImage::Format, unpremul);
+ QFETCH(QImage::Format, premul);
+
+ QCOMPARE(qt_toPremultipliedFormat(unpremul), premul);
+ QCOMPARE(qt_toUnpremultipliedFormat(premul), unpremul);
+}
+
QTEST_GUILESS_MAIN(tst_QImage)
#include "tst_qimage.moc"
diff --git a/tests/auto/gui/image/qimageiohandler/CMakeLists.txt b/tests/auto/gui/image/qimageiohandler/CMakeLists.txt
index 4bbf2f5b01..9fbd9c9b9f 100644
--- a/tests/auto/gui/image/qimageiohandler/CMakeLists.txt
+++ b/tests/auto/gui/image/qimageiohandler/CMakeLists.txt
@@ -1,12 +1,19 @@
-# Generated from qimageiohandler.pro.
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qimageiohandler Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qimageiohandler LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
qt_internal_add_test(tst_qimageiohandler
SOURCES
tst_qimageiohandler.cpp
- PUBLIC_LIBRARIES
+ LIBRARIES
Qt::Gui
)
diff --git a/tests/auto/gui/image/qimageiohandler/tst_qimageiohandler.cpp b/tests/auto/gui/image/qimageiohandler/tst_qimageiohandler.cpp
index 9fa0e37cad..bd325e185c 100644
--- a/tests/auto/gui/image/qimageiohandler/tst_qimageiohandler.cpp
+++ b/tests/auto/gui/image/qimageiohandler/tst_qimageiohandler.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QTest>
diff --git a/tests/auto/gui/image/qimagereader/BLACKLIST b/tests/auto/gui/image/qimagereader/BLACKLIST
new file mode 100644
index 0000000000..6422ff1dac
--- /dev/null
+++ b/tests/auto/gui/image/qimagereader/BLACKLIST
@@ -0,0 +1,8 @@
+[setClipRect:SVG: rect]
+wayland
+[setClipRect:SVGZ: rect]
+wayland
+[setScaledClipRect:SVG: rect]
+wayland
+[setScaledClipRect:SVGZ: rect]
+wayland
diff --git a/tests/auto/gui/image/qimagereader/CMakeLists.txt b/tests/auto/gui/image/qimagereader/CMakeLists.txt
index a0cda3bb73..2a14ca3c9c 100644
--- a/tests/auto/gui/image/qimagereader/CMakeLists.txt
+++ b/tests/auto/gui/image/qimagereader/CMakeLists.txt
@@ -1,9 +1,16 @@
-# Generated from qimagereader.pro.
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qimagereader Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qimagereader LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
# Collect test data
file(GLOB_RECURSE test_data_glob
RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
@@ -17,7 +24,7 @@ list(APPEND test_data ${test_data_glob})
qt_internal_add_test(tst_qimagereader
SOURCES
tst_qimagereader.cpp
- PUBLIC_LIBRARIES
+ LIBRARIES
Qt::CorePrivate
Qt::Gui
Qt::GuiPrivate
@@ -42,24 +49,3 @@ qt_internal_add_resource(tst_qimagereader "qmake_immediate"
${qmake_immediate_resource_files}
)
-
-#### Keys ignored in scope 1:.:.:qimagereader.pro:<TRUE>:
-# MOC_DIR = "tmp"
-
-## Scopes:
-#####################################################################
-
-if(ANDROID)
- # Resources:
- set(android_testdata_resource_files
- "images/kollada-noext"
- "images/trans.gif"
- )
-
- qt_internal_add_resource(tst_qimagereader "android_testdata"
- PREFIX
- "/"
- FILES
- ${android_testdata_resource_files}
- )
-endif()
diff --git a/tests/auto/gui/image/qimagereader/images/image.pbm b/tests/auto/gui/image/qimagereader/images/image.pbm
index 67e5efa3e9..e529536ca4 100644
--- a/tests/auto/gui/image/qimagereader/images/image.pbm
+++ b/tests/auto/gui/image/qimagereader/images/image.pbm
@@ -1,8 +1,8 @@
P1
16 6
1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1
-1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1
-1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1
-1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1
-1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1
-1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1
+10 00 00 00 01 00 00 01
+1000 0000 0100 0001
+100000000 1000001
+1000000001000001
+10 000 0000 10000 01
diff --git a/tests/auto/gui/image/qimagereader/tst_qimagereader.cpp b/tests/auto/gui/image/qimagereader/tst_qimagereader.cpp
index 3191f9f06b..96af8b4e9b 100644
--- a/tests/auto/gui/image/qimagereader/tst_qimagereader.cpp
+++ b/tests/auto/gui/image/qimagereader/tst_qimagereader.cpp
@@ -1,31 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QTest>
@@ -36,7 +10,7 @@
#include <QImageReader>
#include <QImageWriter>
#include <QPixmap>
-#include <QSet>
+#include <QScopeGuard>
#include <QTcpSocket>
#include <QTcpServer>
#include <QTimer>
@@ -88,12 +62,17 @@ private slots:
void setScaledSize_data();
void setScaledSize();
+ void setScaledSizeOneDimension_data();
+ void setScaledSizeOneDimension();
+
void setClipRect_data();
void setClipRect();
void setScaledClipRect_data();
void setScaledClipRect();
+ void setFormat();
+
void imageFormat_data();
void imageFormat();
@@ -324,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)));
}
}
}
@@ -395,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();
@@ -510,9 +570,38 @@ void tst_QImageReader::setScaledClipRect()
QImageReader originalReader(prefix + fileName);
originalReader.setScaledSize(QSize(300, 300));
QImage originalImage = originalReader.read();
+ if (format.contains("svg")) {
+ // rendering of subrect may yield slight rounding differences, truncate them away
+ image.convertTo(QImage::Format_RGB444);
+ originalImage.convertTo(QImage::Format_RGB444);
+ }
QCOMPARE(originalImage.copy(newRect), image);
}
+void tst_QImageReader::setFormat()
+{
+ QByteArray ppmImage = "P1 2 2\n1 0\n0 1";
+ QBuffer buf(&ppmImage);
+ QImageReader reader(&buf);
+
+ // read image in autodetected format
+ QCOMPARE(reader.size(), QSize(2,2));
+ buf.close();
+
+ // try reading with non-matching format, must not succeed
+ reader.setDecideFormatFromContent(false);
+ reader.setFormat("bmp");
+ reader.setDevice(&buf);
+ QCOMPARE(reader.size(), QSize());
+ buf.close();
+
+ // read with manually set matching format
+ reader.setFormat("ppm");
+ reader.setDevice(&buf);
+ QCOMPARE(reader.size(), QSize(2,2));
+ buf.close();
+}
+
void tst_QImageReader::imageFormat_data()
{
QTest::addColumn<QString>("fileName");
@@ -527,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;
@@ -588,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()
@@ -667,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;
@@ -1617,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()
@@ -1822,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;
@@ -1978,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
}
}
diff --git a/tests/auto/gui/image/qimagewriter/CMakeLists.txt b/tests/auto/gui/image/qimagewriter/CMakeLists.txt
index e74321731f..06273ce7e4 100644
--- a/tests/auto/gui/image/qimagewriter/CMakeLists.txt
+++ b/tests/auto/gui/image/qimagewriter/CMakeLists.txt
@@ -1,9 +1,16 @@
-# Generated from qimagewriter.pro.
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qimagewriter Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qimagewriter LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
# Collect test data
file(GLOB_RECURSE test_data_glob
RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
@@ -13,38 +20,8 @@ list(APPEND test_data ${test_data_glob})
qt_internal_add_test(tst_qimagewriter
SOURCES
tst_qimagewriter.cpp
- PUBLIC_LIBRARIES
+ LIBRARIES
Qt::Gui
TESTDATA ${test_data}
)
-#### Keys ignored in scope 1:.:.:qimagewriter.pro:<TRUE>:
-# MOC_DIR = "tmp"
-
-## Scopes:
-#####################################################################
-
-if(ANDROID)
- # Resources:
- set(qimagewriter_resource_files
- "images/YCbCr_cmyk.jpg"
- "images/YCbCr_rgb.jpg"
- "images/beavis.jpg"
- "images/colorful.bmp"
- "images/earth.gif"
- "images/font.bmp"
- "images/gnus.xbm"
- "images/kollada.png"
- "images/marble.xpm"
- "images/ship63.pbm"
- "images/teapot.ppm"
- "images/trolltech.gif"
- )
-
- qt_internal_add_resource(tst_qimagewriter "qimagewriter"
- PREFIX
- "/"
- FILES
- ${qimagewriter_resource_files}
- )
-endif()
diff --git a/tests/auto/gui/image/qimagewriter/tst_qimagewriter.cpp b/tests/auto/gui/image/qimagewriter/tst_qimagewriter.cpp
index 2f3c744fd9..1059cc48ab 100644
--- a/tests/auto/gui/image/qimagewriter/tst_qimagewriter.cpp
+++ b/tests/auto/gui/image/qimagewriter/tst_qimagewriter.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QTest>
#include <QDebug>
@@ -127,7 +102,7 @@ void tst_QImageWriter::getSetCheck()
QCOMPARE((QIODevice *) var1, obj1.device());
// The class should possibly handle a 0-pointer as a device, since
- // there is a default contructor, so it's "handling" a 0 device by default.
+ // there is a default constructor, so it's "handling" a 0 device by default.
// For example: QMovie::setDevice(0) works just fine
obj1.setDevice((QIODevice *)0);
QCOMPARE((QIODevice *) 0, obj1.device());
diff --git a/tests/auto/gui/image/qmovie/CMakeLists.txt b/tests/auto/gui/image/qmovie/CMakeLists.txt
index 545ee481d1..52e0a347c4 100644
--- a/tests/auto/gui/image/qmovie/CMakeLists.txt
+++ b/tests/auto/gui/image/qmovie/CMakeLists.txt
@@ -1,20 +1,28 @@
-# Generated from qmovie.pro.
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qmovie Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qmovie LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
# Collect test data
file(GLOB_RECURSE test_data_glob
RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
- animations/*)
+ animations/* multiframe/*)
list(APPEND test_data ${test_data_glob})
qt_internal_add_test(tst_qmovie
SOURCES
tst_qmovie.cpp
- PUBLIC_LIBRARIES
+ LIBRARIES
Qt::Gui
+ Qt::TestPrivate
TESTDATA ${test_data}
)
@@ -23,6 +31,7 @@ set(resources_resource_files
"animations/comicsecard.gif"
"animations/corrupt.gif"
"animations/trolltech.gif"
+ "multiframe/Obj_N2_Internal_Mem.ico"
)
qt_internal_add_resource(tst_qmovie "resources"
@@ -32,16 +41,11 @@ qt_internal_add_resource(tst_qmovie "resources"
${resources_resource_files}
)
-
-#### Keys ignored in scope 1:.:.:qmovie.pro:<TRUE>:
-# MOC_DIR = "tmp"
-# QT_FOR_CONFIG = "gui-private"
-
## Scopes:
#####################################################################
qt_internal_extend_target(tst_qmovie CONDITION TARGET Qt::Widgets
- PUBLIC_LIBRARIES
+ LIBRARIES
Qt::Widgets
)
diff --git a/tests/auto/gui/image/qmovie/multiframe/Obj_N2_Internal_Mem.ico b/tests/auto/gui/image/qmovie/multiframe/Obj_N2_Internal_Mem.ico
new file mode 100644
index 0000000000..8da119efdd
--- /dev/null
+++ b/tests/auto/gui/image/qmovie/multiframe/Obj_N2_Internal_Mem.ico
Binary files differ
diff --git a/tests/auto/gui/image/qmovie/tst_qmovie.cpp b/tests/auto/gui/image/qmovie/tst_qmovie.cpp
index 11592ffc2a..29c3297043 100644
--- a/tests/auto/gui/image/qmovie/tst_qmovie.cpp
+++ b/tests/auto/gui/image/qmovie/tst_qmovie.cpp
@@ -1,35 +1,11 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QTest>
#include <QTestEventLoop>
#include <QSignalSpy>
+#include <QtTest/private/qpropertytesthelper_p.h>
#include <QIODevice>
#ifndef QT_NO_WIDGETS
@@ -60,12 +36,20 @@ private slots:
void playMovie();
void jumpToFrame_data();
void jumpToFrame();
+ void frameDelay();
void changeMovieFile();
#ifndef QT_NO_WIDGETS
void infiniteLoop();
#endif
void emptyMovie();
void bindings();
+ void automatedBindings();
+#ifndef QT_NO_ICO
+ void multiFrameImage();
+#endif
+
+ void setScaledSize_data();
+ void setScaledSize();
};
// Testing get/set functions
@@ -181,7 +165,7 @@ void tst_QMovie::playMovie()
movie.start();
QCOMPARE(movie.state(), QMovie::Running);
QTestEventLoop::instance().enterLoop(2);
- QCOMPARE(finishedSpy.count(), 0);
+ QCOMPARE(finishedSpy.size(), 0);
QCOMPARE(movie.state(), QMovie::Running);
QCOMPARE(movie.currentFrameNumber(), 0);
}
@@ -201,6 +185,17 @@ void tst_QMovie::jumpToFrame()
QCOMPARE(movie.currentFrameNumber(), 0);
}
+void tst_QMovie::frameDelay()
+{
+ QMovie movie(QFINDTESTDATA("animations/comicsecard.gif"));
+ QList<int> frameDelays{ 200, 800, 800, 2000, 2600 };
+ for (int i = 0; i < movie.frameCount(); i++) {
+ movie.jumpToFrame(i);
+ // Processing may have taken a little time, so round to nearest 100ms
+ QCOMPARE(100 * qRound(movie.nextFrameDelay() / 100.0f), frameDelays[i]);
+ }
+}
+
void tst_QMovie::changeMovieFile()
{
QMovie movie(QFINDTESTDATA("animations/comicsecard.gif"));
@@ -264,5 +259,78 @@ void tst_QMovie::bindings()
QCOMPARE(cacheModeObserver, QMovie::CacheAll);
}
+void tst_QMovie::automatedBindings()
+{
+ QMovie movie;
+
+ QTestPrivate::testReadWritePropertyBasics(movie, 50, 100, "speed");
+ if (QTest::currentTestFailed()) {
+ qDebug("Failed property test for QMovie::speed");
+ return;
+ }
+
+ QTestPrivate::testReadWritePropertyBasics(movie, QMovie::CacheAll, QMovie::CacheNone,
+ "cacheMode");
+ if (QTest::currentTestFailed()) {
+ qDebug("Failed property test for QMovie::cacheMode");
+ return;
+ }
+}
+
+#ifndef QT_NO_ICO
+/*! \internal
+ Test behavior of QMovie with image formats that are multi-frame,
+ but not normally intended as animation formats (such as tiff and ico).
+*/
+void tst_QMovie::multiFrameImage()
+{
+ QMovie movie(QFINDTESTDATA("multiframe/Obj_N2_Internal_Mem.ico"));
+ const int expectedFrameCount = 9;
+
+ QCOMPARE(movie.frameCount(), expectedFrameCount);
+ QVERIFY(movie.isValid());
+ movie.setSpeed(1000); // speed up the test: play at 10 FPS (1000% of normal)
+ QElapsedTimer playTimer;
+ QSignalSpy frameChangedSpy(&movie, &QMovie::frameChanged);
+ QSignalSpy errorSpy(&movie, &QMovie::error);
+ QSignalSpy finishedSpy(&movie, &QMovie::finished);
+ playTimer.start();
+ movie.start();
+ QTRY_COMPARE(finishedSpy.size(), 1);
+ QCOMPARE_GE(playTimer.elapsed(), 100 * expectedFrameCount);
+ QCOMPARE(movie.nextFrameDelay(), 100);
+ QCOMPARE(errorSpy.size(), 0);
+ QCOMPARE(frameChangedSpy.size(), expectedFrameCount);
+}
+#endif
+
+void tst_QMovie::setScaledSize_data()
+{
+ QTest::addColumn<QString>("fileName");
+ QTest::addColumn<QSize>("scaledSize");
+ QTest::addColumn<QSize>("expectedSize");
+
+ QTest::newRow("trolltech (50, 50)") << QString("animations/trolltech.gif") << QSize(50, 50) << QSize(50, 50);
+ QTest::newRow("trolltech (400, 400)") << QString("animations/trolltech.gif") << QSize(400, 400) << QSize(400, 400);
+ QTest::newRow("trolltech (50, 0)") << QString("animations/trolltech.gif") << QSize(50, 0) << QSize(50, 25);
+ QTest::newRow("trolltech (50, -1)") << QString("animations/trolltech.gif") << QSize(50, -1) << QSize(50, 25);
+ QTest::newRow("trolltech (0, 50)") << QString("animations/trolltech.gif") << QSize(0, 50) << QSize(100, 50);
+ QTest::newRow("trolltech (-1, 50)") << QString("animations/trolltech.gif") << QSize(-1, 50) << QSize(100, 50);
+}
+
+void tst_QMovie::setScaledSize()
+{
+ QFETCH(QString, fileName);
+ QFETCH(QSize, scaledSize);
+ QFETCH(QSize, expectedSize);
+
+ QMovie movie(QFINDTESTDATA(fileName));
+ movie.setScaledSize(scaledSize);
+
+ movie.start();
+ QCOMPARE(movie.currentFrameNumber(), 0);
+ QCOMPARE(movie.currentImage().size(), expectedSize);
+}
+
QTEST_MAIN(tst_QMovie)
#include "tst_qmovie.moc"
diff --git a/tests/auto/gui/image/qpicture/CMakeLists.txt b/tests/auto/gui/image/qpicture/CMakeLists.txt
index 29bf68fa06..30b0aafd11 100644
--- a/tests/auto/gui/image/qpicture/CMakeLists.txt
+++ b/tests/auto/gui/image/qpicture/CMakeLists.txt
@@ -1,12 +1,19 @@
-# Generated from qpicture.pro.
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qpicture Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qpicture LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
qt_internal_add_test(tst_qpicture
SOURCES
tst_qpicture.cpp
- PUBLIC_LIBRARIES
+ LIBRARIES
Qt::Gui
)
diff --git a/tests/auto/gui/image/qpicture/tst_qpicture.cpp b/tests/auto/gui/image/qpicture/tst_qpicture.cpp
index 25e284a6ec..2fa4436154 100644
--- a/tests/auto/gui/image/qpicture/tst_qpicture.cpp
+++ b/tests/auto/gui/image/qpicture/tst_qpicture.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QTest>
diff --git a/tests/auto/gui/image/qpixmap/CMakeLists.txt b/tests/auto/gui/image/qpixmap/CMakeLists.txt
index 1946715047..8531ef5b7b 100644
--- a/tests/auto/gui/image/qpixmap/CMakeLists.txt
+++ b/tests/auto/gui/image/qpixmap/CMakeLists.txt
@@ -1,9 +1,16 @@
-# Generated from qpixmap.pro.
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qpixmap Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qpixmap LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
# Collect test data
file(GLOB_RECURSE test_data_glob
RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
@@ -25,7 +32,7 @@ list(APPEND test_data ${test_data_glob})
qt_internal_add_test(tst_qpixmap
SOURCES
tst_qpixmap.cpp
- PUBLIC_LIBRARIES
+ LIBRARIES
Qt::CorePrivate
Qt::Gui
Qt::GuiPrivate
@@ -95,13 +102,13 @@ qt_internal_add_resource(tst_qpixmap "qpixmap"
#####################################################################
qt_internal_extend_target(tst_qpixmap CONDITION TARGET Qt::Widgets
- PUBLIC_LIBRARIES
+ LIBRARIES
Qt::Widgets
Qt::WidgetsPrivate
)
qt_internal_extend_target(tst_qpixmap CONDITION WIN32
- PUBLIC_LIBRARIES
+ LIBRARIES
gdi32
user32
)
diff --git a/tests/auto/gui/image/qpixmap/tst_qpixmap.cpp b/tests/auto/gui/image/qpixmap/tst_qpixmap.cpp
index 69f6796bbb..137439d98b 100644
--- a/tests/auto/gui/image/qpixmap/tst_qpixmap.cpp
+++ b/tests/auto/gui/image/qpixmap/tst_qpixmap.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QSet>
#include <QTemporaryFile>
@@ -1448,7 +1423,7 @@ void tst_QPixmap::loadFromDataImage()
QPixmap pixmapWithCopy = QPixmap::fromImage(imageRef);
QFile file(imagePath);
- file.open(QIODevice::ReadOnly);
+ QVERIFY(file.open(QIODevice::ReadOnly));
QByteArray rawData = file.readAll();
QPixmap directLoadingPixmap;
diff --git a/tests/auto/gui/image/qpixmapcache/CMakeLists.txt b/tests/auto/gui/image/qpixmapcache/CMakeLists.txt
index 9e99842e6e..444de9cb3e 100644
--- a/tests/auto/gui/image/qpixmapcache/CMakeLists.txt
+++ b/tests/auto/gui/image/qpixmapcache/CMakeLists.txt
@@ -1,13 +1,20 @@
-# Generated from qpixmapcache.pro.
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qpixmapcache Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qpixmapcache LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
qt_internal_add_test(tst_qpixmapcache
SOURCES
tst_qpixmapcache.cpp
- PUBLIC_LIBRARIES
+ LIBRARIES
Qt::Gui
Qt::GuiPrivate
)
diff --git a/tests/auto/gui/image/qpixmapcache/tst_qpixmapcache.cpp b/tests/auto/gui/image/qpixmapcache/tst_qpixmapcache.cpp
index a87ec5d025..8384a46491 100644
--- a/tests/auto/gui/image/qpixmapcache/tst_qpixmapcache.cpp
+++ b/tests/auto/gui/image/qpixmapcache/tst_qpixmapcache.cpp
@@ -1,32 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#define Q_TEST_QPIXMAPCACHE
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QTest>
@@ -34,6 +7,16 @@
#include <qpixmapcache.h>
#include "private/qpixmapcache_p.h"
+#include <functional>
+
+QT_BEGIN_NAMESPACE // The test requires QT_BUILD_INTERNAL
+Q_AUTOTEST_EXPORT void qt_qpixmapcache_flush_detached_pixmaps();
+Q_AUTOTEST_EXPORT int qt_qpixmapcache_qpixmapcache_total_used();
+Q_AUTOTEST_EXPORT int q_QPixmapCache_keyHashSize();
+QT_END_NAMESPACE
+
+using namespace Qt::StringLiterals;
+
class tst_QPixmapCache : public QObject
{
Q_OBJECT
@@ -50,13 +33,22 @@ private slots:
void setCacheLimit();
void find();
void insert();
+ void failedInsertReturnsInvalidKey();
+#if QT_DEPRECATED_SINCE(6, 6)
void replace();
+#endif
void remove();
void clear();
void pixmapKey();
void noLeak();
+ void clearDoesNotLeakStringKeys();
+ void evictionDoesNotLeakStringKeys();
+ void reducingCacheLimitDoesNotLeakStringKeys();
void strictCacheLimit();
void noCrashOnLargeInsert();
+
+private:
+ void stringLeak_impl(std::function<void()> whenOp);
};
static QPixmapCache::KeyData* getPrivate(QPixmapCache::Key &key)
@@ -123,28 +115,32 @@ void tst_QPixmapCache::setCacheLimit()
//The int part of the API
p1 = new QPixmap(2, 3);
QPixmapCache::Key key = QPixmapCache::insert(*p1);
- QVERIFY(QPixmapCache::find(key, p1) != 0);
+ QVERIFY(QPixmapCache::find(key, p1));
delete p1;
QPixmapCache::setCacheLimit(0);
- QVERIFY(QPixmapCache::find(key, p1) == 0);
+ QVERIFY(!QPixmapCache::find(key, p1));
- p1 = new QPixmap(2, 3);
QPixmapCache::setCacheLimit(1000);
- QPixmapCache::replace(key, *p1);
- QVERIFY(QPixmapCache::find(key, p1) == 0);
+#if QT_DEPRECATED_SINCE(6, 6)
+ QT_WARNING_PUSH
+ QT_WARNING_DISABLE_DEPRECATED
+ p1 = new QPixmap(2, 3);
+ QVERIFY(!QPixmapCache::replace(key, *p1));
+ QVERIFY(!QPixmapCache::find(key, p1));
delete p1;
+#endif // QT_DEPRECATED_SINCE(6, 6)
//Let check if keys are released when the pixmap cache is
//full or has been flushed.
QPixmapCache::clear();
p1 = new QPixmap(2, 3);
key = QPixmapCache::insert(*p1);
- QVERIFY(QPixmapCache::find(key, p1) != 0);
+ QVERIFY(QPixmapCache::find(key, p1));
p1->detach(); // dectach so that the cache thinks no-one is using it.
QPixmapCache::setCacheLimit(0);
- QVERIFY(QPixmapCache::find(key, p1) == 0);
+ QVERIFY(!QPixmapCache::find(key, p1));
QPixmapCache::setCacheLimit(1000);
key = QPixmapCache::insert(*p1);
QVERIFY(key.isValid());
@@ -158,7 +154,7 @@ void tst_QPixmapCache::setCacheLimit()
QPixmap p2;
p1 = new QPixmap(2, 3);
key = QPixmapCache::insert(*p1);
- QVERIFY(QPixmapCache::find(key, &p2) != 0);
+ QVERIFY(QPixmapCache::find(key, &p2));
//we flush the cache
p1->detach();
p2.detach();
@@ -166,8 +162,8 @@ void tst_QPixmapCache::setCacheLimit()
QPixmapCache::setCacheLimit(1000);
QPixmapCache::Key key2 = QPixmapCache::insert(*p1);
QCOMPARE(getPrivate(key2)->key, 1);
- QVERIFY(QPixmapCache::find(key, &p2) == 0);
- QVERIFY(QPixmapCache::find(key2, &p2) != 0);
+ QVERIFY(!QPixmapCache::find(key, &p2));
+ QVERIFY(QPixmapCache::find(key2, &p2));
QCOMPARE(p2, *p1);
delete p1;
@@ -185,12 +181,12 @@ void tst_QPixmapCache::setCacheLimit()
p1->detach();
QPixmapCache::Key key3 = QPixmapCache::insert(*p1);
p1->detach();
- QPixmapCache::flushDetachedPixmaps();
+ qt_qpixmapcache_flush_detached_pixmaps();
key2 = QPixmapCache::insert(*p1);
QCOMPARE(getPrivate(key2)->key, 1);
//This old key is not valid anymore after the flush
QVERIFY(!key.isValid());
- QVERIFY(QPixmapCache::find(key, &p2) == 0);
+ QVERIFY(!QPixmapCache::find(key, &p2));
delete p1;
}
@@ -228,7 +224,7 @@ void tst_QPixmapCache::find()
QPixmapCache::insert(p5);
//at that time the first key has been erase because no more place in the cache
- QVERIFY(QPixmapCache::find(key, &p1) == 0);
+ QVERIFY(!QPixmapCache::find(key, &p1));
QVERIFY(!key.isValid());
}
@@ -287,6 +283,7 @@ void tst_QPixmapCache::insert()
for (int i = 0; i < numberOfKeys; ++i) {
QPixmap p3(10,10);
keys.append(QPixmapCache::insert(p3));
+ QVERIFY(keys.back().isValid());
}
num = 0;
@@ -300,6 +297,35 @@ void tst_QPixmapCache::insert()
QVERIFY(num <= estimatedNum);
}
+void tst_QPixmapCache::failedInsertReturnsInvalidKey()
+{
+ //
+ // GIVEN: a pixmap whose memory footprint exceeds the cache's limit:
+ //
+ QPixmapCache::setCacheLimit(20);
+
+ QPixmap pm(256, 256);
+ pm.fill(Qt::transparent);
+ QCOMPARE_GT(pm.width() * pm.height() * pm.depth() / 8,
+ QPixmapCache::cacheLimit() * 1024);
+
+ //
+ // WHEN: trying to add this pixmap to the cache
+ //
+ const auto success = QPixmapCache::insert(u"foo"_s, pm); // QString API
+ { QPixmap r; QVERIFY(!QPixmapCache::find(u"foo"_s, &r)); }
+ const auto key = QPixmapCache::insert(pm); // "int" API
+
+ //
+ // THEN: failure is reported to the user
+ //
+ QVERIFY(!key.isValid()); // "int" API
+ QVERIFY(!success); // QString API
+}
+
+#if QT_DEPRECATED_SINCE(6, 6)
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_DEPRECATED
void tst_QPixmapCache::replace()
{
//The int part of the API
@@ -328,6 +354,8 @@ void tst_QPixmapCache::replace()
//Broken keys
QCOMPARE(QPixmapCache::replace(QPixmapCache::Key(), p2), false);
}
+QT_WARNING_POP
+#endif // QT_DEPRECATED_SINCE(6, 6)
void tst_QPixmapCache::remove()
{
@@ -361,11 +389,11 @@ void tst_QPixmapCache::remove()
QVERIFY(p1.toImage() == p1.toImage()); // sanity check
QPixmapCache::remove(key);
- QVERIFY(QPixmapCache::find(key, &p1) == 0);
+ QVERIFY(!QPixmapCache::find(key, &p1));
//Broken key
QPixmapCache::remove(QPixmapCache::Key());
- QVERIFY(QPixmapCache::find(QPixmapCache::Key(), &p1) == 0);
+ QVERIFY(!QPixmapCache::find(QPixmapCache::Key(), &p1));
//Test if keys are release
QPixmapCache::clear();
@@ -379,7 +407,7 @@ void tst_QPixmapCache::remove()
QPixmapCache::clear();
key = QPixmapCache::insert(p1);
QCOMPARE(getPrivate(key)->key, 1);
- QVERIFY(QPixmapCache::find(key, &p1) != 0);
+ QVERIFY(QPixmapCache::find(key, &p1));
QPixmapCache::remove(key);
QCOMPARE(p1.isDetached(), true);
@@ -389,8 +417,8 @@ void tst_QPixmapCache::remove()
QPixmapCache::insert("red", p1);
key = QPixmapCache::insert(p1);
QPixmapCache::remove(key);
- QVERIFY(QPixmapCache::find(key, &p1) == 0);
- QVERIFY(QPixmapCache::find("red", &p1) != 0);
+ QVERIFY(!QPixmapCache::find(key, &p1));
+ QVERIFY(QPixmapCache::find("red", &p1));
}
void tst_QPixmapCache::clear()
@@ -434,7 +462,7 @@ void tst_QPixmapCache::clear()
QPixmapCache::clear();
for (int k = 0; k < numberOfKeys; ++k) {
- QVERIFY(QPixmapCache::find(keys.at(k), &p1) == 0);
+ QVERIFY(!QPixmapCache::find(keys.at(k), &p1));
QVERIFY(!keys[k].isValid());
}
}
@@ -483,10 +511,6 @@ void tst_QPixmapCache::pixmapKey()
QVERIFY(!getPrivate(key8));
}
-QT_BEGIN_NAMESPACE
-extern int q_QPixmapCache_keyHashSize();
-QT_END_NAMESPACE
-
void tst_QPixmapCache::noLeak()
{
QPixmapCache::Key key;
@@ -503,6 +527,68 @@ void tst_QPixmapCache::noLeak()
QCOMPARE(oldSize, newSize);
}
+void tst_QPixmapCache::clearDoesNotLeakStringKeys()
+{
+ stringLeak_impl([] { QPixmapCache::clear(); });
+}
+
+void tst_QPixmapCache::evictionDoesNotLeakStringKeys()
+{
+ stringLeak_impl([] {
+ // fill the cache with other pixmaps to force eviction of "our" pixmap:
+ constexpr int Iterations = 10;
+ for (int i = 0; i < Iterations; ++i) {
+ QPixmap pm(64, 64);
+ pm.fill(Qt::transparent);
+ [[maybe_unused]] auto r = QPixmapCache::insert(pm);
+ }
+ });
+}
+
+void tst_QPixmapCache::reducingCacheLimitDoesNotLeakStringKeys()
+{
+ stringLeak_impl([] {
+ QPixmapCache::setCacheLimit(0);
+ });
+}
+
+void tst_QPixmapCache::stringLeak_impl(std::function<void()> whenOp)
+{
+ QVERIFY(whenOp);
+
+ QPixmapCache::setCacheLimit(20); // 20KiB
+ //
+ // GIVEN: a QPixmap with QString key `key` in QPixmapCache
+ //
+ QString key;
+ {
+ QPixmap pm(64, 64);
+ QCOMPARE_LT(pm.width() * pm.height() * std::ceil(pm.depth() / 8.0),
+ QPixmapCache::cacheLimit() * 1024);
+ pm.fill(Qt::transparent);
+ key = u"theKey"_s.repeated(20); // avoid eventual QString SSO
+ QVERIFY(key.isDetached());
+ QPixmapCache::insert(key, pm);
+ }
+ QVERIFY(!key.isDetached()); // was saved inside QPixmapCache
+
+ //
+ // WHEN: performing the given operation
+ //
+ whenOp();
+ if (QTest::currentTestFailed())
+ return;
+
+ //
+ // THEN: `key` is no longer referenced by QPixmapCache:
+ //
+ QVERIFY(key.isDetached());
+ // verify that the pixmap is really gone from the cache
+ // (do it after the key check, because QPixmapCache cleans up `key` on a failed lookup)
+ QPixmap r;
+ QVERIFY(!QPixmapCache::find(key, &r));
+}
+
void tst_QPixmapCache::strictCacheLimit()
{
@@ -524,7 +610,7 @@ void tst_QPixmapCache::strictCacheLimit()
QPixmapCache::insert(id + "-b", pixmap);
}
- QVERIFY(QPixmapCache::totalUsed() <= limit);
+ QVERIFY(qt_qpixmapcache_qpixmapcache_total_used() <= limit);
}
void tst_QPixmapCache::noCrashOnLargeInsert()