diff options
author | Allan Sandfeld Jensen <allan.jensen@theqtcompany.com> | 2015-04-21 13:49:50 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@theqtcompany.com> | 2015-05-12 11:06:41 +0000 |
commit | 8363c855f5d31c3c7499b57621d79b10bc6ba088 (patch) | |
tree | f54979bfea65176dba1dff58fa83cb48b266c257 | |
parent | 4c00a26fc583003059f1854bf1289c28c7f01bd6 (diff) | |
download | qtimageformats-8363c855f5d31c3c7499b57621d79b10bc6ba088.tar.gz |
Correctly interpret RGBA tiff images as premultiplied
The TIFFReadRGBAImageOriented method turns out to return colors with
alpha premultiplied by default. The only reason we pass our own tests
is because we also save the colors incorrectly unpremultiplied.
The patch fixes the format type of the returned images, and explictily
writes the how alpha should be interpreted in the saved files.
Change-Id: Ie1c3881acfe07eae25ca735adf243c1636f656a0
Reviewed-by: Gunnar Sletta <gunnar@sletta.org>
-rw-r--r-- | src/plugins/imageformats/tiff/qtiffhandler.cpp | 16 | ||||
-rw-r--r-- | tests/auto/tiff/tst_qtiff.cpp | 4 |
2 files changed, 14 insertions, 6 deletions
diff --git a/src/plugins/imageformats/tiff/qtiffhandler.cpp b/src/plugins/imageformats/tiff/qtiffhandler.cpp index 93fd1ed..3fc1680 100644 --- a/src/plugins/imageformats/tiff/qtiffhandler.cpp +++ b/src/plugins/imageformats/tiff/qtiffhandler.cpp @@ -232,7 +232,7 @@ bool QTiffHandlerPrivate::openForRead(QIODevice *device) else if (samplesPerPixel < 4) format = QImage::Format_RGB32; else - format = QImage::Format_ARGB32; + format = QImage::Format_ARGB32_Premultiplied; headersRead = true; return true; @@ -275,7 +275,9 @@ bool QTiffHandler::read(QImage *image) return false; QImage::Format format = d->format; - if (format == QImage::Format_RGB32 && image->format() == QImage::Format_ARGB32) + if (format == QImage::Format_RGB32 && + (image->format() == QImage::Format_ARGB32 || + image->format() == QImage::Format_ARGB32_Premultiplied)) format = image->format(); if (image->size() != d->size || image->format() != format) @@ -647,10 +649,14 @@ bool QTiffHandler::write(const QImage &image) } TIFFClose(tiff); } else { + const bool premultiplied = image.format() != QImage::Format_ARGB32 + && image.format() != QImage::Format_RGBA8888; + const uint16 extrasamples = premultiplied ? EXTRASAMPLE_ASSOCALPHA : EXTRASAMPLE_UNASSALPHA; if (!TIFFSetField(tiff, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB) || !TIFFSetField(tiff, TIFFTAG_COMPRESSION, compression == NoCompression ? COMPRESSION_NONE : COMPRESSION_LZW) || !TIFFSetField(tiff, TIFFTAG_SAMPLESPERPIXEL, 4) - || !TIFFSetField(tiff, TIFFTAG_BITSPERSAMPLE, 8)) { + || !TIFFSetField(tiff, TIFFTAG_BITSPERSAMPLE, 8) + || !TIFFSetField(tiff, TIFFTAG_EXTRASAMPLES, 1, &extrasamples)) { TIFFClose(tiff); return false; } @@ -658,9 +664,11 @@ bool QTiffHandler::write(const QImage &image) const int chunks = (width * height * 4 / (1024 * 1024 * 16)) + 1; const int chunkHeight = qMax(height / chunks, 1); + const QImage::Format format = premultiplied ? QImage::Format_RGBA8888_Premultiplied + : QImage::Format_RGBA8888; int y = 0; while (y < height) { - const QImage chunk = image.copy(0, y, width, qMin(chunkHeight, height - y)).convertToFormat(QImage::Format_RGBA8888); + const QImage chunk = image.copy(0, y, width, qMin(chunkHeight, height - y)).convertToFormat(format); int chunkStart = y; int chunkEnd = y + chunk.height(); diff --git a/tests/auto/tiff/tst_qtiff.cpp b/tests/auto/tiff/tst_qtiff.cpp index 89630c2..71c3b63 100644 --- a/tests/auto/tiff/tst_qtiff.cpp +++ b/tests/auto/tiff/tst_qtiff.cpp @@ -366,7 +366,7 @@ void tst_qtiff::readWriteNonDestructive_data() QTest::addColumn<bool>("grayscale"); QTest::newRow("tiff mono") << QImage::Format_Mono << QImage::Format_Mono << false; QTest::newRow("tiff indexed") << QImage::Format_Indexed8 << QImage::Format_Indexed8 << false; - QTest::newRow("tiff argb32") << QImage::Format_ARGB32 << QImage::Format_ARGB32 << false; + QTest::newRow("tiff argb32pm") << QImage::Format_ARGB32_Premultiplied << QImage::Format_ARGB32_Premultiplied << false; QTest::newRow("tiff rgb32") << QImage::Format_RGB32 << QImage::Format_RGB32 << false; QTest::newRow("tiff grayscale") << QImage::Format_Indexed8 << QImage::Format_Indexed8 << true; } @@ -410,7 +410,7 @@ void tst_qtiff::largeTiff() QSKIP("not tested on WinCE"); #endif - QImage img(4096, 2048, QImage::Format_ARGB32); + QImage img(4096, 2048, QImage::Format_ARGB32_Premultiplied); QPainter p(&img); img.fill(0x0); |