summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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