kimgio: webp plugin optimization

Signed-off-by: Ivailo Monev <xakepa10@gmail.com>
This commit is contained in:
Ivailo Monev 2024-04-11 13:16:48 +03:00
parent 851e7ec05c
commit d4d1fc653b
2 changed files with 35 additions and 30 deletions

View file

@ -38,15 +38,7 @@ WebPHandler::WebPHandler()
WebPHandler::~WebPHandler() WebPHandler::~WebPHandler()
{ {
if (m_webpanimdec) { deinit();
WebPAnimDecoderDelete(m_webpanimdec);
m_webpanimdec = nullptr;
}
if (m_framepainter) {
delete m_framepainter;
m_framepainter = nullptr;
}
} }
bool WebPHandler::canRead() const bool WebPHandler::canRead() const
@ -74,6 +66,7 @@ bool WebPHandler::read(QImage *image)
if (Q_UNLIKELY(webpstatus == 0)) { if (Q_UNLIKELY(webpstatus == 0)) {
kWarning() << "Could not get frame" << m_currentimage << webpstatus << m_webpanimdec; kWarning() << "Could not get frame" << m_currentimage << webpstatus << m_webpanimdec;
WebPDemuxReleaseIterator(&webpiter); WebPDemuxReleaseIterator(&webpiter);
deinit();
return false; return false;
} }
@ -81,6 +74,7 @@ bool WebPHandler::read(QImage *image)
if (Q_UNLIKELY(frame.isNull())) { if (Q_UNLIKELY(frame.isNull())) {
kWarning() << "Could not create image"; kWarning() << "Could not create image";
WebPDemuxReleaseIterator(&webpiter); WebPDemuxReleaseIterator(&webpiter);
deinit();
return false; return false;
} }
@ -96,6 +90,7 @@ bool WebPHandler::read(QImage *image)
if (Q_UNLIKELY(!webpoutput)) { if (Q_UNLIKELY(!webpoutput)) {
kWarning() << "Could not decode image"; kWarning() << "Could not decode image";
WebPDemuxReleaseIterator(&webpiter); WebPDemuxReleaseIterator(&webpiter);
deinit();
return false; return false;
} }
@ -141,6 +136,11 @@ bool WebPHandler::read(QImage *image)
*image = m_framebuffer; *image = m_framebuffer;
WebPDemuxReleaseIterator(&webpiter); WebPDemuxReleaseIterator(&webpiter);
if ((m_currentimage + 1) >= m_imagecount) {
// last frame, release resources
deinit();
}
return true; return true;
} }
@ -266,23 +266,12 @@ bool WebPHandler::jumpToImage(int imageNumber)
return false; return false;
} }
if (imageNumber == 0) { if (imageNumber == 0) {
deinit();
const qint64 devicepos = device()->pos(); const qint64 devicepos = device()->pos();
m_data = device()->readAll(); m_data = device()->readAll();
device()->seek(devicepos); device()->seek(devicepos);
if (m_webpanimdec) {
WebPAnimDecoderDelete(m_webpanimdec);
m_webpanimdec = nullptr;
}
if (m_framepainter) {
delete m_framepainter;
m_framepainter = nullptr;
}
m_framebuffer = QImage();
m_previousrect = QRectF();
m_background = QColor();
m_webpdata = { reinterpret_cast<const uint8_t*>(m_data.constData()), size_t(m_data.size()) }; m_webpdata = { reinterpret_cast<const uint8_t*>(m_data.constData()), size_t(m_data.size()) };
WebPAnimDecoderOptionsInit(&m_webpanimoptions); WebPAnimDecoderOptionsInit(&m_webpanimoptions);
#if Q_BYTE_ORDER == Q_BIG_ENDIAN #if Q_BYTE_ORDER == Q_BIG_ENDIAN
@ -296,17 +285,15 @@ bool WebPHandler::jumpToImage(int imageNumber)
); );
if (Q_UNLIKELY(!m_webpanimdec)) { if (Q_UNLIKELY(!m_webpanimdec)) {
kWarning() << "Could not create animation decoder"; kWarning() << "Could not create animation decoder";
m_data.clear(); deinit();
return false; return false;
} }
WebPAnimInfo webpaniminfo; WebPAnimInfo webpaniminfo;
int webpstatus = WebPAnimDecoderGetInfo(m_webpanimdec, &webpaniminfo); int webpstatus = WebPAnimDecoderGetInfo(m_webpanimdec, &webpaniminfo);
if (Q_UNLIKELY(webpstatus == 0)) { if (Q_UNLIKELY(webpstatus == 0)) {
kWarning() << "Could not get animation information"; kWarning() << "Could not get animation information" << webpstatus;
m_data.clear(); deinit();
WebPAnimDecoderDelete(m_webpanimdec);
m_webpanimdec = nullptr;
return false; return false;
} }
@ -316,9 +303,7 @@ bool WebPHandler::jumpToImage(int imageNumber)
m_framebuffer = QImage(webpaniminfo.canvas_width, webpaniminfo.canvas_height, QImage::Format_ARGB32_Premultiplied); m_framebuffer = QImage(webpaniminfo.canvas_width, webpaniminfo.canvas_height, QImage::Format_ARGB32_Premultiplied);
if (Q_UNLIKELY(m_framebuffer.isNull())) { if (Q_UNLIKELY(m_framebuffer.isNull())) {
kWarning() << "Could not create buffer image"; kWarning() << "Could not create buffer image";
m_data.clear(); deinit();
WebPAnimDecoderDelete(m_webpanimdec);
m_webpanimdec = nullptr;
return false; return false;
} }
// NOTE: have to fill, areas of frames may not be drawn // NOTE: have to fill, areas of frames may not be drawn
@ -327,6 +312,7 @@ bool WebPHandler::jumpToImage(int imageNumber)
m_background = QColor(QRgb(webpaniminfo.bgcolor)); m_background = QColor(QRgb(webpaniminfo.bgcolor));
} }
if (imageNumber >= m_imagecount) { if (imageNumber >= m_imagecount) {
deinit();
return false; return false;
} }
m_currentimage = imageNumber; m_currentimage = imageNumber;
@ -368,6 +354,23 @@ bool WebPHandler::canRead(QIODevice *device)
return false; return false;
} }
void WebPHandler::deinit()
{
if (m_webpanimdec) {
WebPAnimDecoderDelete(m_webpanimdec);
m_webpanimdec = nullptr;
}
if (m_framepainter) {
delete m_framepainter;
m_framepainter = nullptr;
}
m_data.clear();
m_framebuffer = QImage();
m_previousrect = QRectF();
m_background = QColor();
}
QList<QByteArray> WebPPlugin::mimeTypes() const QList<QByteArray> WebPPlugin::mimeTypes() const
{ {
static const QList<QByteArray> list = QList<QByteArray>() static const QList<QByteArray> list = QList<QByteArray>()

View file

@ -53,6 +53,8 @@ public:
int currentImageNumber() const final; int currentImageNumber() const final;
private: private:
void deinit();
int m_quality; int m_quality;
int m_loopcount; int m_loopcount;
int m_imagecount; int m_imagecount;