rework animations code for statefull image reading

requires changes to image plugins and elsewhere

Signed-off-by: Ivailo Monev <xakepa10@gmail.com>
This commit is contained in:
Ivailo Monev 2024-04-11 00:28:38 +03:00
parent 95f4215d4b
commit 3f06e61a8f
6 changed files with 40 additions and 63 deletions

View file

@ -353,17 +353,6 @@ int QImageIOHandler::imageCount() const
return canRead() ? 1 : 0;
}
/*!
For image formats that support animation, this function jumps to the
next image.
The default implementation does nothing, and returns false.
*/
bool QImageIOHandler::jumpToNextImage()
{
return false;
}
/*!
For image formats that support animation, this function jumps to the image
whose sequence number is \a imageNumber. The next call to read() will

View file

@ -67,7 +67,6 @@ public:
virtual bool supportsOption(ImageOption option) const;
// incremental loading
virtual bool jumpToNextImage();
virtual bool jumpToImage(int imageNumber);
virtual int loopCount() const;
virtual int imageCount() const;

View file

@ -675,24 +675,6 @@ bool QImageReader::read(QImage *image)
return true;
}
/*!
For image formats that support animation, this function steps over the
current image, returning true if successful or false if there is no
following image in the animation.
The default implementation calls read(), then discards the resulting
image, but the image handler may have a more efficient way of implementing
this operation.
\sa jumpToImage(), QImageIOHandler::jumpToNextImage()
*/
bool QImageReader::jumpToNextImage()
{
if (!d->initHandler())
return false;
return d->handler->jumpToNextImage();
}
/*!
For image formats that support animation, this function skips to the image
whose sequence number is \a imageNumber, returning true if successful
@ -700,7 +682,7 @@ bool QImageReader::jumpToNextImage()
The next call to read() will attempt to read this image.
\sa jumpToNextImage(), QImageIOHandler::jumpToImage()
\sa QImageIOHandler::jumpToImage()
*/
bool QImageReader::jumpToImage(int imageNumber)
{

View file

@ -78,7 +78,6 @@ public:
QImage read();
bool read(QImage *image);
bool jumpToNextImage();
bool jumpToImage(int imageNumber);
int loopCount() const;
int imageCount() const;

View file

@ -141,7 +141,8 @@ public:
void begin();
void done();
void readerError(const QImageReader::ImageReaderError error);
bool loadCurrentFrame();
void _q_loadNextFrame();
int loopCount;
@ -162,14 +163,34 @@ QMoviePrivate::QMoviePrivate(QMovie *qq)
void QMoviePrivate::begin()
{
Q_Q(QMovie);
loopCount = -1;
if (!reader->jumpToImage(0)) {
emit q->error(reader->error());
return;
}
loopCount = reader->loopCount();
_q_loadNextFrame();
if (!loadCurrentFrame()) {
return;
}
nextImageTimer.start();
movieState = QMovie::Running;
emit q->started();
emit q->stateChanged(QMovie::Running);
}
bool QMoviePrivate::loadCurrentFrame()
{
Q_Q(QMovie);
if (!reader->read(&currentImage)) {
currentImage = QImage();
done();
emit q->error(reader->error());
return false;
}
emit q->frameChanged(reader->currentImageNumber());
return true;
}
void QMoviePrivate::done()
{
Q_Q(QMovie);
@ -179,35 +200,32 @@ void QMoviePrivate::done()
emit q->stateChanged(QMovie::NotRunning);
}
void QMoviePrivate::readerError(const QImageReader::ImageReaderError error)
{
Q_Q(QMovie);
done();
emit q->error(reader->error());
}
void QMoviePrivate::_q_loadNextFrame()
{
Q_Q(QMovie);
if (!reader->read(&currentImage)) {
currentImage = QImage();
readerError(reader->error());
if (!loadCurrentFrame()) {
return;
}
const int currentframe = reader->currentImageNumber();
emit q->frameChanged(currentframe);
const int framecount = reader->imageCount();
int nextframe = (reader->currentImageNumber() + 1);
// qDebug() << Q_FUNC_INFO << framecount << nextframe << loopCount;
nextImageTimer.setInterval(reader->nextImageDelay());
if (currentframe >= reader->imageCount()) {
loopCount++;
if (loopCount == 0 || loopCount < reader->loopCount()) {
// infinite loop or not done looping
if (!reader->jumpToImage(0)) {
readerError(reader->error());
}
if (framecount > 0 && nextframe >= framecount) {
if (loopCount == 0) {
// infinite loop
nextframe = 0;
} else if (loopCount < reader->loopCount()) {
// not done looping
loopCount++;
} else {
done();
return;
}
}
if (!reader->jumpToImage(nextframe)) {
done();
emit q->error(reader->error());
}
}
/*!
@ -431,15 +449,6 @@ int QMovie::currentFrameNumber() const
return d->reader->currentImageNumber();
}
/*!
Jumps to the next frame. Returns true on success; otherwise returns false.
*/
bool QMovie::jumpToNextFrame()
{
Q_D(QMovie);
return d->reader->jumpToNextImage();
}
/*!
Returns the number of times the movie will loop before it finishes.
If the movie will only play once (no looping), loopCount returns 0.

View file

@ -97,7 +97,6 @@ Q_SIGNALS:
public Q_SLOTS:
void start();
bool jumpToNextFrame();
void stop();
private: