From b28764c641e4fef19d5e800b7537439fb2054914 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Fri, 3 Jan 2014 14:46:07 +0100 Subject: Inplace versions of QImage rgbSwapped() and mirrored() for rvalue refs Adds inplace version of QImage::rgbSwapped() and QImage::mirrored() that can be used on temporary QImage objects when supported by the compiler. [ChangeLog][QtGui][QImage]Rvalue qualified mirrored and rgbSwapped methods for inline conversions Change-Id: I4ffb658bf620dfc472d9db14c1aa70291c1fd842 Reviewed-by: Gunnar Sletta --- tests/auto/gui/image/qimage/qimage.pro | 1 + tests/auto/gui/image/qimage/tst_qimage.cpp | 251 +++++++++++++++++++++++++++++ 2 files changed, 252 insertions(+) (limited to 'tests/auto') diff --git a/tests/auto/gui/image/qimage/qimage.pro b/tests/auto/gui/image/qimage/qimage.pro index 467a59ec9f..117e34653d 100644 --- a/tests/auto/gui/image/qimage/qimage.pro +++ b/tests/auto/gui/image/qimage/qimage.pro @@ -4,5 +4,6 @@ TARGET = tst_qimage SOURCES += tst_qimage.cpp QT += core-private gui-private testlib +contains(QT_CONFIG, c++11): CONFIG += c++11 TESTDATA += images/* diff --git a/tests/auto/gui/image/qimage/tst_qimage.cpp b/tests/auto/gui/image/qimage/tst_qimage.cpp index 7fdb2f4cba..5016abff4f 100644 --- a/tests/auto/gui/image/qimage/tst_qimage.cpp +++ b/tests/auto/gui/image/qimage/tst_qimage.cpp @@ -149,6 +149,17 @@ private slots: void rgbSwapped_data(); void rgbSwapped(); + void mirrored_data(); + void mirrored(); + + void inplaceRgbSwapped_data(); + void inplaceRgbSwapped(); + + void inplaceMirrored_data(); + void inplaceMirrored(); + + void inplaceDoubleConversion(); + void deepCopyWhenPaintingActive(); void scaled_QTBUG19157(); @@ -2106,6 +2117,246 @@ void tst_QImage::rgbSwapped() QCOMPARE(memcmp(image.constBits(), imageSwappedTwice.constBits(), image.byteCount()), 0); } +void tst_QImage::mirrored_data() +{ + QTest::addColumn("format"); + QTest::addColumn("swap_vertical"); + QTest::addColumn("swap_horizontal"); + + QTest::newRow("Format_RGB32, vertical") << QImage::Format_RGB32 << true << false; + QTest::newRow("Format_ARGB32, vertical") << QImage::Format_ARGB32 << true << false; + QTest::newRow("Format_ARGB32_Premultiplied, vertical") << QImage::Format_ARGB32_Premultiplied << true << false; + QTest::newRow("Format_RGB16, vertical") << QImage::Format_RGB16 << true << false; + QTest::newRow("Format_ARGB8565_Premultiplied, vertical") << QImage::Format_ARGB8565_Premultiplied << true << false; + QTest::newRow("Format_ARGB6666_Premultiplied, vertical") << QImage::Format_ARGB6666_Premultiplied << true << false; + QTest::newRow("Format_ARGB4444_Premultiplied, vertical") << QImage::Format_ARGB4444_Premultiplied << true << false; + QTest::newRow("Format_RGB666, vertical") << QImage::Format_RGB666 << true << false; + QTest::newRow("Format_RGB555, vertical") << QImage::Format_RGB555 << true << false; + QTest::newRow("Format_ARGB8555_Premultiplied, vertical") << QImage::Format_ARGB8555_Premultiplied << true << false; + QTest::newRow("Format_RGB888, vertical") << QImage::Format_RGB888 << true << false; + QTest::newRow("Format_RGB444, vertical") << QImage::Format_RGB444 << true << false; + QTest::newRow("Format_RGBX8888, vertical") << QImage::Format_RGBX8888 << true << false; + QTest::newRow("Format_RGBA8888_Premultiplied, vertical") << QImage::Format_RGBA8888_Premultiplied << 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_Premultiplied, horizontal") << QImage::Format_ARGB32_Premultiplied << 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_Premultiplied, horizontal+vertical") << QImage::Format_ARGB32_Premultiplied << 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; +} + +void tst_QImage::mirrored() +{ + QFETCH(QImage::Format, format); + QFETCH(bool, swap_vertical); + QFETCH(bool, swap_horizontal); + + QImage image(16, 16, format); + + switch (format) { + case QImage::Format_Mono: + for (int i = 0; i < image.height(); ++i) { + ushort* scanLine = (ushort*)image.scanLine(i); + *scanLine = (i % 2) ? 0x5555U : 0xCCCCU; + } + break; + case QImage::Format_Indexed8: + for (int i = 0; i < image.height(); ++i) { + for (int j = 0; j < image.width(); ++j) { + image.setColor(i*16+j, qRgb(j*16, i*16, 0)); + image.setPixel(j, i, i*16+j); + } + } + break; + default: + 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)); + break; + } + + QImage imageMirrored = image.mirrored(swap_horizontal, swap_vertical); + + for (int i = 0; i < image.height(); ++i) { + int mirroredI = swap_vertical ? (image.height() - i - 1) : i; + for (int j = 0; j < image.width(); ++j) { + QRgb referenceColor = image.pixel(j, i); + int mirroredJ = swap_horizontal ? (image.width() - j - 1) : j; + QRgb mirroredColor = imageMirrored.pixel(mirroredJ, mirroredI); + QCOMPARE(mirroredColor, referenceColor); + } + } + + QImage imageMirroredTwice = imageMirrored.mirrored(swap_horizontal, swap_vertical); + + QCOMPARE(image, imageMirroredTwice); + + if (format != QImage::Format_Mono) + QCOMPARE(memcmp(image.constBits(), imageMirroredTwice.constBits(), image.byteCount()), 0); + else { + for (int i = 0; i < image.height(); ++i) + for (int j = 0; j < image.width(); ++j) + QCOMPARE(image.pixel(j,i), imageMirroredTwice.pixel(j,i)); + } +} + +void tst_QImage::inplaceRgbSwapped_data() +{ + QTest::addColumn("format"); + + QTest::newRow("Format_ARGB32_Premultiplied") << QImage::Format_ARGB32_Premultiplied; + QTest::newRow("Format_RGBA8888") << QImage::Format_RGBA8888; + QTest::newRow("Format_RGB888") << QImage::Format_RGB888; + QTest::newRow("Format_RGB16") << QImage::Format_RGB16; + QTest::newRow("Format_Indexed8") << QImage::Format_Indexed8; +} + +void tst_QImage::inplaceRgbSwapped() +{ +#if defined(Q_COMPILER_REF_QUALIFIERS) + QFETCH(QImage::Format, format); + + QImage image(64, 1, format); + image.fill(0); + + QVector testColor(image.width()); + for (int i = 0; i < image.width(); ++i) + testColor[i] = qRgb(i * 2, i * 3, 255 - i * 4); + + if (format == QImage::Format_Indexed8) { + for (int i = 0; i < image.width(); ++i) { + image.setColor(i, testColor[i]); + image.setPixel(i, 0, i); + } + } else { + for (int i = 0; i < image.width(); ++i) + image.setPixel(i, 0, testColor[i]); + } + + const uchar* orginalPtr = image.constScanLine(0); + QImage imageSwapped = std::move(image).rgbSwapped(); + + for (int i = 0; i < imageSwapped.width(); ++i) { + QRgb referenceColor = testColor[i]; + QRgb swappedColor = imageSwapped.pixel(i, 0); + QCOMPARE(qRed(swappedColor) & 0xf8, qBlue(referenceColor) & 0xf8); + QCOMPARE(qGreen(swappedColor) & 0xf8, qGreen(referenceColor) & 0xf8); + QCOMPARE(qBlue(swappedColor) & 0xf8, qRed(referenceColor) & 0xf8); + } + + QCOMPARE(imageSwapped.constScanLine(0), orginalPtr); +#endif +} + + +void tst_QImage::inplaceMirrored_data() +{ + QTest::addColumn("format"); + 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; +} + +void tst_QImage::inplaceMirrored() +{ +#if defined(Q_COMPILER_REF_QUALIFIERS) + QFETCH(QImage::Format, format); + QFETCH(bool, swap_vertical); + QFETCH(bool, swap_horizontal); + + QImage image(16, 16, format); + + switch (format) { + case QImage::Format_Mono: + for (int i = 0; i < image.height(); ++i) { + ushort* scanLine = (ushort*)image.scanLine(i); + *scanLine = (i % 2) ? 0x0fffU : 0xf000U; + } + break; + case QImage::Format_Indexed8: + for (int i = 0; i < image.height(); ++i) { + for (int j = 0; j < image.width(); ++j) { + image.setColor(i*16+j, qRgb(j*16, i*16, 0)); + image.setPixel(j, i, i*16+j); + } + } + break; + default: + 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)); + } + + const uchar* originalPtr = image.constScanLine(0); + + QImage imageMirrored = std::move(image).mirrored(swap_horizontal, swap_vertical); + if (format != QImage::Format_Mono) { + 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) { + int mirroredJ = swap_horizontal ? (imageMirrored.width() - j - 1) : j; + QRgb mirroredColor = imageMirrored.pixel(mirroredJ, mirroredI); + QCOMPARE(qRed(mirroredColor) & 0xF8, j * 16); + QCOMPARE(qGreen(mirroredColor) & 0xF8, i * 16); + } + } + } else { + for (int i = 0; i < imageMirrored.height(); ++i) { + ushort* scanLine = (ushort*)imageMirrored.scanLine(i); + ushort expect; + if (swap_vertical && swap_horizontal) + expect = (i % 2) ? 0x000fU : 0xfff0U; + else if (swap_vertical) + expect = (i % 2) ? 0xf000U : 0x0fffU; + else + expect = (i % 2) ? 0xfff0U : 0x000fU; + QCOMPARE(*scanLine, expect); + } + } + QCOMPARE(imageMirrored.constScanLine(0), originalPtr); +#endif +} + +void tst_QImage::inplaceDoubleConversion() +{ +#if defined(Q_COMPILER_REF_QUALIFIERS) + QImage image1(32, 32, QImage::Format_ARGB32); + QImage image2(32, 32, QImage::Format_ARGB32); + image1.fill(0); + image2.fill(0); + const uchar* originalPtr1 = image1.constScanLine(0); + const uchar* originalPtr2 = image2.constScanLine(0); + + QCOMPARE(std::move(image1).rgbSwapped().mirrored().constScanLine(0), originalPtr1); + QCOMPARE(std::move(image2).mirrored().rgbSwapped().constScanLine(0), originalPtr2); +#endif +} + void tst_QImage::deepCopyWhenPaintingActive() { QImage image(64, 64, QImage::Format_ARGB32_Premultiplied); -- cgit v1.2.3