From 30301436b59efe7ff25991cbbaa388f6f1b4d66e Mon Sep 17 00:00:00 2001 From: Eirik Aavitsland Date: Wed, 15 Mar 2017 09:23:42 +0100 Subject: 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: Allan Sandfeld Jensen --- src/plugins/imageformats/tiff/qtiffhandler.cpp | 31 +++++++++++++++++++++++-- tests/auto/tiff/tst_qtiff.cpp | 22 ++++++++++++++++++ tests/shared/images/tiff.qrc | 2 ++ tests/shared/images/tiff/indexed_nontiled.tif | Bin 0 -> 119486 bytes tests/shared/images/tiff/indexed_tiled.tif | Bin 0 -> 209220 bytes 5 files changed, 53 insertions(+), 2 deletions(-) create mode 100644 tests/shared/images/tiff/indexed_nontiled.tif create mode 100644 tests/shared/images/tiff/indexed_tiled.tif diff --git a/src/plugins/imageformats/tiff/qtiffhandler.cpp b/src/plugins/imageformats/tiff/qtiffhandler.cpp index b5d80f9..e34ea25 100644 --- a/src/plugins/imageformats/tiff/qtiffhandler.cpp +++ b/src/plugins/imageformats/tiff/qtiffhandler.cpp @@ -385,11 +385,38 @@ bool QTiffHandler::read(QImage *image) } image->setColorTable(qtColorTable); - for (uint32 y=0; yscanLine(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(); 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; yscanLine(y), y, 0) < 0) { + d->close(); + return false; + } + } } // free redTable, greenTable and greenTable done by libtiff diff --git a/tests/auto/tiff/tst_qtiff.cpp b/tests/auto/tiff/tst_qtiff.cpp index 65cc56c..bec2ca2 100644 --- a/tests/auto/tiff/tst_qtiff.cpp +++ b/tests/auto/tiff/tst_qtiff.cpp @@ -81,6 +81,9 @@ private slots: void multipage_data(); void multipage(); + void tiled_data(); + void tiled(); + private: QString prefix; }; @@ -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_8") << QString("rgb_orientation_8.tiff") << QSize(64, 64); 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() @@ -557,5 +562,22 @@ void tst_qtiff::multipage() QCOMPARE(reader.jumpToNextImage(), false); } +void tst_qtiff::tiled_data() +{ + QTest::addColumn("expectedFile"); + QTest::addColumn("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) #include "tst_qtiff.moc" diff --git a/tests/shared/images/tiff.qrc b/tests/shared/images/tiff.qrc index c98a72c..258acf0 100644 --- a/tests/shared/images/tiff.qrc +++ b/tests/shared/images/tiff.qrc @@ -41,5 +41,7 @@ tiff/rgb_orientation_8.tiff tiff/teapot.tiff tiff/colorful.bmp + tiff/indexed_tiled.tif + tiff/indexed_nontiled.tif diff --git a/tests/shared/images/tiff/indexed_nontiled.tif b/tests/shared/images/tiff/indexed_nontiled.tif new file mode 100644 index 0000000..d0b7cef Binary files /dev/null and b/tests/shared/images/tiff/indexed_nontiled.tif differ diff --git a/tests/shared/images/tiff/indexed_tiled.tif b/tests/shared/images/tiff/indexed_tiled.tif new file mode 100644 index 0000000..4ed11dd Binary files /dev/null and b/tests/shared/images/tiff/indexed_tiled.tif differ -- cgit v1.2.3