You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
105 lines
4.0 KiB
105 lines
4.0 KiB
From ebcd7aa43e16a18e795dc0720c4821467ca694fe Mon Sep 17 00:00:00 2001
|
|
From: Eirik Aavitsland <eirik.aavitsland@qt.io>
|
|
Date: Thu, 8 Sep 2022 14:52:19 +0200
|
|
Subject: [PATCH 1/4] webp: support sequential input device if full file is
|
|
available
|
|
|
|
Since we do no random access during decoding, just a readAll() of the
|
|
whole image file. So if it is all available already, we can handle a
|
|
sequential device. That is useful for Quick AnimationImage, which will
|
|
pass a finished QNetworkReply as the input device.
|
|
|
|
This commit removes some seek() calls in the header checking, that
|
|
supposedly should reset the device position. These were in practice
|
|
either no-ops or bugs, since the device is only being peeked, so the
|
|
position never changes in the first place, and a QImageIOHandler is
|
|
supposed to read from the device at the position it is at when passed.
|
|
|
|
Fixes: QTBUG-70245
|
|
Change-Id: I5a4ff5fa4bbd19b0545ad41645969d714b4dc7d5
|
|
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
|
|
Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
|
|
|
|
|
|
(cherry picked from commit 369be99d82a7c1182e3693756ab545cea86bb90d)
|
|
---
|
|
.../imageformats/webp/qwebphandler.cpp | 29 +++++++++----------
|
|
1 file changed, 14 insertions(+), 15 deletions(-)
|
|
|
|
diff --git a/src/plugins/imageformats/webp/qwebphandler.cpp b/src/plugins/imageformats/webp/qwebphandler.cpp
|
|
index 82d38cb..d02eb05 100644
|
|
--- a/src/plugins/imageformats/webp/qwebphandler.cpp
|
|
+++ b/src/plugins/imageformats/webp/qwebphandler.cpp
|
|
@@ -45,6 +45,7 @@
|
|
#include <qdebug.h>
|
|
#include <qpainter.h>
|
|
#include <qvariant.h>
|
|
+#include <QtEndian>
|
|
|
|
static const int riffHeaderSize = 12; // RIFF_HEADER_SIZE from webp/format_constants.h
|
|
|
|
@@ -102,21 +103,23 @@ bool QWebpHandler::ensureScanned() const
|
|
|
|
m_scanState = ScanError;
|
|
|
|
- if (device()->isSequential()) {
|
|
- qWarning() << "Sequential devices are not supported";
|
|
+ QWebpHandler *that = const_cast<QWebpHandler *>(this);
|
|
+ const int headerBytesNeeded = sizeof(WebPBitstreamFeatures);
|
|
+ QByteArray header = device()->peek(headerBytesNeeded);
|
|
+ if (header.size() < headerBytesNeeded)
|
|
return false;
|
|
- }
|
|
|
|
- qint64 oldPos = device()->pos();
|
|
- device()->seek(0);
|
|
-
|
|
- QWebpHandler *that = const_cast<QWebpHandler *>(this);
|
|
- QByteArray header = device()->peek(sizeof(WebPBitstreamFeatures));
|
|
+ // We do no random access during decoding, just a readAll() of the whole image file. So if
|
|
+ // if it is all available already, we can accept a sequential device. The riff header contains
|
|
+ // the file size minus 8 bytes header
|
|
+ qint64 byteSize = qFromLittleEndian<quint32>(header.constData() + 4);
|
|
+ if (device()->isSequential() && device()->bytesAvailable() < byteSize + 8) {
|
|
+ qWarning() << "QWebpHandler: Insufficient data available in sequential device";
|
|
+ return false;
|
|
+ }
|
|
if (WebPGetFeatures((const uint8_t*)header.constData(), header.size(), &(that->m_features)) == VP8_STATUS_OK) {
|
|
if (m_features.has_animation) {
|
|
// For animation, we have to read and scan whole file to determine loop count and images count
|
|
- device()->seek(oldPos);
|
|
-
|
|
if (that->ensureDemuxer()) {
|
|
that->m_loop = WebPDemuxGetI(m_demuxer, WEBP_FF_LOOP_COUNT);
|
|
that->m_frameCount = WebPDemuxGetI(m_demuxer, WEBP_FF_FRAME_COUNT);
|
|
@@ -126,17 +129,13 @@ bool QWebpHandler::ensureScanned() const
|
|
if (that->m_features.has_alpha)
|
|
that->m_composited->fill(Qt::transparent);
|
|
|
|
- // We do not reset device position since we have read in all data
|
|
m_scanState = ScanSuccess;
|
|
- return true;
|
|
}
|
|
} else {
|
|
m_scanState = ScanSuccess;
|
|
}
|
|
}
|
|
|
|
- device()->seek(oldPos);
|
|
-
|
|
return m_scanState == ScanSuccess;
|
|
}
|
|
|
|
@@ -159,7 +158,7 @@ bool QWebpHandler::ensureDemuxer()
|
|
|
|
bool QWebpHandler::read(QImage *image)
|
|
{
|
|
- if (!ensureScanned() || device()->isSequential() || !ensureDemuxer())
|
|
+ if (!ensureScanned() || !ensureDemuxer())
|
|
return false;
|
|
|
|
QRect prevFrameRect;
|
|
--
|
|
2.46.0
|
|
|