diff options
-rw-r--r-- | src/plugins/imageformats/tiff/qtiffhandler.cpp | 169 | ||||
-rw-r--r-- | tests/auto/tiff/tst_qtiff.cpp | 19 | ||||
-rw-r--r-- | tests/shared/images/tiff.qrc | 11 | ||||
-rw-r--r-- | tests/shared/images/tiff/indexed_nontiled.tif | bin | 119486 -> 0 bytes | |||
-rw-r--r-- | tests/shared/images/tiff/indexed_tiled.tif | bin | 209220 -> 0 bytes | |||
-rw-r--r-- | tests/shared/images/tiff/oddsize_grayscale.tiff | bin | 0 -> 4553 bytes | |||
-rw-r--r-- | tests/shared/images/tiff/oddsize_mono.tiff | bin | 0 -> 886 bytes | |||
-rw-r--r-- | tests/shared/images/tiff/original_grayscale.tiff | bin | 0 -> 4432 bytes | |||
-rw-r--r-- | tests/shared/images/tiff/tiled_grayscale.tiff | bin | 0 -> 4584 bytes | |||
-rw-r--r-- | tests/shared/images/tiff/tiled_indexed.tiff | bin | 0 -> 6061 bytes | |||
-rw-r--r-- | tests/shared/images/tiff/tiled_mono.tiff | bin | 0 -> 926 bytes | |||
-rw-r--r-- | tests/shared/images/tiff/tiled_oddsize_grayscale.tiff | bin | 0 -> 5639 bytes | |||
-rw-r--r-- | tests/shared/images/tiff/tiled_oddsize_mono.tiff | bin | 0 -> 1114 bytes | |||
-rw-r--r-- | tests/shared/images/tiff/tiled_rgb.tiff | bin | 0 -> 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 Binary files differdeleted file mode 100644 index d0b7cef..0000000 --- a/tests/shared/images/tiff/indexed_nontiled.tif +++ /dev/null diff --git a/tests/shared/images/tiff/indexed_tiled.tif b/tests/shared/images/tiff/indexed_tiled.tif Binary files differdeleted file mode 100644 index 4ed11dd..0000000 --- a/tests/shared/images/tiff/indexed_tiled.tif +++ /dev/null diff --git a/tests/shared/images/tiff/oddsize_grayscale.tiff b/tests/shared/images/tiff/oddsize_grayscale.tiff Binary files differnew file mode 100644 index 0000000..d519cd2 --- /dev/null +++ b/tests/shared/images/tiff/oddsize_grayscale.tiff diff --git a/tests/shared/images/tiff/oddsize_mono.tiff b/tests/shared/images/tiff/oddsize_mono.tiff Binary files differnew file mode 100644 index 0000000..fbac0ed --- /dev/null +++ b/tests/shared/images/tiff/oddsize_mono.tiff diff --git a/tests/shared/images/tiff/original_grayscale.tiff b/tests/shared/images/tiff/original_grayscale.tiff Binary files differnew file mode 100644 index 0000000..174c2cf --- /dev/null +++ b/tests/shared/images/tiff/original_grayscale.tiff diff --git a/tests/shared/images/tiff/tiled_grayscale.tiff b/tests/shared/images/tiff/tiled_grayscale.tiff Binary files differnew file mode 100644 index 0000000..894ba8b --- /dev/null +++ b/tests/shared/images/tiff/tiled_grayscale.tiff diff --git a/tests/shared/images/tiff/tiled_indexed.tiff b/tests/shared/images/tiff/tiled_indexed.tiff Binary files differnew file mode 100644 index 0000000..2bd266a --- /dev/null +++ b/tests/shared/images/tiff/tiled_indexed.tiff diff --git a/tests/shared/images/tiff/tiled_mono.tiff b/tests/shared/images/tiff/tiled_mono.tiff Binary files differnew file mode 100644 index 0000000..cbcda19 --- /dev/null +++ b/tests/shared/images/tiff/tiled_mono.tiff diff --git a/tests/shared/images/tiff/tiled_oddsize_grayscale.tiff b/tests/shared/images/tiff/tiled_oddsize_grayscale.tiff Binary files differnew file mode 100644 index 0000000..27bc9d4 --- /dev/null +++ b/tests/shared/images/tiff/tiled_oddsize_grayscale.tiff diff --git a/tests/shared/images/tiff/tiled_oddsize_mono.tiff b/tests/shared/images/tiff/tiled_oddsize_mono.tiff Binary files differnew file mode 100644 index 0000000..e858e90 --- /dev/null +++ b/tests/shared/images/tiff/tiled_oddsize_mono.tiff diff --git a/tests/shared/images/tiff/tiled_rgb.tiff b/tests/shared/images/tiff/tiled_rgb.tiff Binary files differnew file mode 100644 index 0000000..90291b9 --- /dev/null +++ b/tests/shared/images/tiff/tiled_rgb.tiff |