From b9ba2217566531b51f3c5c5158bfcc386539d810 Mon Sep 17 00:00:00 2001 From: Eirik Aavitsland Date: Fri, 25 May 2018 16:15:14 +0200 Subject: 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 --- src/plugins/imageformats/webp/qwebphandler.cpp | 27 ++++++++++++------------- tests/auto/webp/images/kollada_noalpha.webp | Bin 0 -> 3570 bytes tests/auto/webp/tst_qwebp.cpp | 23 ++++++++++++++++----- tests/auto/webp/webp.qrc | 1 + 4 files changed, 32 insertions(+), 19 deletions(-) create mode 100644 tests/auto/webp/images/kollada_noalpha.webp diff --git a/src/plugins/imageformats/webp/qwebphandler.cpp b/src/plugins/imageformats/webp/qwebphandler.cpp index 3a7bf43..12c4001 100644 --- a/src/plugins/imageformats/webp/qwebphandler.cpp +++ b/src/plugins/imageformats/webp/qwebphandler.cpp @@ -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; } diff --git a/tests/auto/webp/images/kollada_noalpha.webp b/tests/auto/webp/images/kollada_noalpha.webp new file mode 100644 index 0000000..b5abe5d Binary files /dev/null and b/tests/auto/webp/images/kollada_noalpha.webp differ diff --git a/tests/auto/webp/tst_qwebp.cpp b/tests/auto/webp/tst_qwebp.cpp index ad4a376..17289a5 100644 --- a/tests/auto/webp/tst_qwebp.cpp +++ b/tests/auto/webp/tst_qwebp.cpp @@ -53,15 +53,18 @@ void tst_qwebp::readImage_data() { QTest::addColumn("fileName"); QTest::addColumn("size"); + QTest::addColumn("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("postfix"); QTest::addColumn("quality"); QTest::addColumn("size"); + QTest::addColumn("alpha"); QTest::addColumn("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) diff --git a/tests/auto/webp/webp.qrc b/tests/auto/webp/webp.qrc index 6519e58..7d0c626 100644 --- a/tests/auto/webp/webp.qrc +++ b/tests/auto/webp/webp.qrc @@ -4,5 +4,6 @@ images/kollada.webp images/kollada_lossless.webp images/kollada_animation.webp + images/kollada_noalpha.webp -- cgit v1.2.3