Merge branch 'master' of https://github.com/fluxer/kdelibs into devinfo

This commit is contained in:
Ivailo Monev 2021-08-01 02:02:40 +03:00
commit 404947818e
2 changed files with 63 additions and 83 deletions

View file

@ -29,15 +29,11 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>.
#include <QImage> #include <QImage>
#include <QVariant> #include <QVariant>
//---------------------------------------------------------------------
WebPHandler::WebPHandler() WebPHandler::WebPHandler()
: quality(75) : quality(75)
{ {
} }
//---------------------------------------------------------------------
bool WebPHandler::canRead() const bool WebPHandler::canRead() const
{ {
if (canRead(device())) { if (canRead(device())) {
@ -47,14 +43,13 @@ bool WebPHandler::canRead() const
return false; return false;
} }
//---------------------------------------------------------------------
bool WebPHandler::read(QImage *retImage) bool WebPHandler::read(QImage *retImage)
{ {
QByteArray data = device()->readAll(); QByteArray data = device()->readAll();
WebPBitstreamFeatures features; WebPBitstreamFeatures features;
VP8StatusCode ret = WebPGetFeatures(reinterpret_cast<const uint8_t*>(data.constData()), data.size(), &features); const VP8StatusCode ret = WebPGetFeatures(reinterpret_cast<const uint8_t*>(data.constData()),
data.size(), &features);
if (ret != VP8_STATUS_OK) { if (ret != VP8_STATUS_OK) {
return false; return false;
} }
@ -86,14 +81,13 @@ bool WebPHandler::read(QImage *retImage)
return true; return true;
} }
//---------------------------------------------------------------------
bool WebPHandler::write(const QImage &image) bool WebPHandler::write(const QImage &image)
{ {
// limitation in WebP // limitation in WebP
if ( (image.height() > 16383) || (image.height() == 0) || if (image.height() > 16383 || image.height() == 0 ||
(image.width() > 16383) || (image.width() == 0) ) image.width() > 16383 || image.width() == 0) {
return false; return false;
}
uint8_t *imageData = new uint8_t[image.width() * image.height() * (3 + image.hasAlphaChannel())]; uint8_t *imageData = new uint8_t[image.width() * image.height() * (3 + image.hasAlphaChannel())];
@ -116,7 +110,7 @@ bool WebPHandler::write(const QImage &image)
if (image.hasAlphaChannel()) { if (image.hasAlphaChannel()) {
size = WebPEncodeRGBA(imageData, image.width(), image.height(), image.width() * 4, quality, &output); size = WebPEncodeRGBA(imageData, image.width(), image.height(), image.width() * 4, quality, &output);
} else { } else {
size = WebPEncodeRGB(imageData, image.width(), image.height(), image.width() * 4, quality, &output); size = WebPEncodeRGB(imageData, image.width(), image.height(), image.width() * 3, quality, &output);
} }
delete []imageData; delete []imageData;
@ -131,106 +125,83 @@ bool WebPHandler::write(const QImage &image)
return true; return true;
} }
//--------------------------------------------------------------------- QByteArray WebPHandler::name() const
QByteArray WebPHandler::format() const
{ {
return "webp"; return "webp";
} }
//---------------------------------------------------------------------
bool WebPHandler::supportsOption(ImageOption option) const bool WebPHandler::supportsOption(ImageOption option) const
{ {
return (option == Quality) || (option == Size); return (option == Quality) || (option == Size);
} }
//---------------------------------------------------------------------
QVariant WebPHandler::option(ImageOption option) const QVariant WebPHandler::option(ImageOption option) const
{ {
switch ( option ) switch (option) {
{ case Quality: {
case Quality:
return quality; return quality;
}
case Size: { case Size: {
QByteArray data = device()->peek(26); const QByteArray data = device()->peek(26);
int width = 0, height = 0; int width = 0, height = 0;
if (WebPGetInfo(reinterpret_cast<const uint8_t*>(data.constData()), if (WebPGetInfo(reinterpret_cast<const uint8_t*>(data.constData()),
data.size(), &width, &height) == 0 ) data.size(), &width, &height) == 0) {
return QSize(); // header error return QSize(); // header error
}
return QSize(width, height); return QSize(width, height);
} }
default: {
default: return QVariant(); return QVariant();
} }
} }
Q_UNREACHABLE();
//--------------------------------------------------------------------- }
void WebPHandler::setOption(ImageOption option, const QVariant &value) void WebPHandler::setOption(ImageOption option, const QVariant &value)
{ {
if (option == Quality) if (option == Quality) {
quality = qBound(0, value.toInt(), 100); quality = qBound(0, value.toInt(), 100);
} }
}
//---------------------------------------------------------------------
bool WebPHandler::canRead(QIODevice *device) bool WebPHandler::canRead(QIODevice *device)
{ {
if (!device) { if (Q_UNLIKELY(!device)) {
qWarning("WebPHandler::canRead() called with no device"); qWarning("WebPHandler::canRead() called with no device");
return false; return false;
} }
// WebP file header: 4 bytes "RIFF", 4 bytes length, 4 bytes "WEBP" // WebP file header: 4 bytes "RIFF", 4 bytes length, 4 bytes "WEBP"
QByteArray header = device->peek(12); const QByteArray header = device->peek(12);
return (header.size() == 12) && header.startsWith("RIFF") && header.endsWith("WEBP"); return (header.size() == 12) && header.startsWith("RIFF") && header.endsWith("WEBP");
} }
//---------------------------------------------------------------------
//---------------------------------------------------------------------
class WebPPlugin : public QImageIOPlugin
{
public:
QStringList keys() const;
Capabilities capabilities(QIODevice *device, const QByteArray &format) const;
QImageIOHandler *create(QIODevice *device, const QByteArray &format = QByteArray()) const;
};
//---------------------------------------------------------------------
QStringList WebPPlugin::keys() const QStringList WebPPlugin::keys() const
{ {
return QStringList() << "webp"; return QStringList() << "webp";
} }
//---------------------------------------------------------------------
QImageIOPlugin::Capabilities WebPPlugin::capabilities(QIODevice *device, const QByteArray &format) const QImageIOPlugin::Capabilities WebPPlugin::capabilities(QIODevice *device, const QByteArray &format) const
{ {
if (format == "webp") if (format == "webp") {
return Capabilities(CanRead | CanWrite); return Capabilities(CanRead | CanWrite);
if (!format.isEmpty()) }
if (!format.isEmpty()) {
return 0; return 0;
if (!device->isOpen()) }
if (!device->isOpen()) {
return 0; return 0;
Capabilities cap;
if (device->isReadable() && WebPHandler::canRead(device))
cap |= CanRead;
if (device->isWritable())
cap |= CanWrite;
return cap;
} }
//--------------------------------------------------------------------- Capabilities cap;
if (device->isReadable() && WebPHandler::canRead(device)) {
cap |= CanRead;
}
if (device->isWritable()) {
cap |= CanWrite;
}
return cap;
}
QImageIOHandler *WebPPlugin::create(QIODevice *device, const QByteArray &format) const QImageIOHandler *WebPPlugin::create(QIODevice *device, const QByteArray &format) const
{ {

View file

@ -30,15 +30,15 @@ class WebPHandler : public QImageIOHandler
public: public:
WebPHandler(); WebPHandler();
virtual bool canRead() const; bool canRead() const final;
virtual bool read(QImage *image); bool read(QImage *image) final;
virtual bool write(const QImage &image); bool write(const QImage &image) final;
virtual QByteArray format() const; QByteArray name() const final;
virtual bool supportsOption(ImageOption option) const; bool supportsOption(ImageOption option) const final;
virtual QVariant option(ImageOption option) const; QVariant option(ImageOption option) const final;
virtual void setOption(ImageOption option, const QVariant &value); void setOption(ImageOption option, const QVariant &value) final;
static bool canRead(QIODevice *device); static bool canRead(QIODevice *device);
@ -46,4 +46,13 @@ private:
int quality; int quality;
}; };
class WebPPlugin : public QImageIOPlugin
{
public:
QStringList keys() const final;
Capabilities capabilities(QIODevice *device, const QByteArray &format) const final;
QImageIOHandler *create(QIODevice *device, const QByteArray &format = QByteArray()) const final;
};
#endif #endif