Correct QImage::fill(uint) on RGBA8888 formats

QImage::fill(uint) was incorrectly performing ARGB->RGBA conversion when
called on RGBA8888 formated images.

This patch moves the color conversion to QImage::fill(QColor) where it
belongs so that fill(uint) can behave consistent with documentation and
how it treats other formats.

The fill(uint) method had no automated tests, and this patch adds one.

[ChangeLog][QtGui][QImage] QImage::fill(uint) now fills the given pixel
value unconverted when used on RGBA8888 image, making it consistent with
the documentation and treatment of all other image formats.

Change-Id: I00a9d810c61d350dbdd7c4b9ad09e5ce11896b6d
Reviewed-by: Gunnar Sletta <gunnar.sletta@jollamobile.com>
bb10
Allan Sandfeld Jensen 2014-06-17 13:31:00 +02:00
parent e98c461d43
commit 70dd563046
2 changed files with 77 additions and 26 deletions

View File

@ -1662,11 +1662,14 @@ void QImage::fill(uint pixel)
return;
}
if (d->format == Format_RGB32 || d->format == Format_RGBX8888)
if (d->format == Format_RGB32)
pixel |= 0xff000000;
if (d->format == Format_RGBX8888 || d->format == Format_RGBA8888 || d->format == Format_RGBA8888_Premultiplied)
pixel = ARGB2RGBA(pixel);
if (d->format == Format_RGBX8888)
#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
pixel |= 0xff000000;
#else
pixel |= 0x000000ff;
#endif
qt_rectfill<uint>(reinterpret_cast<uint*>(d->data), pixel,
0, 0, d->width, d->height, d->bytes_per_line);
@ -1716,22 +1719,27 @@ void QImage::fill(const QColor &color)
if (!d)
return;
if (d->depth == 32) {
uint pixel = color.rgba();
if (d->format == QImage::Format_ARGB32_Premultiplied || d->format == QImage::Format_RGBA8888_Premultiplied)
pixel = qPremultiply(pixel);
fill((uint) pixel);
} else if (d->format == QImage::Format_RGB16) {
switch (d->format) {
case QImage::Format_RGB32:
case QImage::Format_ARGB32:
fill(color.rgba());
break;
case QImage::Format_ARGB32_Premultiplied:
fill(qPremultiply(color.rgba()));
break;
case QImage::Format_RGBX8888:
fill(ARGB2RGBA(color.rgba() | 0xff000000));
break;
case QImage::Format_RGBA8888:
fill(ARGB2RGBA(color.rgba()));
break;
case QImage::Format_RGBA8888_Premultiplied:
fill(ARGB2RGBA(qPremultiply(color.rgba())));
break;
case QImage::Format_RGB16:
fill((uint) qConvertRgb32To16(color.rgba()));
} else if (d->depth == 1) {
if (color == Qt::color1)
fill((uint) 1);
else
fill((uint) 0);
} else if (d->depth == 8) {
break;
case QImage::Format_Indexed8: {
uint pixel = 0;
for (int i=0; i<d->colortable.size(); ++i) {
if (color.rgba() == d->colortable.at(i)) {
@ -1740,20 +1748,24 @@ void QImage::fill(const QColor &color)
}
}
fill(pixel);
} else {
break;
}
case QImage::Format_Mono:
case QImage::Format_MonoLSB:
if (color == Qt::color1)
fill((uint) 1);
else
fill((uint) 0);
break;
default: {
QPainter p(this);
p.setCompositionMode(QPainter::CompositionMode_Source);
p.fillRect(rect(), color);
}
}}
}
/*!
Inverts all pixel values in the image.

View File

@ -146,6 +146,9 @@ private slots:
void fillRGB888();
void fillPixel_data();
void fillPixel();
void rgbSwapped_data();
void rgbSwapped();
@ -2054,6 +2057,42 @@ void tst_QImage::fillRGB888()
}
}
void tst_QImage::fillPixel_data()
{
QTest::addColumn<QImage::Format>("format");
QTest::addColumn<uint>("color");
QTest::addColumn<uint>("pixelValue");
QTest::newRow("RGB16, transparent") << QImage::Format_RGB16 << 0x0u << 0xff000000u;
QTest::newRow("RGB32, transparent") << QImage::Format_RGB32 << 0x0u << 0xff000000u;
QTest::newRow("RGBx8888, transparent") << QImage::Format_RGBX8888 << 0x0u << 0xff000000u;
QTest::newRow("ARGB32, transparent") << QImage::Format_ARGB32 << 0x0u << 0x00000000u;
QTest::newRow("ARGB32pm, transparent") << QImage::Format_ARGB32_Premultiplied << 0x0u << 0x00000000u;
QTest::newRow("RGBA8888pm, transparent") << QImage::Format_RGBA8888_Premultiplied << 0x0u << 0x00000000u;
QTest::newRow("RGB16, red") << QImage::Format_RGB16 << (uint)qConvertRgb32To16(0xffff0000) << 0xffff0000u;
QTest::newRow("RGB32, red") << QImage::Format_RGB32 << 0xffff0000u << 0xffff0000u;
QTest::newRow("ARGB32, red") << QImage::Format_ARGB32 << 0xffff0000u << 0xffff0000u;
QTest::newRow("RGBA8888, red") << QImage::Format_RGBA8888 << 0xff0000ffu << 0xffff0000u;
QTest::newRow("RGB32, semi-red") << QImage::Format_RGB32 << 0x80ff0000u << 0xffff0000u;
QTest::newRow("ARGB32, semi-red") << QImage::Format_ARGB32 << 0x80ff0000u << 0x80ff0000u;
QTest::newRow("ARGB32pm, semi-red") << QImage::Format_ARGB32 << 0x80800000u << 0x80800000u;
QTest::newRow("RGBA8888pm, semi-red") << QImage::Format_RGBA8888_Premultiplied << 0x80000080u << 0x80800000u;
}
void tst_QImage::fillPixel()
{
QFETCH(QImage::Format, format);
QFETCH(uint, color);
QFETCH(uint, pixelValue);
QImage image(1, 1, format);
image.fill(color);
QCOMPARE(image.pixel(0, 0), pixelValue);
}
void tst_QImage::rgbSwapped_data()
{
QTest::addColumn<QImage::Format>("format");