Commit 454fb13c authored by Allan Sandfeld Jensen's avatar Allan Sandfeld Jensen
Browse files

Handle Grayscale8 TIFFs


Correctly read and write Grayscale8 image format.

Change-Id: I537c68f94077458c69ee1de08b5b37986b54aa26
Reviewed-by: default avatarIvan Komissarov <ABBAPOH@gmail.com>
Reviewed-by: default avatarGunnar Sletta <gunnar@sletta.org>
Showing with 45 additions and 18 deletions
......@@ -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)
......
......@@ -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));
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment