Commit 30301436 authored by Eirik Aavitsland's avatar Eirik Aavitsland
Browse files

Add support for tiled, color indexed tiff files


For color index images, the tiff handler uses scanline based
reading. The tiff decoder does not support that if the image is stored
in tiled format. This commit adds tile based reading for such cases.

[ChangeLog][TIFF] Added support for tiled, color indexed tiff files

Task-number: QTBUG-12636
Change-Id: Ic759903c75c8252267429f01e3dd9706fc516f8f
Reviewed-by: default avatarAllan Sandfeld Jensen <allan.jensen@qt.io>
Showing with 53 additions and 2 deletions
...@@ -385,11 +385,38 @@ bool QTiffHandler::read(QImage *image) ...@@ -385,11 +385,38 @@ bool QTiffHandler::read(QImage *image)
} }
image->setColorTable(qtColorTable); image->setColorTable(qtColorTable);
for (uint32 y=0; y<height; ++y) {
if (TIFFReadScanline(tiff, image->scanLine(y), y, 0) < 0) { if (TIFFIsTiled(tiff)) {
quint32 tileWidth, tileLength;
TIFFGetField(tiff, TIFFTAG_TILEWIDTH, &tileWidth);
TIFFGetField(tiff, TIFFTAG_TILELENGTH, &tileLength);
uchar *buf = (uchar *)_TIFFmalloc(TIFFTileSize(tiff));
if (!tileWidth || !tileLength || !buf) {
_TIFFfree(buf);
d->close(); d->close();
return false; return false;
} }
for (quint32 y = 0; y < height; y += tileLength) {
for (quint32 x = 0; x < width; x += tileWidth) {
if (TIFFReadTile(tiff, buf, x, y, 0, 0) < 0) {
_TIFFfree(buf);
d->close();
return false;
}
quint32 linesToCopy = qMin(tileLength, height - y);
quint32 widthToCopy = qMin(tileWidth, width - x);
for (quint32 i = 0; i < linesToCopy; i++)
::memcpy(image->scanLine(y + i) + x, buf + (i * tileWidth), widthToCopy);
}
}
_TIFFfree(buf);
} else {
for (uint32 y=0; y<height; ++y) {
if (TIFFReadScanline(tiff, image->scanLine(y), y, 0) < 0) {
d->close();
return false;
}
}
} }
// free redTable, greenTable and greenTable done by libtiff // free redTable, greenTable and greenTable done by libtiff
......
...@@ -81,6 +81,9 @@ private slots: ...@@ -81,6 +81,9 @@ private slots:
void multipage_data(); void multipage_data();
void multipage(); void multipage();
void tiled_data();
void tiled();
private: private:
QString prefix; QString prefix;
}; };
...@@ -153,6 +156,8 @@ void tst_qtiff::readImage_data() ...@@ -153,6 +156,8 @@ void tst_qtiff::readImage_data()
QTest::newRow("rgb_orientation_7") << QString("rgb_orientation_7.tiff") << QSize(64, 64); QTest::newRow("rgb_orientation_7") << QString("rgb_orientation_7.tiff") << QSize(64, 64);
QTest::newRow("rgb_orientation_8") << QString("rgb_orientation_8.tiff") << QSize(64, 64); QTest::newRow("rgb_orientation_8") << QString("rgb_orientation_8.tiff") << QSize(64, 64);
QTest::newRow("teapot") << QString("teapot.tiff") << QSize(256, 256); QTest::newRow("teapot") << QString("teapot.tiff") << QSize(256, 256);
QTest::newRow("indexed_nontiled") << QString("indexed_nontiled.tif") << QSize(512, 384);
QTest::newRow("indexed_tiled") << QString("indexed_tiled.tif") << QSize(512, 384);
} }
void tst_qtiff::readImage() void tst_qtiff::readImage()
...@@ -557,5 +562,22 @@ void tst_qtiff::multipage() ...@@ -557,5 +562,22 @@ void tst_qtiff::multipage()
QCOMPARE(reader.jumpToNextImage(), false); QCOMPARE(reader.jumpToNextImage(), false);
} }
void tst_qtiff::tiled_data()
{
QTest::addColumn<QString>("expectedFile");
QTest::addColumn<QString>("tiledFile");
QTest::newRow("Indexed") << "indexed_nontiled.tif" << "indexed_tiled.tif";
}
void tst_qtiff::tiled()
{
QFETCH(QString, expectedFile);
QFETCH(QString, tiledFile);
QImage expectedImage(prefix + expectedFile);
QImage tiledImage(prefix + tiledFile);
QCOMPARE(expectedImage, tiledImage);
}
QTEST_MAIN(tst_qtiff) QTEST_MAIN(tst_qtiff)
#include "tst_qtiff.moc" #include "tst_qtiff.moc"
...@@ -41,5 +41,7 @@ ...@@ -41,5 +41,7 @@
<file>tiff/rgb_orientation_8.tiff</file> <file>tiff/rgb_orientation_8.tiff</file>
<file>tiff/teapot.tiff</file> <file>tiff/teapot.tiff</file>
<file>tiff/colorful.bmp</file> <file>tiff/colorful.bmp</file>
<file>tiff/indexed_tiled.tif</file>
<file>tiff/indexed_nontiled.tif</file>
</qresource> </qresource>
</RCC> </RCC>
File added
File added
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