Skip to content

Commit

Permalink
QMovie: fix regression in frame delays
Browse files Browse the repository at this point in the history
The recent addition of support for multi-frame (non-animation) formats
had an unwanted side effect of sometimes calling
QImageReader::nextImageDelay() when the reader is at a different
frame than intended. Fix by effectively reverting to the previous call
pattern.

Fixes: QTBUG-124227
Pick-to: 6.7 6.5
Change-Id: I735f8d67afb17bd4c77f9b4507a71796b7d66958
Reviewed-by: Paul Olav Tvete <[email protected]>
  • Loading branch information
aavit committed Apr 24, 2024
1 parent 1758396 commit 5f0ed0a
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 3 deletions.
6 changes: 3 additions & 3 deletions src/gui/image/qmovie.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -319,7 +319,7 @@ QFrameInfo QMoviePrivate::infoForFrame(int frameNumber)
// For an animated image format, QImageIOHandler::nextImageDelay() should
// provide the time to wait until showing the next frame; but multi-frame
// formats are not expected to provide this value, so use 1000 ms by default.
const int nextFrameDelay = supportsAnimation ? reader->nextImageDelay() : 1000;
const auto nextFrameDelay = [&]() { return supportsAnimation ? reader->nextImageDelay() : 1000; };

if (cacheMode == QMovie::CacheNone) {
if (frameNumber != currentFrameNumber+1) {
Expand Down Expand Up @@ -363,7 +363,7 @@ QFrameInfo QMoviePrivate::infoForFrame(int frameNumber)
}
if (frameNumber > greatestFrameNumber)
greatestFrameNumber = frameNumber;
return QFrameInfo(QPixmap::fromImage(std::move(anImage)), nextFrameDelay);
return QFrameInfo(QPixmap::fromImage(std::move(anImage)), nextFrameDelay());
} else if (frameNumber != 0) {
// We've read all frames now. Return an end marker
haveReadAll = true;
Expand Down Expand Up @@ -391,7 +391,7 @@ QFrameInfo QMoviePrivate::infoForFrame(int frameNumber)
return QFrameInfo(); // Invalid
}
greatestFrameNumber = i;
QFrameInfo info(QPixmap::fromImage(std::move(anImage)), nextFrameDelay);
QFrameInfo info(QPixmap::fromImage(std::move(anImage)), nextFrameDelay());
// Cache it!
frameMap.insert(i, info);
if (i == frameNumber) {
Expand Down
12 changes: 12 additions & 0 deletions tests/auto/gui/image/qmovie/tst_qmovie.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ private slots:
void playMovie();
void jumpToFrame_data();
void jumpToFrame();
void frameDelay();
void changeMovieFile();
#ifndef QT_NO_WIDGETS
void infiniteLoop();
Expand Down Expand Up @@ -184,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"));
Expand Down

0 comments on commit 5f0ed0a

Please sign in to comment.