diff options
-rw-r--r-- | src/gui/image/qimage.cpp | 12 | ||||
-rw-r--r-- | tests/auto/gui/image/qimage/tst_qimage.cpp | 51 |
2 files changed, 61 insertions, 2 deletions
diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp index f20800440d..f09e73f214 100644 --- a/src/gui/image/qimage.cpp +++ b/src/gui/image/qimage.cpp @@ -2825,14 +2825,22 @@ template<class T> inline void do_mirror_data(QImageData *dst, QImageData *src, if (dst == src) { // When mirroring in-place, stop in the middle for one of the directions, since we // are swapping the bytes instead of merely copying. - const int srcXEnd = dstX0 ? w / 2 : w; - const int srcYEnd = !dstX0 && dstY0 ? h / 2 : h; + const int srcXEnd = (dstX0 && !dstY0) ? w / 2 : w; + const int srcYEnd = dstY0 ? h / 2 : h; for (int srcY = 0, dstY = dstY0; srcY < srcYEnd; ++srcY, dstY += dstYIncr) { T *srcPtr = (T *) (src->data + srcY * src->bytes_per_line); T *dstPtr = (T *) (dst->data + dstY * dst->bytes_per_line); for (int srcX = 0, dstX = dstX0; srcX < srcXEnd; ++srcX, dstX += dstXIncr) std::swap(srcPtr[srcX], dstPtr[dstX]); } + // If mirroring both ways, the middle line needs to be mirrored horizontally only. + if (dstX0 && dstY0 && (h & 1)) { + int srcY = h / 2; + int srcXEnd2 = w / 2; + T *srcPtr = (T *) (src->data + srcY * src->bytes_per_line); + for (int srcX = 0, dstX = dstX0; srcX < srcXEnd2; ++srcX, dstX += dstXIncr) + std::swap(srcPtr[srcX], srcPtr[dstX]); + } } else { for (int srcY = 0, dstY = dstY0; srcY < h; ++srcY, dstY += dstYIncr) { T *srcPtr = (T *) (src->data + srcY * src->bytes_per_line); diff --git a/tests/auto/gui/image/qimage/tst_qimage.cpp b/tests/auto/gui/image/qimage/tst_qimage.cpp index 525d5b33a0..5691a654d7 100644 --- a/tests/auto/gui/image/qimage/tst_qimage.cpp +++ b/tests/auto/gui/image/qimage/tst_qimage.cpp @@ -155,6 +155,9 @@ private slots: void inplaceMirrored_data(); void inplaceMirrored(); + void inplaceMirroredOdd_data(); + void inplaceMirroredOdd(); + void inplaceRgbMirrored(); void inplaceConversion_data(); @@ -2471,6 +2474,54 @@ void tst_QImage::inplaceMirrored() #endif } +void tst_QImage::inplaceMirroredOdd_data() +{ + QTest::addColumn<QImage::Format>("format"); + QTest::addColumn<bool>("swap_vertical"); + QTest::addColumn<bool>("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_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_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; +} + +void tst_QImage::inplaceMirroredOdd() +{ +#if defined(Q_COMPILER_REF_QUALIFIERS) + QFETCH(QImage::Format, format); + QFETCH(bool, swap_vertical); + QFETCH(bool, swap_horizontal); + + QImage image(15, 15, 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)); + + const uchar* originalPtr = image.constScanLine(0); + + QImage imageMirrored = std::move(image).mirrored(swap_horizontal, swap_vertical); + 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); + } + } + QCOMPARE(imageMirrored.constScanLine(0), originalPtr); +#endif +} + void tst_QImage::inplaceRgbMirrored() { #if defined(Q_COMPILER_REF_QUALIFIERS) |