summaryrefslogtreecommitdiffstats
path: root/src
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 /src
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>
Diffstat (limited to 'src')
-rw-r--r--src/plugins/imageformats/tiff/qtiffhandler.cpp16
1 files changed, 12 insertions, 4 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();