summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@theqtcompany.com>2015-04-21 13:07:11 +0200
committerAllan Sandfeld Jensen <allan.jensen@theqtcompany.com>2015-05-29 13:24:02 +0000
commit454fb13c465e29f0d0f9a295bdb822b4a09c7e48 (patch)
tree33504ec71e798e0e5b6613ce23298e3df57e99ec
parent40e9ba00a05d3a0ef0aa401565d7129eaa476ee6 (diff)
Handle Grayscale8 TIFFs
Correctly read and write Grayscale8 image format. Change-Id: I537c68f94077458c69ee1de08b5b37986b54aa26 Reviewed-by: Ivan Komissarov <ABBAPOH@gmail.com> Reviewed-by: Gunnar Sletta <gunnar@sletta.org>
-rw-r--r--src/plugins/imageformats/tiff/qtiffhandler.cpp43
-rw-r--r--tests/auto/tiff/tst_qtiff.cpp20
2 files changed, 45 insertions, 18 deletions
diff --git a/src/plugins/imageformats/tiff/qtiffhandler.cpp b/src/plugins/imageformats/tiff/qtiffhandler.cpp
index ceb6935..a6b87af 100644
--- a/src/plugins/imageformats/tiff/qtiffhandler.cpp
+++ b/src/plugins/imageformats/tiff/qtiffhandler.cpp
@@ -245,6 +245,8 @@ bool QTiffHandlerPrivate::openForRead(QIODevice *device)
if (grayscale && bitPerSample == 1 && samplesPerPixel == 1)
format = QImage::Format_Mono;
+ else if (photometric == PHOTOMETRIC_MINISBLACK && bitPerSample == 8 && samplesPerPixel == 1)
+ format = QImage::Format_Grayscale8;
else if ((grayscale || photometric == PHOTOMETRIC_PALETTE) && bitPerSample == 8 && samplesPerPixel == 1)
format = QImage::Format_Indexed8;
else if (samplesPerPixel < 4)
@@ -366,6 +368,15 @@ bool QTiffHandler::read(QImage *image)
// free redTable, greenTable and greenTable done by libtiff
}
+ } else if (format == QImage::Format_Grayscale8) {
+ if (!image->isNull()) {
+ for (uint32 y = 0; y < height; ++y) {
+ if (TIFFReadScanline(tiff, image->scanLine(y), y, 0) < 0) {
+ d->close();
+ return false;
+ }
+ }
+ }
} else {
if (!image->isNull()) {
const int stopOnError = 1;
@@ -428,6 +439,29 @@ static bool checkGrayscale(const QVector<QRgb> &colorTable)
return true;
}
+static QVector<QRgb> effectiveColorTable(const QImage &image)
+{
+ QVector<QRgb> colors;
+ switch (image.format()) {
+ case QImage::Format_Indexed8:
+ colors = image.colorTable();
+ break;
+ case QImage::Format_Alpha8:
+ colors.resize(256);
+ for (int i = 0; i < 256; ++i)
+ colors[i] = qRgba(0, 0, 0, i);
+ break;
+ case QImage::Format_Grayscale8:
+ colors.resize(256);
+ for (int i = 0; i < 256; ++i)
+ colors[i] = qRgb(i, i, i);
+ break;
+ default:
+ Q_UNREACHABLE();
+ }
+ return colors;
+}
+
bool QTiffHandler::write(const QImage &image)
{
if (!device()->isWritable())
@@ -515,12 +549,14 @@ bool QTiffHandler::write(const QImage &image)
}
}
TIFFClose(tiff);
- } else if (format == QImage::Format_Indexed8) {
- const QVector<QRgb> colorTable = image.colorTable();
+ } else if (format == QImage::Format_Indexed8
+ || format == QImage::Format_Grayscale8
+ || format == QImage::Format_Alpha8) {
+ QVector<QRgb> colorTable = effectiveColorTable(image);
bool isGrayscale = checkGrayscale(colorTable);
if (isGrayscale) {
uint16 photometric = PHOTOMETRIC_MINISBLACK;
- if (image.colorTable().at(0) == 0xffffffff)
+ if (colorTable.at(0) == 0xffffffff)
photometric = PHOTOMETRIC_MINISWHITE;
if (!TIFFSetField(tiff, TIFFTAG_PHOTOMETRIC, photometric)
|| !TIFFSetField(tiff, TIFFTAG_COMPRESSION, compression == NoCompression ? COMPRESSION_NONE : COMPRESSION_PACKBITS)
@@ -579,7 +615,6 @@ bool QTiffHandler::write(const QImage &image)
}
}
TIFFClose(tiff);
-
} else if (!image.hasAlphaChannel()) {
if (!TIFFSetField(tiff, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB)
|| !TIFFSetField(tiff, TIFFTAG_COMPRESSION, compression == NoCompression ? COMPRESSION_NONE : COMPRESSION_LZW)
diff --git a/tests/auto/tiff/tst_qtiff.cpp b/tests/auto/tiff/tst_qtiff.cpp
index a073025..70837a5 100644
--- a/tests/auto/tiff/tst_qtiff.cpp
+++ b/tests/auto/tiff/tst_qtiff.cpp
@@ -364,31 +364,23 @@ void tst_qtiff::readWriteNonDestructive_data()
{
QTest::addColumn<QImage::Format>("format");
QTest::addColumn<QImage::Format>("expectedFormat");
- QTest::addColumn<bool>("grayscale");
QTest::addColumn<QImageIOHandler::Transformation>("transformation");
- QTest::newRow("tiff mono") << QImage::Format_Mono << QImage::Format_Mono << false << QImageIOHandler::TransformationNone;
- QTest::newRow("tiff indexed") << QImage::Format_Indexed8 << QImage::Format_Indexed8 << false << QImageIOHandler::TransformationMirror;
- QTest::newRow("tiff argb32pm") << QImage::Format_ARGB32_Premultiplied << QImage::Format_ARGB32_Premultiplied << false << QImageIOHandler::TransformationRotate90;
- QTest::newRow("tiff rgb32") << QImage::Format_RGB32 << QImage::Format_RGB32 << false << QImageIOHandler::TransformationRotate270;
- QTest::newRow("tiff grayscale") << QImage::Format_Indexed8 << QImage::Format_Indexed8 << true << QImageIOHandler::TransformationFlip;
+ QTest::newRow("tiff mono") << QImage::Format_Mono << QImage::Format_Mono << QImageIOHandler::TransformationNone;
+ QTest::newRow("tiff indexed") << QImage::Format_Indexed8 << QImage::Format_Indexed8 << QImageIOHandler::TransformationMirror;
+ QTest::newRow("tiff argb32pm") << QImage::Format_ARGB32_Premultiplied << QImage::Format_ARGB32_Premultiplied << QImageIOHandler::TransformationRotate90;
+ QTest::newRow("tiff rgb32") << QImage::Format_RGB32 << QImage::Format_RGB32 << QImageIOHandler::TransformationRotate270;
+ QTest::newRow("tiff grayscale") << QImage::Format_Grayscale8 << QImage::Format_Grayscale8 << QImageIOHandler::TransformationFlip;
}
void tst_qtiff::readWriteNonDestructive()
{
QFETCH(QImage::Format, format);
QFETCH(QImage::Format, expectedFormat);
- QFETCH(bool, grayscale);
QFETCH(QImageIOHandler::Transformation, transformation);
+
QImage image = QImage(prefix + "colorful.bmp").convertToFormat(format);
QVERIFY(!image.isNull());
- if (grayscale) {
- QVector<QRgb> colors;
- for (int i = 0; i < 256; ++i)
- colors << qRgb(i, i, i);
- image.setColorTable(colors);
- }
-
QByteArray output;
QBuffer buf(&output);
QVERIFY(buf.open(QIODevice::WriteOnly));