From f1983dcdf6c596f901694ad16dcd3c74c77f4c13 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Wed, 28 Apr 2021 12:40:11 +0200 Subject: Correct RGB to Grayscale conversion The existing conversions weren't handling gamma correctly and used an ad-hoc definition of gray instead of based on true luminance. [ChangeLog][QtGui] RGB conversions to grayscale formats are now gamma-corrected and produce color-space luminance values Change-Id: I88ab870c8f5e502ddb053e6a14a75102239a26f2 Reviewed-by: Lars Knoll --- tests/auto/gui/image/qimage/tst_qimage.cpp | 29 ++++++++++++++-------- .../gui/image/qimagewriter/tst_qimagewriter.cpp | 8 +++++- 2 files changed, 25 insertions(+), 12 deletions(-) (limited to 'tests/auto/gui') diff --git a/tests/auto/gui/image/qimage/tst_qimage.cpp b/tests/auto/gui/image/qimage/tst_qimage.cpp index 0fb4263024..c3096bd47f 100644 --- a/tests/auto/gui/image/qimage/tst_qimage.cpp +++ b/tests/auto/gui/image/qimage/tst_qimage.cpp @@ -2951,21 +2951,29 @@ void tst_QImage::genericRgbConversion() QImage image(16, 16, 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)); + for (int i = 0; i < image.height(); ++i) { + for (int j = 0; j < image.width(); ++j) { + if (srcGrayscale || dstGrayscale) + image.setPixel(j, i, qRgb((i + j) * 8, (i + j) * 8, (i + j) * 8)); + else + image.setPixel(j, i, qRgb(j * 16, i * 16, (i + j) * 8)); + } + } QImage imageConverted = image.convertToFormat(dest_format); + uint mask = std::min(image.depth(), imageConverted.depth()) < 32 ? 0xFFF0F0F0 : 0xFFFFFFFF; + if (srcGrayscale || dstGrayscale) + mask = std::max(image.depth(), imageConverted.depth()) < 32 ? 0xFFF0F0F0 : 0xFFFFFFFF; + if (srcGrayscale && dstGrayscale) + mask = 0xFFFFFFFF; QCOMPARE(imageConverted.format(), dest_format); for (int i = 0; i < imageConverted.height(); ++i) { for (int j = 0; j < imageConverted.width(); ++j) { QRgb convertedColor = imageConverted.pixel(j,i); - if (srcGrayscale || dstGrayscale) { - QVERIFY(qAbs(qGray(convertedColor) - qGray(qRgb(j*16, i*16, 0))) < 15); - } else { - QCOMPARE(qRed(convertedColor) & 0xF0, j * 16); - QCOMPARE(qGreen(convertedColor) & 0xF0, i * 16); - } + if (srcGrayscale || dstGrayscale) + QCOMPARE(convertedColor & mask, qRgb((i + j) * 8, (i + j) * 8, (i + j) * 8) & mask); + else + QCOMPARE(convertedColor & mask, qRgb(j * 16, i * 16, (i + j) * 8) & mask); } } } @@ -3014,8 +3022,7 @@ void tst_QImage::inplaceRgbConversion() for (int i = 0; i < imageConverted.height(); ++i) { for (int j = 0; j < imageConverted.width(); ++j) { QRgb convertedColor = imageConverted.pixel(j,i); - QCOMPARE(qRed(convertedColor) & 0xF0, j * 16); - QCOMPARE(qGreen(convertedColor) & 0xF0, i * 16); + QCOMPARE(convertedColor & 0xFFF0F0F0, qRgb(j * 16, i * 16, 0)); } } if (qt_depthForFormat(format) == qt_depthForFormat(dest_format)) diff --git a/tests/auto/gui/image/qimagewriter/tst_qimagewriter.cpp b/tests/auto/gui/image/qimagewriter/tst_qimagewriter.cpp index 907719259d..49a4504d2a 100644 --- a/tests/auto/gui/image/qimagewriter/tst_qimagewriter.cpp +++ b/tests/auto/gui/image/qimagewriter/tst_qimagewriter.cpp @@ -291,7 +291,13 @@ void tst_QImageWriter::writeImage2() QVERIFY(reader.read(&written)); } - written = written.convertToFormat(image.format()); + // The 8-bit input value might have turned into a fraction in 16-bit grayscale + // which can't be preserved in file formats that doesn't support 16bpc. + if (image.format() == QImage::Format_Grayscale16 && + written.format() != QImage::Format_Grayscale16 && written.depth() <= 32) + image.convertTo(QImage::Format_Grayscale8); + + written.convertTo(image.format()); if (!equalImageContents(written, image)) { qDebug() << "image" << image.format() << image.width() << image.height() << image.depth() -- cgit v1.2.3