From 68faf3a9bb496d655de575196b7070855ef096e0 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Mon, 27 Apr 2015 14:43:50 +0200 Subject: [PATCH] Fix QImage format after inplace conversion Some inplace conversions would not set the requested image format in the returned image, due to the same conversion being used for several destination formats. This patch ensures all inplace conversions return the right format, and adds testing infrastructure to easily test iterate over all formats so that they all can be tested. Change-Id: I68ab17a713ddb2aa8ed6aaf0a0a1ec8bbcb56090 Reviewed-by: Gunnar Sletta --- src/gui/image/qimage_conversions.cpp | 126 +++++++++---- tests/auto/gui/image/qimage/tst_qimage.cpp | 210 ++++++++++++++------- 2 files changed, 239 insertions(+), 97 deletions(-) diff --git a/src/gui/image/qimage_conversions.cpp b/src/gui/image/qimage_conversions.cpp index e1be0322155..74ad1127a97 100644 --- a/src/gui/image/qimage_conversions.cpp +++ b/src/gui/image/qimage_conversions.cpp @@ -425,25 +425,25 @@ static void convert_ARGB_to_RGBA(QImageData *dest, const QImageData *src, Qt::Im } } +template static bool convert_ARGB_to_RGBA_inplace(QImageData *data, Qt::ImageConversionFlags) { Q_ASSERT(data->format == QImage::Format_ARGB32 || data->format == QImage::Format_ARGB32_Premultiplied); const int pad = (data->bytes_per_line >> 2) - data->width; quint32 *rgb_data = (quint32 *) data->data; + Q_CONSTEXPR uint mask = (DestFormat == QImage::Format_RGBX8888) ? 0xff000000 : 0; for (int i = 0; i < data->height; ++i) { const quint32 *end = rgb_data + data->width; while (rgb_data < end) { - *rgb_data = ARGB2RGBA(*rgb_data); + *rgb_data = ARGB2RGBA(*rgb_data | mask); ++rgb_data; } rgb_data += pad; } - if (data->format == QImage::Format_ARGB32) - data->format = QImage::Format_RGBA8888; - else - data->format = QImage::Format_RGBA8888_Premultiplied; + + data->format = DestFormat; return true; } @@ -567,6 +567,7 @@ static inline uint qUnpremultiplyRgb30(uint rgb30) return 0; } +template static void convert_A2RGB30_PM_to_RGB30(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags) { Q_ASSERT(src->format == QImage::Format_A2RGB30_Premultiplied || src->format == QImage::Format_A2BGR30_Premultiplied); @@ -582,7 +583,8 @@ static void convert_A2RGB30_PM_to_RGB30(QImageData *dest, const QImageData *src, for (int i = 0; i < src->height; ++i) { const quint32 *end = src_data + src->width; while (src_data < end) { - *dest_data = 0xc0000000 | qUnpremultiplyRgb30(*src_data); + const uint p = 0xc0000000 | qUnpremultiplyRgb30(*src_data); + *dest_data = (rgbswap) ? qRgbSwapRgb30(p) : p; ++src_data; ++dest_data; } @@ -591,6 +593,7 @@ static void convert_A2RGB30_PM_to_RGB30(QImageData *dest, const QImageData *src, } } +template static bool convert_A2RGB30_PM_to_RGB30_inplace(QImageData *data, Qt::ImageConversionFlags) { Q_ASSERT(data->format == QImage::Format_A2RGB30_Premultiplied || data->format == QImage::Format_A2BGR30_Premultiplied); @@ -601,16 +604,17 @@ static bool convert_A2RGB30_PM_to_RGB30_inplace(QImageData *data, Qt::ImageConve for (int i = 0; i < data->height; ++i) { const uint *end = rgb_data + data->width; while (rgb_data < end) { - *rgb_data = 0xc0000000 | qUnpremultiplyRgb30(*rgb_data); + const uint p = 0xc0000000 | qUnpremultiplyRgb30(*rgb_data); + *rgb_data = (rgbswap) ? qRgbSwapRgb30(p) : p; ++rgb_data; } rgb_data += pad; } if (data->format == QImage::Format_A2RGB30_Premultiplied) - data->format = QImage::Format_RGB30; + data->format = (rgbswap) ? QImage::Format_BGR30 : QImage::Format_RGB30; else - data->format = QImage::Format_BGR30; + data->format = (rgbswap) ? QImage::Format_RGB30 : QImage::Format_BGR30; return true; } @@ -678,6 +682,19 @@ static bool convert_BGR30_to_RGB30_inplace(QImageData *data, Qt::ImageConversion return true; } +static bool convert_BGR30_to_A2RGB30_inplace(QImageData *data, Qt::ImageConversionFlags flags) +{ + Q_ASSERT(data->format == QImage::Format_RGB30 || data->format == QImage::Format_BGR30); + if (!convert_BGR30_to_RGB30_inplace(data, flags)) + return false; + + if (data->format == QImage::Format_RGB30) + data->format = QImage::Format_A2RGB30_Premultiplied; + else + data->format = QImage::Format_A2BGR30_Premultiplied; + return true; +} + static bool convert_indexed8_to_ARGB_PM_inplace(QImageData *data, Qt::ImageConversionFlags) { Q_ASSERT(data->format == QImage::Format_Indexed8); @@ -732,7 +749,7 @@ static bool convert_indexed8_to_ARGB_PM_inplace(QImageData *data, Qt::ImageConve return true; } -static bool convert_indexed8_to_RGB_inplace(QImageData *data, Qt::ImageConversionFlags) +static bool convert_indexed8_to_ARGB_inplace(QImageData *data, Qt::ImageConversionFlags) { Q_ASSERT(data->format == QImage::Format_Indexed8); if (!data->own_data) @@ -775,7 +792,7 @@ static bool convert_indexed8_to_RGB_inplace(QImageData *data, Qt::ImageConversio } data->colortable = QVector(); - data->format = QImage::Format_RGB32; + data->format = QImage::Format_ARGB32; data->bytes_per_line = dst_bytes_per_line; data->depth = depth; data->nbytes = nbytes; @@ -783,6 +800,24 @@ static bool convert_indexed8_to_RGB_inplace(QImageData *data, Qt::ImageConversio return true; } +static bool convert_indexed8_to_RGB_inplace(QImageData *data, Qt::ImageConversionFlags flags) +{ + Q_ASSERT(data->format == QImage::Format_Indexed8); + if (!data->own_data) + return false; + + if (data->has_alpha_clut) { + for (int i = 0; i < data->colortable.size(); ++i) + data->colortable[i] |= 0xff000000; + } + + if (!convert_indexed8_to_ARGB_inplace(data, flags)) + return false; + + data->format = QImage::Format_RGB32; + return true; +} + static bool convert_indexed8_to_RGB16_inplace(QImageData *data, Qt::ImageConversionFlags) { Q_ASSERT(data->format == QImage::Format_Indexed8); @@ -965,8 +1000,9 @@ static void mask_alpha_converter(QImageData *dest, const QImageData *src, Qt::Im template static bool mask_alpha_converter_inplace(QImageData *data, Qt::ImageConversionFlags) { - Q_ASSERT(data->format == QImage::Format_RGB32 || DestFormat == QImage::Format_RGB32); - + Q_ASSERT(data->format == QImage::Format_RGB32 + || DestFormat == QImage::Format_RGB32 + || DestFormat == QImage::Format_RGBX8888); const int pad = (data->bytes_per_line >> 2) - data->width; QRgb *rgb_data = (QRgb *) data->data; @@ -1009,6 +1045,29 @@ static void mask_alpha_converter_RGBx(QImageData *dest, const QImageData *src, Q #endif } +static bool mask_alpha_converter_rgbx_inplace(QImageData *data, Qt::ImageConversionFlags flags) +{ +#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN + return mask_alpha_converter_inplace(data, flags); +#else + Q_UNUSED(flags); + + const int pad = (data->bytes_per_line >> 2) - data->width; + QRgb *rgb_data = (QRgb *) data->data; + + for (int i = 0; i < data->height; ++i) { + const QRgb *end = rgb_data + data->width; + while (rgb_data < end) { + *rgb_data = *rgb_data | 0x000000fff; + ++rgb_data; + } + rgb_data += pad; + } + data->format = DestFormat; + return true; +#endif +} + static QVector fix_color_table(const QVector &ctbl, QImage::Format format) { QVector colorTable = ctbl; @@ -2323,9 +2382,9 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0, 0, - convert_A2RGB30_PM_to_RGB30, - 0, + convert_A2RGB30_PM_to_RGB30, 0, + convert_A2RGB30_PM_to_RGB30, convert_BGR30_to_RGB30, 0, 0 }, // Format_BGR30A2_Premultiplied @@ -2375,12 +2434,11 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0, 0, - 0, + convert_A2RGB30_PM_to_RGB30, convert_BGR30_to_RGB30, - convert_A2RGB30_PM_to_RGB30, - 0, - 0, + convert_A2RGB30_PM_to_RGB30, 0, + 0, 0 }, // Format_RGB30A2_Premultiplied { 0, @@ -2440,8 +2498,8 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma 0, 0, 0, - 0, convert_indexed8_to_RGB_inplace, + convert_indexed8_to_ARGB_inplace, convert_indexed8_to_ARGB_PM_inplace, convert_indexed8_to_RGB16_inplace, 0, @@ -2501,8 +2559,8 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma 0, 0, 0, - 0, - convert_ARGB_to_RGBA_inplace, + convert_ARGB_to_RGBA_inplace, + convert_ARGB_to_RGBA_inplace, 0, 0, 0, 0, 0, 0, 0 }, // Format_ARGB32 @@ -2525,7 +2583,7 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma 0, 0, 0, - convert_ARGB_to_RGBA_inplace, + convert_ARGB_to_RGBA_inplace, 0, 0, 0, 0, 0, 0 }, // Format_ARGB32_Premultiplied { @@ -2594,7 +2652,7 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma 0, 0, 0, - 0, + mask_alpha_converter_rgbx_inplace, #if Q_BYTE_ORDER == Q_LITTLE_ENDIAN && __SSE2__ 0, convert_ARGB_to_ARGB_PM_inplace_sse2, @@ -2646,10 +2704,10 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma 0, 0, 0, - 0, + 0, // self convert_passthrough_inplace, convert_BGR30_to_RGB30_inplace, - convert_BGR30_to_RGB30_inplace, + convert_BGR30_to_A2RGB30_inplace, 0, 0 }, // Format_BGR30 { @@ -2672,9 +2730,9 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma 0, 0, 0, - convert_A2RGB30_PM_to_RGB30_inplace, - 0, - 0, + convert_A2RGB30_PM_to_RGB30_inplace, + 0, // self + convert_A2RGB30_PM_to_RGB30_inplace, convert_BGR30_to_RGB30_inplace, 0, 0 }, // Format_BGR30A2_Premultiplied @@ -2699,8 +2757,8 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma 0, 0, convert_BGR30_to_RGB30_inplace, - convert_BGR30_to_RGB30_inplace, - 0, + convert_BGR30_to_A2RGB30_inplace, + 0, // self convert_passthrough_inplace, 0, 0 }, // Format_RGB30 @@ -2724,10 +2782,10 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma 0, 0, 0, - 0, + convert_A2RGB30_PM_to_RGB30_inplace, convert_BGR30_to_RGB30_inplace, - convert_A2RGB30_PM_to_RGB30_inplace, - 0, + convert_A2RGB30_PM_to_RGB30_inplace, + 0, // self 0, 0 }, // Format_RGB30A2_Premultiplied { diff --git a/tests/auto/gui/image/qimage/tst_qimage.cpp b/tests/auto/gui/image/qimage/tst_qimage.cpp index 266230de387..fa2aae66584 100644 --- a/tests/auto/gui/image/qimage/tst_qimage.cpp +++ b/tests/auto/gui/image/qimage/tst_qimage.cpp @@ -41,6 +41,7 @@ #include #include +#include #include Q_DECLARE_METATYPE(QImage::Format) @@ -160,8 +161,11 @@ private slots: void inplaceRgbMirrored(); - void inplaceConversion_data(); - void inplaceConversion(); + void genericRgbConversion_data(); + void genericRgbConversion(); + + void inplaceRgbConversion_data(); + void inplaceRgbConversion(); void deepCopyWhenPaintingActive(); void scaled_QTBUG19157(); @@ -191,6 +195,67 @@ private: const QString m_prefix; }; +static QString formatToString(QImage::Format format) +{ + switch (format) { + case QImage::Format_Invalid: + return QStringLiteral("Invalid"); + case QImage::Format_Mono: + return QStringLiteral("Mono"); + case QImage::Format_MonoLSB: + return QStringLiteral("MonoLSB"); + case QImage::Format_Indexed8: + return QStringLiteral("Indexed8"); + case QImage::Format_RGB32: + return QStringLiteral("RGB32"); + case QImage::Format_ARGB32: + return QStringLiteral("ARGB32"); + case QImage::Format_ARGB32_Premultiplied: + return QStringLiteral("ARGB32pm"); + case QImage::Format_RGB16: + return QStringLiteral("RGB16"); + case QImage::Format_ARGB8565_Premultiplied: + return QStringLiteral("ARGB8565pm"); + case QImage::Format_RGB666: + return QStringLiteral("RGB666"); + case QImage::Format_ARGB6666_Premultiplied: + return QStringLiteral("ARGB6666pm"); + case QImage::Format_RGB555: + return QStringLiteral("RGB555"); + case QImage::Format_ARGB8555_Premultiplied: + return QStringLiteral("ARGB8555pm"); + case QImage::Format_RGB888: + return QStringLiteral("RGB888"); + case QImage::Format_RGB444: + return QStringLiteral("RGB444"); + case QImage::Format_ARGB4444_Premultiplied: + return QStringLiteral("ARGB4444pm"); + case QImage::Format_RGBX8888: + return QStringLiteral("RGBx88888"); + case QImage::Format_RGBA8888: + return QStringLiteral("RGBA88888"); + case QImage::Format_RGBA8888_Premultiplied: + return QStringLiteral("RGBA88888pm"); + case QImage::Format_BGR30: + return QStringLiteral("BGR30"); + case QImage::Format_A2BGR30_Premultiplied: + return QStringLiteral("A2BGR30pm"); + case QImage::Format_RGB30: + return QStringLiteral("RGB30"); + case QImage::Format_A2RGB30_Premultiplied: + return QStringLiteral("A2RGB30pm"); + case QImage::Format_Alpha8: + return QStringLiteral("Alpha8"); + case QImage::Format_Grayscale8: + return QStringLiteral("Grayscale8"); + default: + break; + }; + Q_UNREACHABLE(); + qWarning("Unhandled image format"); + return QStringLiteral("unknown"); +} + tst_QImage::tst_QImage() : m_prefix(QFINDTESTDATA("images/")) { @@ -2162,23 +2227,9 @@ void tst_QImage::rgbSwapped_data() { QTest::addColumn("format"); - QTest::newRow("Format_Indexed8") << QImage::Format_Indexed8; - QTest::newRow("Format_RGB32") << QImage::Format_RGB32; - QTest::newRow("Format_ARGB32") << QImage::Format_ARGB32; - QTest::newRow("Format_ARGB32_Premultiplied") << QImage::Format_ARGB32_Premultiplied; - QTest::newRow("Format_RGB16") << QImage::Format_RGB16; - QTest::newRow("Format_ARGB8565_Premultiplied") << QImage::Format_ARGB8565_Premultiplied; - QTest::newRow("Format_ARGB6666_Premultiplied") << QImage::Format_ARGB6666_Premultiplied; - QTest::newRow("Format_ARGB4444_Premultiplied") << QImage::Format_ARGB4444_Premultiplied; - QTest::newRow("Format_RGB666") << QImage::Format_RGB666; - QTest::newRow("Format_RGB555") << QImage::Format_RGB555; - QTest::newRow("Format_ARGB8555_Premultiplied") << QImage::Format_ARGB8555_Premultiplied; - QTest::newRow("Format_RGB888") << QImage::Format_RGB888; - QTest::newRow("Format_RGB444") << QImage::Format_RGB444; - QTest::newRow("Format_RGBX8888") << QImage::Format_RGBX8888; - QTest::newRow("Format_RGBA8888_Premultiplied") << QImage::Format_RGBA8888_Premultiplied; - QTest::newRow("Format_A2BGR30_Premultiplied") << QImage::Format_A2BGR30_Premultiplied; - QTest::newRow("Format_RGB30") << QImage::Format_RGB30; + for (int i = QImage::Format_Indexed8; i < QImage::Format_Alpha8; ++i) { + QTest::newRow(qPrintable(formatToString(QImage::Format(i)))) << QImage::Format(i); + } } void tst_QImage::rgbSwapped() @@ -2398,23 +2449,18 @@ void tst_QImage::inplaceMirrored_data() QTest::addColumn("swap_vertical"); QTest::addColumn("swap_horizontal"); - QTest::newRow("Format_ARGB32, vertical") << QImage::Format_ARGB32 << true << false; - QTest::newRow("Format_RGB888, vertical") << QImage::Format_RGB888 << true << false; - QTest::newRow("Format_RGB16, vertical") << QImage::Format_RGB16 << true << false; - QTest::newRow("Format_Indexed8, vertical") << QImage::Format_Indexed8 << true << false; - QTest::newRow("Format_Mono, vertical") << QImage::Format_Mono << true << false; - - QTest::newRow("Format_ARGB32, horizontal") << QImage::Format_ARGB32 << false << true; - QTest::newRow("Format_RGB888, horizontal") << QImage::Format_RGB888 << false << true; - QTest::newRow("Format_RGB16, horizontal") << QImage::Format_RGB16 << false << true; - QTest::newRow("Format_Indexed8, horizontal") << QImage::Format_Indexed8 << false << true; - QTest::newRow("Format_Mono, horizontal") << QImage::Format_Mono << false << true; - - QTest::newRow("Format_ARGB32, horizontal+vertical") << QImage::Format_ARGB32 << true << true; - QTest::newRow("Format_RGB888, horizontal+vertical") << QImage::Format_RGB888 << true << true; - QTest::newRow("Format_RGB16, horizontal+vertical") << QImage::Format_RGB16 << true << true; - QTest::newRow("Format_Indexed8, horizontal+vertical") << QImage::Format_Indexed8 << true << true; - QTest::newRow("Format_Mono, horizontal+vertical") << QImage::Format_Mono << true << true; + for (int i = QImage::Format_Mono; i < QImage::NImageFormats; ++i) { + if (i == QImage::Format_Alpha8 || i == QImage::Format_Grayscale8) + continue; + if (i == QImage::Format_RGB444 || i == QImage::Format_ARGB4444_Premultiplied) + continue; + QTest::newRow(qPrintable(formatToString(QImage::Format(i)) + QStringLiteral(", vertical"))) + << QImage::Format(i) << true << false; + QTest::newRow(qPrintable(formatToString(QImage::Format(i)) + QStringLiteral(", horizontal"))) + << QImage::Format(i) << false << true; + QTest::newRow(qPrintable(formatToString(QImage::Format(i)) + QStringLiteral(", horizontal+vertical"))) + << QImage::Format(i) << true << true; + } } void tst_QImage::inplaceMirrored() @@ -2428,6 +2474,7 @@ void tst_QImage::inplaceMirrored() switch (format) { case QImage::Format_Mono: + case QImage::Format_MonoLSB: for (int i = 0; i < image.height(); ++i) { ushort* scanLine = (ushort*)image.scanLine(i); *scanLine = (i % 2) ? 0x0fffU : 0xf000U; @@ -2450,7 +2497,7 @@ void tst_QImage::inplaceMirrored() const uchar* originalPtr = image.constScanLine(0); QImage imageMirrored = std::move(image).mirrored(swap_horizontal, swap_vertical); - if (format != QImage::Format_Mono) { + if (format != QImage::Format_Mono && format != QImage::Format_MonoLSB) { for (int i = 0; i < imageMirrored.height(); ++i) { int mirroredI = swap_vertical ? (imageMirrored.height() - i - 1) : i; for (int j = 0; j < imageMirrored.width(); ++j) { @@ -2540,23 +2587,60 @@ void tst_QImage::inplaceRgbMirrored() #endif } -void tst_QImage::inplaceConversion_data() +void tst_QImage::genericRgbConversion_data() { QTest::addColumn("format"); QTest::addColumn("dest_format"); - QTest::newRow("Format_RGB32 -> RGB16") << QImage::Format_RGB32 << QImage::Format_RGB16; - QTest::newRow("Format_ARGB32 -> Format_RGBA8888") << QImage::Format_ARGB32 << QImage::Format_RGBA8888; - QTest::newRow("Format_RGB888 -> Format_ARGB6666_Premultiplied") << QImage::Format_RGB888 << QImage::Format_ARGB6666_Premultiplied; - QTest::newRow("Format_RGB16 -> Format_RGB555") << QImage::Format_RGB16 << QImage::Format_RGB555; - QTest::newRow("Format_RGB666 -> Format_RGB888") << QImage::Format_RGB666 << QImage::Format_RGB888; - QTest::newRow("Format_ARGB8565_Premultiplied, Format_ARGB8555_Premultiplied") << QImage::Format_ARGB8565_Premultiplied << QImage::Format_ARGB8555_Premultiplied; - QTest::newRow("Format_ARGB4444_Premultiplied, Format_RGB444") << QImage::Format_ARGB4444_Premultiplied << QImage::Format_RGB444; - QTest::newRow("Format_RGBA8888 -> RGB16") << QImage::Format_RGBA8888 << QImage::Format_RGB16; - QTest::newRow("Format_RGBA8888_Premultiplied -> RGB16") << QImage::Format_RGBA8888_Premultiplied << QImage::Format_RGB16; + for (int i = QImage::Format_RGB32; i < QImage::Format_Alpha8; ++i) { + for (int j = QImage::Format_RGB32; j < QImage::Format_Alpha8; ++j) { + if (i == j) + continue; + QString test = QString::fromLatin1("%1 -> %2").arg(formatToString(QImage::Format(i))).arg(formatToString(QImage::Format(j))); + QTest::newRow(qPrintable(test)) << QImage::Format(i) << QImage::Format(j); + } + } } -void tst_QImage::inplaceConversion() +void tst_QImage::genericRgbConversion() +{ + // Test that all RGB conversions work and maintain at least 4bit of color accuracy. + QFETCH(QImage::Format, format); + QFETCH(QImage::Format, dest_format); + + QImage image(16, 16, format); + + for (int i = 0; i < image.height(); ++i) + for (int j = 0; j < image.width(); ++j) + image.setPixel(j, i, qRgb(j*16, i*16, 0)); + + QImage imageConverted = image.convertToFormat(dest_format); + QCOMPARE(imageConverted.format(), dest_format); + for (int i = 0; i < imageConverted.height(); ++i) { + for (int j = 0; j < imageConverted.width(); ++j) { + QRgb convertedColor = imageConverted.pixel(j,i); + QCOMPARE(qRed(convertedColor) & 0xF0, j * 16); + QCOMPARE(qGreen(convertedColor) & 0xF0, i * 16); + } + } +} + +void tst_QImage::inplaceRgbConversion_data() +{ + QTest::addColumn("format"); + QTest::addColumn("dest_format"); + + for (int i = QImage::Format_RGB32; i < QImage::Format_Alpha8; ++i) { + for (int j = QImage::Format_RGB32; j < QImage::Format_Alpha8; ++j) { + if (i == j) + continue; + QString test = QString::fromLatin1("%1 -> %2").arg(formatToString(QImage::Format(i))).arg(formatToString(QImage::Format(j))); + QTest::newRow(qPrintable(test)) << QImage::Format(i) << QImage::Format(j); + } + } +} + +void tst_QImage::inplaceRgbConversion() { // Test that conversions between RGB formats of the same bitwidth can be done inplace. #if defined(Q_COMPILER_REF_QUALIFIERS) @@ -2580,13 +2664,22 @@ void tst_QImage::inplaceConversion() QCOMPARE(qGreen(convertedColor) & 0xF0, i * 16); } } - if (image.depth() == imageConverted.depth()) + bool expectInplace = image.depth() == imageConverted.depth(); + // RGB30 <-> RGB32 have a few direct conversions without inplace counterparts. + if (format >= QImage::Format_BGR30 && format <= QImage::Format_A2RGB30_Premultiplied + && dest_format >= QImage::Format_RGB32 && dest_format <= QImage::Format_ARGB32_Premultiplied) + expectInplace = false; + if (dest_format >= QImage::Format_BGR30 && dest_format <= QImage::Format_A2RGB30_Premultiplied + && format >= QImage::Format_RGB32 && format <= QImage::Format_ARGB32_Premultiplied) + expectInplace = false; + + if (expectInplace) QCOMPARE(imageConverted.constScanLine(0), originalPtr); { // Test attempted inplace conversion of images created on existing buffer - static const quint32 readOnlyData[] = { 0x00010203U, 0x04050607U, 0x08091011U, 0x12131415U }; - quint32 readWriteData[] = { 0x00010203U, 0x04050607U, 0x08091011U, 0x12131415U }; + static const quint32 readOnlyData[] = { 0xff0102ffU, 0xff0506ffU, 0xff0910ffU, 0xff1314ffU }; + quint32 readWriteData[] = { 0xff0102ffU, 0xff0506ffU, 0xff0910ffU, 0xff1314ffU }; QImage roImage((const uchar *)readOnlyData, 2, 2, format); QImage roInplaceConverted = std::move(roImage).convertToFormat(dest_format); @@ -2708,18 +2801,9 @@ void tst_QImage::invertPixelsRGB_data() { QTest::addColumn("image_format"); - QTest::newRow("invertPixels RGB16") << QImage::Format_RGB16; - QTest::newRow("invertPixels RGB32") << QImage::Format_RGB32; - QTest::newRow("invertPixels BGR30") << QImage::Format_BGR30; - QTest::newRow("invertPixels RGB444") << QImage::Format_RGB444; - QTest::newRow("invertPixels RGB555") << QImage::Format_RGB555; - QTest::newRow("invertPixels RGB888") << QImage::Format_RGB888; - - QTest::newRow("invertPixels ARGB32") << QImage::Format_ARGB32; - QTest::newRow("invertPixels ARGB32pm") << QImage::Format_ARGB32_Premultiplied; - QTest::newRow("invertPixels RGBA8888") << QImage::Format_RGBA8888; - QTest::newRow("invertPixels RGBA8888pm") << QImage::Format_RGBA8888_Premultiplied; - QTest::newRow("invertPixels RGBA4444pm") << QImage::Format_ARGB4444_Premultiplied; + for (int i = QImage::Format_RGB32; i < QImage::Format_Alpha8; ++i) { + QTest::newRow(qPrintable(formatToString(QImage::Format(i)))) << QImage::Format(i); + } } void tst_QImage::invertPixelsRGB()