summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEirik Aavitsland <eirik.aavitsland@qt.io>2017-03-16 14:13:57 +0100
committerEirik Aavitsland <eirik.aavitsland@qt.io>2017-03-16 14:08:34 +0000
commitc7a6a451a5c277556e28dfb3b4b943719cdda7ff (patch)
treed5fe2e41250bd67d3219a7def5ba83b20cfddfe0
parent30301436b59efe7ff25991cbbaa388f6f1b4d66e (diff)
Extend support for tiled tiff files to all color formatsv5.9.0-beta3v5.9.0-beta2v5.9.0-beta1
This commit extends the recently added support for tiled tiff images of color index format to also cover grayscale and mono images. RGB images were already covered, since the libtiff API used for those handles tiled images transparently. This commit also simplifies the tiff read() function by sharing common code among the different formats. [ChangeLog][TIFF] Extend support for tiled tiff files to all color formats Change-Id: I13f94bbca65dd6a35384a415906034e245ad8b79 Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
-rw-r--r--src/plugins/imageformats/tiff/qtiffhandler.cpp169
-rw-r--r--tests/auto/tiff/tst_qtiff.cpp19
-rw-r--r--tests/shared/images/tiff.qrc11
-rw-r--r--tests/shared/images/tiff/indexed_nontiled.tifbin119486 -> 0 bytes
-rw-r--r--tests/shared/images/tiff/indexed_tiled.tifbin209220 -> 0 bytes
-rw-r--r--tests/shared/images/tiff/oddsize_grayscale.tiffbin0 -> 4553 bytes
-rw-r--r--tests/shared/images/tiff/oddsize_mono.tiffbin0 -> 886 bytes
-rw-r--r--tests/shared/images/tiff/original_grayscale.tiffbin0 -> 4432 bytes
-rw-r--r--tests/shared/images/tiff/tiled_grayscale.tiffbin0 -> 4584 bytes
-rw-r--r--tests/shared/images/tiff/tiled_indexed.tiffbin0 -> 6061 bytes
-rw-r--r--tests/shared/images/tiff/tiled_mono.tiffbin0 -> 926 bytes
-rw-r--r--tests/shared/images/tiff/tiled_oddsize_grayscale.tiffbin0 -> 5639 bytes
-rw-r--r--tests/shared/images/tiff/tiled_oddsize_mono.tiffbin0 -> 1114 bytes
-rw-r--r--tests/shared/images/tiff/tiled_rgb.tiffbin0 -> 12748 bytes
14 files changed, 100 insertions, 99 deletions
diff --git a/src/plugins/imageformats/tiff/qtiffhandler.cpp b/src/plugins/imageformats/tiff/qtiffhandler.cpp
index e34ea25..81ad7e9 100644
--- a/src/plugins/imageformats/tiff/qtiffhandler.cpp
+++ b/src/plugins/imageformats/tiff/qtiffhandler.cpp
@@ -329,125 +329,106 @@ bool QTiffHandler::read(QImage *image)
if (image->size() != d->size || image->format() != format)
*image = QImage(d->size, format);
+ if (image->isNull()) {
+ d->close();
+ return false;
+ }
+
TIFF *const tiff = d->tiff;
const uint32 width = d->size.width();
const uint32 height = d->size.height();
- if (format == QImage::Format_Mono) {
- QVector<QRgb> colortable(2);
- if (d->photometric == PHOTOMETRIC_MINISBLACK) {
- colortable[0] = 0xff000000;
- colortable[1] = 0xffffffff;
- } else {
- colortable[0] = 0xffffffff;
- colortable[1] = 0xff000000;
- }
- image->setColorTable(colortable);
-
- if (!image->isNull()) {
- for (uint32 y=0; y<height; ++y) {
- if (TIFFReadScanline(tiff, image->scanLine(y), y, 0) < 0) {
+ if (format == QImage::Format_Mono || format == QImage::Format_Indexed8 || format == QImage::Format_Grayscale8) {
+ if (format == QImage::Format_Mono) {
+ QVector<QRgb> colortable(2);
+ if (d->photometric == PHOTOMETRIC_MINISBLACK) {
+ colortable[0] = 0xff000000;
+ colortable[1] = 0xffffffff;
+ } else {
+ colortable[0] = 0xffffffff;
+ colortable[1] = 0xff000000;
+ }
+ image->setColorTable(colortable);
+ } else if (format == QImage::Format_Indexed8) {
+ const uint16 tableSize = 256;
+ QVector<QRgb> qtColorTable(tableSize);
+ if (d->grayscale) {
+ for (int i = 0; i<tableSize; ++i) {
+ const int c = (d->photometric == PHOTOMETRIC_MINISBLACK) ? i : (255 - i);
+ qtColorTable[i] = qRgb(c, c, c);
+ }
+ } else {
+ // create the color table
+ uint16 *redTable = 0;
+ uint16 *greenTable = 0;
+ uint16 *blueTable = 0;
+ if (!TIFFGetField(tiff, TIFFTAG_COLORMAP, &redTable, &greenTable, &blueTable)) {
d->close();
return false;
}
- }
- }
- } else {
- if (format == QImage::Format_Indexed8) {
- if (!image->isNull()) {
- const uint16 tableSize = 256;
- QVector<QRgb> qtColorTable(tableSize);
- if (d->grayscale) {
- for (int i = 0; i<tableSize; ++i) {
- const int c = (d->photometric == PHOTOMETRIC_MINISBLACK) ? i : (255 - i);
- qtColorTable[i] = qRgb(c, c, c);
- }
- } else {
- // create the color table
- uint16 *redTable = 0;
- uint16 *greenTable = 0;
- uint16 *blueTable = 0;
- if (!TIFFGetField(tiff, TIFFTAG_COLORMAP, &redTable, &greenTable, &blueTable)) {
- d->close();
- return false;
- }
- if (!redTable || !greenTable || !blueTable) {
- d->close();
- return false;
- }
-
- for (int i = 0; i<tableSize ;++i) {
- const int red = redTable[i] / 257;
- const int green = greenTable[i] / 257;
- const int blue = blueTable[i] / 257;
- qtColorTable[i] = qRgb(red, green, blue);
- }
+ if (!redTable || !greenTable || !blueTable) {
+ d->close();
+ return false;
}
- image->setColorTable(qtColorTable);
-
- 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; y<height; ++y) {
- if (TIFFReadScanline(tiff, image->scanLine(y), y, 0) < 0) {
- d->close();
- return false;
- }
- }
+ for (int i = 0; i<tableSize ;++i) {
+ const int red = redTable[i] / 257;
+ const int green = greenTable[i] / 257;
+ const int blue = blueTable[i] / 257;
+ qtColorTable[i] = qRgb(red, green, blue);
}
+ }
+ image->setColorTable(qtColorTable);
+ // free redTable, greenTable and greenTable done by libtiff
+ }
- // free redTable, greenTable and greenTable done by libtiff
+ 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;
}
- } 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) {
+ quint32 byteWidth = (format == QImage::Format_Mono) ? (width + 7)/8 : width;
+ quint32 byteTileWidth = (format == QImage::Format_Mono) ? tileWidth/8 : tileWidth;
+ 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 byteOffset = (format == QImage::Format_Mono) ? x/8 : x;
+ quint32 widthToCopy = qMin(byteTileWidth, byteWidth - byteOffset);
+ for (quint32 i = 0; i < linesToCopy; i++) {
+ ::memcpy(image->scanLine(y + i) + byteOffset, buf + (i * byteTileWidth), widthToCopy);
+ }
}
}
+ _TIFFfree(buf);
} else {
- if (!image->isNull()) {
- const int stopOnError = 1;
- if (TIFFReadRGBAImageOriented(tiff, width, height, reinterpret_cast<uint32 *>(image->bits()), qt2Exif(d->transformation), stopOnError)) {
- for (uint32 y=0; y<height; ++y)
- convert32BitOrder(image->scanLine(y), width);
- } else {
+ for (uint32 y=0; y<height; ++y) {
+ if (TIFFReadScanline(tiff, image->scanLine(y), y, 0) < 0) {
d->close();
return false;
}
}
}
+ } else {
+ const int stopOnError = 1;
+ if (TIFFReadRGBAImageOriented(tiff, width, height, reinterpret_cast<uint32 *>(image->bits()), qt2Exif(d->transformation), stopOnError)) {
+ for (uint32 y=0; y<height; ++y)
+ convert32BitOrder(image->scanLine(y), width);
+ } else {
+ d->close();
+ return false;
+ }
}
- if (image->isNull()) {
- d->close();
- return false;
- }
float resX = 0;
float resY = 0;
diff --git a/tests/auto/tiff/tst_qtiff.cpp b/tests/auto/tiff/tst_qtiff.cpp
index bec2ca2..1a96ab3 100644
--- a/tests/auto/tiff/tst_qtiff.cpp
+++ b/tests/auto/tiff/tst_qtiff.cpp
@@ -139,6 +139,7 @@ void tst_qtiff::readImage_data()
QTest::newRow("mono_orientation_7") << QString("mono_orientation_7.tiff") << QSize(64, 64);
QTest::newRow("mono_orientation_8") << QString("mono_orientation_8.tiff") << QSize(64, 64);
QTest::newRow("original_indexed") << QString("original_indexed.tiff") << QSize(64, 64);
+ QTest::newRow("original_grayscale") << QString("original_grayscale.tiff") << QSize(64, 64);
QTest::newRow("original_mono") << QString("original_mono.tiff") << QSize(64, 64);
QTest::newRow("original_rgb") << QString("original_rgb.tiff") << QSize(64, 64);
QTest::newRow("rgba_adobedeflate_littleendian") << QString("rgba_adobedeflate_littleendian.tif") << QSize(200, 200);
@@ -156,8 +157,14 @@ 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);
+ QTest::newRow("oddsize_grayscale") << QString("oddsize_grayscale.tiff") << QSize(59, 71);
+ QTest::newRow("oddsize_mono") << QString("oddsize_mono.tiff") << QSize(59, 71);
+ QTest::newRow("tiled_rgb") << QString("tiled_rgb.tiff") << QSize(64, 64);
+ QTest::newRow("tiled_indexed") << QString("tiled_indexed.tiff") << QSize(64, 64);
+ QTest::newRow("tiled_grayscale") << QString("tiled_grayscale.tiff") << QSize(64, 64);
+ QTest::newRow("tiled_mono") << QString("tiled_mono.tiff") << QSize(64, 64);
+ QTest::newRow("tiled_oddsize_grayscale") << QString("tiled_oddsize_grayscale.tiff") << QSize(59, 71);
+ QTest::newRow("tiled_oddsize_mono") << QString("tiled_oddsize_mono.tiff") << QSize(59, 71);
}
void tst_qtiff::readImage()
@@ -566,7 +573,12 @@ void tst_qtiff::tiled_data()
{
QTest::addColumn<QString>("expectedFile");
QTest::addColumn<QString>("tiledFile");
- QTest::newRow("Indexed") << "indexed_nontiled.tif" << "indexed_tiled.tif";
+ QTest::newRow("RGB") << "original_rgb.tiff" << "tiled_rgb.tiff";
+ QTest::newRow("Indexed") << "original_indexed.tiff" << "tiled_indexed.tiff";
+ QTest::newRow("Grayscale") << "original_grayscale.tiff" << "tiled_grayscale.tiff";
+ QTest::newRow("Mono") << "original_mono.tiff" << "tiled_mono.tiff";
+ QTest::newRow("Oddsize (Grayscale)") << "oddsize_grayscale.tiff" << "tiled_oddsize_grayscale.tiff";
+ QTest::newRow("Oddsize (Mono)") << "oddsize_mono.tiff" << "tiled_oddsize_mono.tiff";
}
void tst_qtiff::tiled()
@@ -576,6 +588,7 @@ void tst_qtiff::tiled()
QImage expectedImage(prefix + expectedFile);
QImage tiledImage(prefix + tiledFile);
+ QVERIFY(!tiledImage.isNull());
QCOMPARE(expectedImage, tiledImage);
}
diff --git a/tests/shared/images/tiff.qrc b/tests/shared/images/tiff.qrc
index 258acf0..19675ba 100644
--- a/tests/shared/images/tiff.qrc
+++ b/tests/shared/images/tiff.qrc
@@ -41,7 +41,14 @@
<file>tiff/rgb_orientation_8.tiff</file>
<file>tiff/teapot.tiff</file>
<file>tiff/colorful.bmp</file>
- <file>tiff/indexed_tiled.tif</file>
- <file>tiff/indexed_nontiled.tif</file>
+ <file>tiff/tiled_grayscale.tiff</file>
+ <file>tiff/tiled_oddsize_grayscale.tiff</file>
+ <file>tiff/oddsize_grayscale.tiff</file>
+ <file>tiff/original_grayscale.tiff</file>
+ <file>tiff/tiled_indexed.tiff</file>
+ <file>tiff/tiled_mono.tiff</file>
+ <file>tiff/tiled_oddsize_mono.tiff</file>
+ <file>tiff/oddsize_mono.tiff</file>
+ <file>tiff/tiled_rgb.tiff</file>
</qresource>
</RCC>
diff --git a/tests/shared/images/tiff/indexed_nontiled.tif b/tests/shared/images/tiff/indexed_nontiled.tif
deleted file mode 100644
index d0b7cef..0000000
--- a/tests/shared/images/tiff/indexed_nontiled.tif
+++ /dev/null
Binary files differ
diff --git a/tests/shared/images/tiff/indexed_tiled.tif b/tests/shared/images/tiff/indexed_tiled.tif
deleted file mode 100644
index 4ed11dd..0000000
--- a/tests/shared/images/tiff/indexed_tiled.tif
+++ /dev/null
Binary files differ
diff --git a/tests/shared/images/tiff/oddsize_grayscale.tiff b/tests/shared/images/tiff/oddsize_grayscale.tiff
new file mode 100644
index 0000000..d519cd2
--- /dev/null
+++ b/tests/shared/images/tiff/oddsize_grayscale.tiff
Binary files differ
diff --git a/tests/shared/images/tiff/oddsize_mono.tiff b/tests/shared/images/tiff/oddsize_mono.tiff
new file mode 100644
index 0000000..fbac0ed
--- /dev/null
+++ b/tests/shared/images/tiff/oddsize_mono.tiff
Binary files differ
diff --git a/tests/shared/images/tiff/original_grayscale.tiff b/tests/shared/images/tiff/original_grayscale.tiff
new file mode 100644
index 0000000..174c2cf
--- /dev/null
+++ b/tests/shared/images/tiff/original_grayscale.tiff
Binary files differ
diff --git a/tests/shared/images/tiff/tiled_grayscale.tiff b/tests/shared/images/tiff/tiled_grayscale.tiff
new file mode 100644
index 0000000..894ba8b
--- /dev/null
+++ b/tests/shared/images/tiff/tiled_grayscale.tiff
Binary files differ
diff --git a/tests/shared/images/tiff/tiled_indexed.tiff b/tests/shared/images/tiff/tiled_indexed.tiff
new file mode 100644
index 0000000..2bd266a
--- /dev/null
+++ b/tests/shared/images/tiff/tiled_indexed.tiff
Binary files differ
diff --git a/tests/shared/images/tiff/tiled_mono.tiff b/tests/shared/images/tiff/tiled_mono.tiff
new file mode 100644
index 0000000..cbcda19
--- /dev/null
+++ b/tests/shared/images/tiff/tiled_mono.tiff
Binary files differ
diff --git a/tests/shared/images/tiff/tiled_oddsize_grayscale.tiff b/tests/shared/images/tiff/tiled_oddsize_grayscale.tiff
new file mode 100644
index 0000000..27bc9d4
--- /dev/null
+++ b/tests/shared/images/tiff/tiled_oddsize_grayscale.tiff
Binary files differ
diff --git a/tests/shared/images/tiff/tiled_oddsize_mono.tiff b/tests/shared/images/tiff/tiled_oddsize_mono.tiff
new file mode 100644
index 0000000..e858e90
--- /dev/null
+++ b/tests/shared/images/tiff/tiled_oddsize_mono.tiff
Binary files differ
diff --git a/tests/shared/images/tiff/tiled_rgb.tiff b/tests/shared/images/tiff/tiled_rgb.tiff
new file mode 100644
index 0000000..90291b9
--- /dev/null
+++ b/tests/shared/images/tiff/tiled_rgb.tiff
Binary files differ