summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@theqtcompany.com>2015-04-21 13:49:50 +0200
committerAllan Sandfeld Jensen <allan.jensen@theqtcompany.com>2015-05-12 11:06:41 +0000
commit8363c855f5d31c3c7499b57621d79b10bc6ba088 (patch)
treef54979bfea65176dba1dff58fa83cb48b266c257
parent4c00a26fc583003059f1854bf1289c28c7f01bd6 (diff)
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.cpp16
-rw-r--r--tests/auto/tiff/tst_qtiff.cpp4
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);