summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShawn Rutledge <[email protected]>2023-10-11 21:41:53 +0200
committerQt Cherry-pick Bot <[email protected]>2024-02-11 21:16:01 +0000
commit5b171e557d8ee22695b366eaf54167eca19c3c29 (patch)
tree6161d824043b5f7a439a9f831bde86f650572bbe
parent3cfce6a00044a637db4fc4ceb4f7df4988739d5d (diff)
QtIcoHandler::canRead(): avoid checking more than once
QtIcoHandler::canRead() calls ICOReader::canRead(), which assumes that QIODevice::pos() is at the position where the .ico data starts (i.e. pos() == 0 if this is a separate .ico file). But if an AnimatedImage in Qt Quick opens an .ico file, canRead() gets called multiple times: the first is when QQuickAnimatedImage::frameCount() eventually results in QImageReaderPrivate::initHandler(); then ICOReader::readHeader() is called, which moves the file position. The second time is when QQuickAnimatedImage calls QMovie::isValid(). At that time, QIODevice::pos() == 6: we need to avoid calling ICOReader::canRead() because it's no longer at the start of the data. Without this change, AnimatedImage reports "Error Reading Animated Image File" and doesn't show anything. The fix is to store the known-good state, the same way that QTiffHandler::canRead() returns true if its d->tiff already exists (TIFFClientOpen() succeeded). The test checks that it's ok to call QMovie::frameCount() first and then QMovie::isValid(). Calling frameCount() has the effect of moving QIODevice::pos(). Task-number: QTBUG-117429 Change-Id: Ie3a5225f2cea9a0d76d685e83ce4d4a10cbe9188 Reviewed-by: Eirik Aavitsland <[email protected]> Reviewed-by: Qt CI Bot <[email protected]> (cherry picked from commit 3f515fa7aff7cb24565f0bb61b16bb2bde6faf60) Reviewed-by: Qt Cherry-pick Bot <[email protected]> (cherry picked from commit dc314851e70a4302d2988aa0e07aeaae19dec990) (cherry picked from commit 1fb0a119ab60ebeb41d8825979f7e93ae185e8a9)
-rw-r--r--src/plugins/imageformats/ico/qicohandler.cpp3
-rw-r--r--src/plugins/imageformats/ico/qicohandler.h2
-rw-r--r--tests/auto/gui/image/qmovie/tst_qmovie.cpp2
3 files changed, 5 insertions, 2 deletions
diff --git a/src/plugins/imageformats/ico/qicohandler.cpp b/src/plugins/imageformats/ico/qicohandler.cpp
index ab89509ca13..be247e901a0 100644
--- a/src/plugins/imageformats/ico/qicohandler.cpp
+++ b/src/plugins/imageformats/ico/qicohandler.cpp
@@ -735,6 +735,8 @@ bool QtIcoHandler::supportsOption(ImageOption option) const
*/
bool QtIcoHandler::canRead() const
{
+ if (knownCanRead)
+ return true;
bool bCanRead = false;
QIODevice *device = QImageIOHandler::device();
if (device) {
@@ -744,6 +746,7 @@ bool QtIcoHandler::canRead() const
} else {
qCWarning(lcIco, "QtIcoHandler::canRead() called with no device");
}
+ knownCanRead = bCanRead;
return bCanRead;
}
diff --git a/src/plugins/imageformats/ico/qicohandler.h b/src/plugins/imageformats/ico/qicohandler.h
index 859842ce277..bcea92bd937 100644
--- a/src/plugins/imageformats/ico/qicohandler.h
+++ b/src/plugins/imageformats/ico/qicohandler.h
@@ -30,7 +30,7 @@ public:
private:
int m_currentIconIndex;
ICOReader *m_pICOReader;
-
+ mutable bool knownCanRead = false;
};
QT_END_NAMESPACE
diff --git a/tests/auto/gui/image/qmovie/tst_qmovie.cpp b/tests/auto/gui/image/qmovie/tst_qmovie.cpp
index 4e30fe95d40..13014e04daa 100644
--- a/tests/auto/gui/image/qmovie/tst_qmovie.cpp
+++ b/tests/auto/gui/image/qmovie/tst_qmovie.cpp
@@ -272,8 +272,8 @@ void tst_QMovie::multiFrameImage()
QMovie movie(QFINDTESTDATA("multiframe/Obj_N2_Internal_Mem.ico"));
const int expectedFrameCount = 9;
- QVERIFY(movie.isValid());
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);