diff options
author | Eirik Aavitsland <eirik.aavitsland@qt.io> | 2016-07-22 11:13:41 +0200 |
---|---|---|
committer | Eirik Aavitsland <eirik.aavitsland@qt.io> | 2016-07-27 11:46:11 +0000 |
commit | 7bf002c3b3f8009138fca217c7fa0c234aed21bd (patch) | |
tree | 1fa917d4c8bf0b5851d86d6397aa3dc9577e5781 | |
parent | 5b64b64717caca231d399a138e747bdded9c116c (diff) |
Backwards compatibility fix: No default colormap for Mono QImages
This is a partial revert of a4e2f2e687ca7aec88ecf82f72d42ac61e17a5b9.
That fix tried to avoid the risk of a crash in pixel() by ensuring
Mono QImages created with external data also got a default color
table. However, that broke usable behavior in existing code that was
painting in Mono QImages using color0/color1.
This commit reverts to the old behavior, and instead expands on the
checking in pixel() so that lacking color table is handled gracefully
for all indexed formats.
Task-number: QTBUG-54827
Change-Id: I9164198bed9d20c4b12cdba40a31c141bef3128d
Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
-rw-r--r-- | src/gui/image/qimage.cpp | 42 | ||||
-rw-r--r-- | tests/auto/gui/image/qimage/tst_qimage.cpp | 38 |
2 files changed, 56 insertions, 24 deletions
diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp index 60d402289d..ee77a32b86 100644 --- a/src/gui/image/qimage.cpp +++ b/src/gui/image/qimage.cpp @@ -828,17 +828,6 @@ QImageData *QImageData::create(uchar *data, int width, int height, int bpl, QIm d->cleanupFunction = cleanupFunction; d->cleanupInfo = cleanupInfo; - switch (format) { - case QImage::Format_Mono: - case QImage::Format_MonoLSB: - d->colortable.resize(2); - d->colortable[0] = QColor(Qt::black).rgba(); - d->colortable[1] = QColor(Qt::white).rgba(); - break; - default: - break; - } - return d; } @@ -2237,21 +2226,30 @@ QRgb QImage::pixel(int x, int y) const } const uchar *s = d->data + y * d->bytes_per_line; - switch(d->format) { + + int index = -1; + switch (d->format) { case Format_Mono: - return d->colortable.at((*(s + (x >> 3)) >> (~x & 7)) & 1); + index = (*(s + (x >> 3)) >> (~x & 7)) & 1; + break; case Format_MonoLSB: - return d->colortable.at((*(s + (x >> 3)) >> (x & 7)) & 1); + index = (*(s + (x >> 3)) >> (x & 7)) & 1; + break; case Format_Indexed8: - { - int index = (int)s[x]; - if (index < d->colortable.size()) { - return d->colortable.at(index); - } else { - qWarning("QImage::pixel: color table index %d out of range.", index); - return 0; - } + index = s[x]; + break; + default: + break; + } + if (index >= 0) { // Indexed format + if (index >= d->colortable.size()) { + qWarning("QImage::pixel: color table index %d out of range.", index); + return 0; } + return d->colortable.at(index); + } + + switch (d->format) { case Format_RGB32: return 0xff000000 | reinterpret_cast<const QRgb *>(s)[x]; case Format_ARGB32: // Keep old behaviour. diff --git a/tests/auto/gui/image/qimage/tst_qimage.cpp b/tests/auto/gui/image/qimage/tst_qimage.cpp index 435178a885..6f088bea24 100644 --- a/tests/auto/gui/image/qimage/tst_qimage.cpp +++ b/tests/auto/gui/image/qimage/tst_qimage.cpp @@ -99,6 +99,8 @@ private slots: void setPixel_data(); void setPixel(); + void defaultColorTable_data(); + void defaultColorTable(); void setColorCount(); void setColor(); @@ -1450,6 +1452,38 @@ void tst_QImage::convertToFormatPreserveText() QCOMPARE(imgResult2.textKeys(), listResult); } +void tst_QImage::defaultColorTable_data() +{ + QTest::addColumn<QImage::Format>("format"); + QTest::addColumn<int>("createdDataCount"); + QTest::addColumn<int>("externalDataCount"); + + // For historical reasons, internally created mono images get a default colormap. + // Externally created and Indexed8 images do not. + QTest::newRow("Mono") << QImage::Format_Mono << 2 << 0; + QTest::newRow("MonoLSB") << QImage::Format_MonoLSB << 2 << 0; + QTest::newRow("Indexed8") << QImage::Format_Indexed8 << 0 << 0; + QTest::newRow("ARGB32_PM") << QImage::Format_A2BGR30_Premultiplied << 0 << 0; +} + +void tst_QImage::defaultColorTable() +{ + QFETCH(QImage::Format, format); + QFETCH(int, createdDataCount); + QFETCH(int, externalDataCount); + + QImage img1(1, 1, format); + QCOMPARE(img1.colorCount(), createdDataCount); + QCOMPARE(img1.colorTable().size(), createdDataCount); + + quint32 buf; + QImage img2(reinterpret_cast<uchar *>(&buf), 1, 1, format); + QCOMPARE(img2.colorCount(), externalDataCount); + + QImage nullImg(0, 0, format); + QCOMPARE(nullImg.colorCount(), 0); +} + void tst_QImage::setColorCount() { QImage img(0, 0, QImage::Format_Indexed8); @@ -3127,8 +3161,8 @@ void tst_QImage::pixel() QImage monolsb(&a, 1, 1, QImage::Format_MonoLSB); QImage indexed(&a, 1, 1, QImage::Format_Indexed8); - QCOMPARE(QColor(mono.pixel(0, 0)), QColor(Qt::black)); - QCOMPARE(QColor(monolsb.pixel(0, 0)), QColor(Qt::black)); + mono.pixel(0, 0); // Don't crash + monolsb.pixel(0, 0); // Don't crash indexed.pixel(0, 0); // Don't crash } } |