Fix inplace double mirroring on odd sized images
The QImage inplace mirroring method, failed to handle the middle line when mirroring both ways (rotate 180). In both other mirroring cases the middle can be left untouched, but in this case it needs to be mirrored half way. To make the logic simpler, double mirroring will now mirror half the lines instead of half of every line. Change-Id: Iaa1f1e1c3f7dedfb78891fc93207f6d0c64bcafe Reviewed-by: Konstantin Ritt <ritt.ks@gmail.com> Reviewed-by: Gunnar Sletta <gunnar@sletta.org>
This commit is contained in:
parent
c3737573ce
commit
f657ecdc5d
@ -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);
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user