webp handler: support alpha-less reading and writing
Webp files can be with or without alpha channel. The handler would ignore this and read all as Format_ARGB32 images, and write all as having alpha, in both cases losing that important bit of information. As a driveby, simplify the endianness handling in write(). By always converting the source image to an endianness-independent QImage format, no special handling is required. Task-number: QTBUG-48628 Change-Id: I624ed72b18a8b59a542979efcb4e8ff81214e0d7 Reviewed-by: Liang Qi <liang.qi@qt.io>
This commit is contained in:
parent
aa33202648
commit
b9ba221756
|
@ -174,7 +174,8 @@ bool QWebpHandler::read(QImage *image)
|
|||
if (status != VP8_STATUS_OK)
|
||||
return false;
|
||||
|
||||
QImage frame(m_iter.width, m_iter.height, QImage::Format_ARGB32);
|
||||
QImage::Format format = m_features.has_alpha ? QImage::Format_ARGB32 : QImage::Format_RGB32;
|
||||
QImage frame(m_iter.width, m_iter.height, format);
|
||||
uint8_t *output = frame.bits();
|
||||
size_t output_size = frame.sizeInBytes();
|
||||
#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
|
||||
|
@ -219,13 +220,10 @@ bool QWebpHandler::write(const QImage &image)
|
|||
}
|
||||
|
||||
QImage srcImage = image;
|
||||
#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
|
||||
if (srcImage.format() != QImage::Format_ARGB32)
|
||||
srcImage = srcImage.convertToFormat(QImage::Format_ARGB32);
|
||||
#else /* Q_BIG_ENDIAN */
|
||||
if (srcImage.format() != QImage::Format_RGBA8888)
|
||||
srcImage = srcImage.convertToFormat(QImage::Format_RGBA8888);
|
||||
#endif
|
||||
bool alpha = srcImage.hasAlphaChannel();
|
||||
QImage::Format newFormat = alpha ? QImage::Format_RGBA8888 : QImage::Format_RGB888;
|
||||
if (srcImage.format() != newFormat)
|
||||
srcImage = srcImage.convertToFormat(newFormat);
|
||||
|
||||
WebPPicture picture;
|
||||
WebPConfig config;
|
||||
|
@ -238,13 +236,14 @@ bool QWebpHandler::write(const QImage &image)
|
|||
picture.width = srcImage.width();
|
||||
picture.height = srcImage.height();
|
||||
picture.use_argb = 1;
|
||||
#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
|
||||
if (!WebPPictureImportBGRA(&picture, srcImage.bits(), srcImage.bytesPerLine())) {
|
||||
#else /* Q_BIG_ENDIAN */
|
||||
if (!WebPPictureImportRGBA(&picture, srcImage.bits(), srcImage.bytesPerLine())) {
|
||||
#endif
|
||||
qWarning() << "failed to import image data to webp picture.";
|
||||
bool failed = false;
|
||||
if (alpha)
|
||||
failed = !WebPPictureImportRGBA(&picture, srcImage.bits(), srcImage.bytesPerLine());
|
||||
else
|
||||
failed = !WebPPictureImportRGB(&picture, srcImage.bits(), srcImage.bytesPerLine());
|
||||
|
||||
if (failed) {
|
||||
qWarning() << "failed to import image data to webp picture.";
|
||||
WebPPictureFree(&picture);
|
||||
return false;
|
||||
}
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 3.5 KiB |
|
@ -53,15 +53,18 @@ void tst_qwebp::readImage_data()
|
|||
{
|
||||
QTest::addColumn<QString>("fileName");
|
||||
QTest::addColumn<QSize>("size");
|
||||
QTest::addColumn<bool>("alpha");
|
||||
|
||||
QTest::newRow("kollada") << QString("kollada") << QSize(436, 160);
|
||||
QTest::newRow("kollada_lossless") << QString("kollada_lossless") << QSize(436, 160);
|
||||
QTest::newRow("kollada") << QString("kollada") << QSize(436, 160) << true;
|
||||
QTest::newRow("kollada_lossless") << QString("kollada_lossless") << QSize(436, 160) << true;
|
||||
QTest::newRow("kollada_noalpha") << QString("kollada_noalpha") << QSize(436, 160) << false;
|
||||
}
|
||||
|
||||
void tst_qwebp::readImage()
|
||||
{
|
||||
QFETCH(QString, fileName);
|
||||
QFETCH(QSize, size);
|
||||
QFETCH(bool, alpha);
|
||||
|
||||
const QString path = QStringLiteral(":/images/") + fileName + QStringLiteral(".webp");
|
||||
QImageReader reader(path);
|
||||
|
@ -69,6 +72,7 @@ void tst_qwebp::readImage()
|
|||
QImage image = reader.read();
|
||||
QVERIFY2(!image.isNull(), qPrintable(reader.errorString()));
|
||||
QCOMPARE(image.size(), size);
|
||||
QCOMPARE(image.hasAlphaChannel(), alpha);
|
||||
}
|
||||
|
||||
void tst_qwebp::readAnimation_data()
|
||||
|
@ -136,10 +140,13 @@ void tst_qwebp::writeImage_data()
|
|||
QTest::addColumn<QString>("postfix");
|
||||
QTest::addColumn<int>("quality");
|
||||
QTest::addColumn<QSize>("size");
|
||||
QTest::addColumn<bool>("alpha");
|
||||
QTest::addColumn<bool>("needcheck");
|
||||
|
||||
QTest::newRow("kollada-75") << QString("kollada") << QString(".png") << 75 << QSize(436, 160) << false;
|
||||
QTest::newRow("kollada-100") << QString("kollada") << QString(".png") << 100 << QSize(436, 160) << true;
|
||||
QTest::newRow("kollada-75") << QString("kollada") << QString(".png") << 75 << QSize(436, 160) << true << false;
|
||||
QTest::newRow("kollada-100") << QString("kollada") << QString(".png") << 100 << QSize(436, 160) << true << true;
|
||||
QTest::newRow("kollada_noalpha-75") << QString("kollada_noalpha") << QString(".webp") << 75 << QSize(436, 160) << false << false;
|
||||
QTest::newRow("kollada_noalpha-100") << QString("kollada_noalpha") << QString(".webp") << 100 << QSize(436, 160) << false << true;
|
||||
}
|
||||
|
||||
void tst_qwebp::writeImage()
|
||||
|
@ -148,6 +155,7 @@ void tst_qwebp::writeImage()
|
|||
QFETCH(QString, postfix);
|
||||
QFETCH(int, quality);
|
||||
QFETCH(QSize, size);
|
||||
QFETCH(bool, alpha);
|
||||
QFETCH(bool, needcheck);
|
||||
|
||||
const QString path = QString("%1-%2.webp").arg(fileName).arg(quality);
|
||||
|
@ -162,8 +170,13 @@ void tst_qwebp::writeImage()
|
|||
writer.setQuality(quality);
|
||||
QVERIFY2(writer.write(image), qPrintable(writer.errorString()));
|
||||
|
||||
QImage reread(path);
|
||||
QVERIFY(!reread.isNull());
|
||||
QVERIFY(reread.size() == size);
|
||||
QVERIFY(reread.hasAlphaChannel() == alpha);
|
||||
|
||||
if (needcheck)
|
||||
QVERIFY(image == QImage(path));
|
||||
QVERIFY(image == reread);
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_qwebp)
|
||||
|
|
|
@ -4,5 +4,6 @@
|
|||
<file>images/kollada.webp</file>
|
||||
<file>images/kollada_lossless.webp</file>
|
||||
<file>images/kollada_animation.webp</file>
|
||||
<file>images/kollada_noalpha.webp</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
|
Loading…
Reference in New Issue