diff options
author | Benjamin Poulain <benjamin.poulain@nokia.com> | 2009-08-17 14:12:12 (GMT) |
---|---|---|
committer | Benjamin Poulain <benjamin.poulain@nokia.com> | 2009-08-17 14:16:36 (GMT) |
commit | ac9f56b31dacc35dd2007caee69a9cf521ed8410 (patch) | |
tree | 4c945b9c487fcef33e8385420b0a2f5cfa6d22ca | |
parent | b31244b59396abea08254cb649eb1f59b2f8ed55 (diff) | |
download | Qt-ac9f56b31dacc35dd2007caee69a9cf521ed8410.zip Qt-ac9f56b31dacc35dd2007caee69a9cf521ed8410.tar.gz Qt-ac9f56b31dacc35dd2007caee69a9cf521ed8410.tar.bz2 |
Add support for the orientation of tiff images
The orientation tag was ignored for tiff images. The tag is now used
to rotate the image before providing it to the user.
The orientation of indexed an mono images is done completely manually.
The orientation of other type is done in conjunction to the mirroring
already performed by libtiff.
Task-number: 258526
Reviewed-by: Samuel Rødal
29 files changed, 151 insertions, 1 deletions
diff --git a/src/plugins/imageformats/tiff/qtiffhandler.cpp b/src/plugins/imageformats/tiff/qtiffhandler.cpp index ec8a483..59edaf4 100644 --- a/src/plugins/imageformats/tiff/qtiffhandler.cpp +++ b/src/plugins/imageformats/tiff/qtiffhandler.cpp @@ -98,6 +98,43 @@ void qtiffUnmapProc(thandle_t /*fd*/, tdata_t /*base*/, toff_t /*size*/) { } +// for 32 bits images +inline void rotate_right_mirror_horizontal(QImage *const image)// rotate right->mirrored horizontal +{ + const int height = image->height(); + const int width = image->width(); + QImage generated(/* width = */ height, /* height = */ width, image->format()); + const uint32 *originalPixel = reinterpret_cast<const uint32*>(image->bits()); + uint32 *const generatedPixels = reinterpret_cast<uint32*>(generated.bits()); + for (int row=0; row < height; ++row) { + for (int col=0; col < width; ++col) { + int idx = col * height + row; + generatedPixels[idx] = *originalPixel; + ++originalPixel; + } + } + *image = generated; +} + +inline void rotate_right_mirror_vertical(QImage *const image) // rotate right->mirrored vertical +{ + const int height = image->height(); + const int width = image->width(); + QImage generated(/* width = */ height, /* height = */ width, image->format()); + const int lastCol = width - 1; + const int lastRow = height - 1; + const uint32 *pixel = reinterpret_cast<const uint32*>(image->bits()); + uint32 *const generatedBits = reinterpret_cast<uint32*>(generated.bits()); + for (int row=0; row < height; ++row) { + for (int col=0; col < width; ++col) { + int idx = (lastCol - col) * height + (lastRow - row); + generatedBits[idx] = *pixel; + ++pixel; + } + } + *image = generated; +} + QTiffHandler::QTiffHandler() : QImageIOHandler() { compression = NoCompression; @@ -223,7 +260,8 @@ bool QTiffHandler::read(QImage *image) if (image->size() != QSize(width, height) || image->format() != QImage::Format_ARGB32) *image = QImage(width, height, QImage::Format_ARGB32); if (!image->isNull()) { - if (TIFFReadRGBAImageOriented(tiff, width, height, reinterpret_cast<uint32 *>(image->bits()), ORIENTATION_TOPLEFT, 0)) { + const int stopOnError = 1; + if (TIFFReadRGBAImageOriented(tiff, width, height, reinterpret_cast<uint32 *>(image->bits()), ORIENTATION_TOPLEFT, stopOnError)) { for (uint32 y=0; y<height; ++y) convert32BitOrder(image->scanLine(y), width); } else { @@ -262,6 +300,73 @@ bool QTiffHandler::read(QImage *image) } } + // rotate the image if the orientation is defined in the file + uint16 orientationTag; + if (TIFFGetField(tiff, TIFFTAG_ORIENTATION, &orientationTag)) { + if (image->format() == QImage::Format_ARGB32) { + // TIFFReadRGBAImageOriented() flip the image but does not rotate them + switch (orientationTag) { + case 5: + rotate_right_mirror_horizontal(image); + break; + case 6: + rotate_right_mirror_vertical(image); + break; + case 7: + rotate_right_mirror_horizontal(image); + break; + case 8: + rotate_right_mirror_vertical(image); + break; + } + } else { + switch (orientationTag) { + case 1: // default orientation + break; + case 2: // mirror horizontal + *image = image->mirrored(true, false); + break; + case 3: // mirror both + *image = image->mirrored(true, true); + break; + case 4: // mirror vertical + *image = image->mirrored(false, true); + break; + case 5: // rotate right mirror horizontal + { + QMatrix transformation; + transformation.rotate(90); + *image = image->transformed(transformation); + *image = image->mirrored(true, false); + break; + } + case 6: // rotate right + { + QMatrix transformation; + transformation.rotate(90); + *image = image->transformed(transformation); + break; + } + case 7: // rotate right, mirror vertical + { + QMatrix transformation; + transformation.rotate(90); + *image = image->transformed(transformation); + *image = image->mirrored(false, true); + break; + } + case 8: // rotate left + { + QMatrix transformation; + transformation.rotate(270); + *image = image->transformed(transformation); + break; + } + } + } + } + + TIFFClose(tiff); return true; } diff --git a/tests/auto/qimagereader/images/tiff_oriented/indexed_orientation_1.tiff b/tests/auto/qimagereader/images/tiff_oriented/indexed_orientation_1.tiff Binary files differnew file mode 100644 index 0000000..3fcb8a9 --- /dev/null +++ b/tests/auto/qimagereader/images/tiff_oriented/indexed_orientation_1.tiff diff --git a/tests/auto/qimagereader/images/tiff_oriented/indexed_orientation_2.tiff b/tests/auto/qimagereader/images/tiff_oriented/indexed_orientation_2.tiff Binary files differnew file mode 100644 index 0000000..6f3e9d5 --- /dev/null +++ b/tests/auto/qimagereader/images/tiff_oriented/indexed_orientation_2.tiff diff --git a/tests/auto/qimagereader/images/tiff_oriented/indexed_orientation_3.tiff b/tests/auto/qimagereader/images/tiff_oriented/indexed_orientation_3.tiff Binary files differnew file mode 100644 index 0000000..aab9cf2 --- /dev/null +++ b/tests/auto/qimagereader/images/tiff_oriented/indexed_orientation_3.tiff diff --git a/tests/auto/qimagereader/images/tiff_oriented/indexed_orientation_4.tiff b/tests/auto/qimagereader/images/tiff_oriented/indexed_orientation_4.tiff Binary files differnew file mode 100644 index 0000000..aad96ff --- /dev/null +++ b/tests/auto/qimagereader/images/tiff_oriented/indexed_orientation_4.tiff diff --git a/tests/auto/qimagereader/images/tiff_oriented/indexed_orientation_5.tiff b/tests/auto/qimagereader/images/tiff_oriented/indexed_orientation_5.tiff Binary files differnew file mode 100644 index 0000000..05d23dc --- /dev/null +++ b/tests/auto/qimagereader/images/tiff_oriented/indexed_orientation_5.tiff diff --git a/tests/auto/qimagereader/images/tiff_oriented/indexed_orientation_6.tiff b/tests/auto/qimagereader/images/tiff_oriented/indexed_orientation_6.tiff Binary files differnew file mode 100644 index 0000000..9ffe7fc --- /dev/null +++ b/tests/auto/qimagereader/images/tiff_oriented/indexed_orientation_6.tiff diff --git a/tests/auto/qimagereader/images/tiff_oriented/indexed_orientation_7.tiff b/tests/auto/qimagereader/images/tiff_oriented/indexed_orientation_7.tiff Binary files differnew file mode 100644 index 0000000..eeeb019 --- /dev/null +++ b/tests/auto/qimagereader/images/tiff_oriented/indexed_orientation_7.tiff diff --git a/tests/auto/qimagereader/images/tiff_oriented/indexed_orientation_8.tiff b/tests/auto/qimagereader/images/tiff_oriented/indexed_orientation_8.tiff Binary files differnew file mode 100644 index 0000000..87cf2fd --- /dev/null +++ b/tests/auto/qimagereader/images/tiff_oriented/indexed_orientation_8.tiff diff --git a/tests/auto/qimagereader/images/tiff_oriented/mono_orientation_1.tiff b/tests/auto/qimagereader/images/tiff_oriented/mono_orientation_1.tiff Binary files differnew file mode 100644 index 0000000..3b589b2 --- /dev/null +++ b/tests/auto/qimagereader/images/tiff_oriented/mono_orientation_1.tiff diff --git a/tests/auto/qimagereader/images/tiff_oriented/mono_orientation_2.tiff b/tests/auto/qimagereader/images/tiff_oriented/mono_orientation_2.tiff Binary files differnew file mode 100644 index 0000000..9a66223 --- /dev/null +++ b/tests/auto/qimagereader/images/tiff_oriented/mono_orientation_2.tiff diff --git a/tests/auto/qimagereader/images/tiff_oriented/mono_orientation_3.tiff b/tests/auto/qimagereader/images/tiff_oriented/mono_orientation_3.tiff Binary files differnew file mode 100644 index 0000000..eed2423 --- /dev/null +++ b/tests/auto/qimagereader/images/tiff_oriented/mono_orientation_3.tiff diff --git a/tests/auto/qimagereader/images/tiff_oriented/mono_orientation_4.tiff b/tests/auto/qimagereader/images/tiff_oriented/mono_orientation_4.tiff Binary files differnew file mode 100644 index 0000000..055480e --- /dev/null +++ b/tests/auto/qimagereader/images/tiff_oriented/mono_orientation_4.tiff diff --git a/tests/auto/qimagereader/images/tiff_oriented/mono_orientation_5.tiff b/tests/auto/qimagereader/images/tiff_oriented/mono_orientation_5.tiff Binary files differnew file mode 100644 index 0000000..b4d0974 --- /dev/null +++ b/tests/auto/qimagereader/images/tiff_oriented/mono_orientation_5.tiff diff --git a/tests/auto/qimagereader/images/tiff_oriented/mono_orientation_6.tiff b/tests/auto/qimagereader/images/tiff_oriented/mono_orientation_6.tiff Binary files differnew file mode 100644 index 0000000..3b1e02a --- /dev/null +++ b/tests/auto/qimagereader/images/tiff_oriented/mono_orientation_6.tiff diff --git a/tests/auto/qimagereader/images/tiff_oriented/mono_orientation_7.tiff b/tests/auto/qimagereader/images/tiff_oriented/mono_orientation_7.tiff Binary files differnew file mode 100644 index 0000000..b752c74 --- /dev/null +++ b/tests/auto/qimagereader/images/tiff_oriented/mono_orientation_7.tiff diff --git a/tests/auto/qimagereader/images/tiff_oriented/mono_orientation_8.tiff b/tests/auto/qimagereader/images/tiff_oriented/mono_orientation_8.tiff Binary files differnew file mode 100644 index 0000000..e228d05 --- /dev/null +++ b/tests/auto/qimagereader/images/tiff_oriented/mono_orientation_8.tiff diff --git a/tests/auto/qimagereader/images/tiff_oriented/original_indexed.tiff b/tests/auto/qimagereader/images/tiff_oriented/original_indexed.tiff Binary files differnew file mode 100644 index 0000000..7507e52 --- /dev/null +++ b/tests/auto/qimagereader/images/tiff_oriented/original_indexed.tiff diff --git a/tests/auto/qimagereader/images/tiff_oriented/original_mono.tiff b/tests/auto/qimagereader/images/tiff_oriented/original_mono.tiff Binary files differnew file mode 100644 index 0000000..8ff9db8 --- /dev/null +++ b/tests/auto/qimagereader/images/tiff_oriented/original_mono.tiff diff --git a/tests/auto/qimagereader/images/tiff_oriented/original_rgb.tiff b/tests/auto/qimagereader/images/tiff_oriented/original_rgb.tiff Binary files differnew file mode 100644 index 0000000..321ea3e --- /dev/null +++ b/tests/auto/qimagereader/images/tiff_oriented/original_rgb.tiff diff --git a/tests/auto/qimagereader/images/tiff_oriented/rgb_orientation_1.tiff b/tests/auto/qimagereader/images/tiff_oriented/rgb_orientation_1.tiff Binary files differnew file mode 100644 index 0000000..2756a82 --- /dev/null +++ b/tests/auto/qimagereader/images/tiff_oriented/rgb_orientation_1.tiff diff --git a/tests/auto/qimagereader/images/tiff_oriented/rgb_orientation_2.tiff b/tests/auto/qimagereader/images/tiff_oriented/rgb_orientation_2.tiff Binary files differnew file mode 100644 index 0000000..ae9af09 --- /dev/null +++ b/tests/auto/qimagereader/images/tiff_oriented/rgb_orientation_2.tiff diff --git a/tests/auto/qimagereader/images/tiff_oriented/rgb_orientation_3.tiff b/tests/auto/qimagereader/images/tiff_oriented/rgb_orientation_3.tiff Binary files differnew file mode 100644 index 0000000..a2f4325 --- /dev/null +++ b/tests/auto/qimagereader/images/tiff_oriented/rgb_orientation_3.tiff diff --git a/tests/auto/qimagereader/images/tiff_oriented/rgb_orientation_4.tiff b/tests/auto/qimagereader/images/tiff_oriented/rgb_orientation_4.tiff Binary files differnew file mode 100644 index 0000000..f35bfc4 --- /dev/null +++ b/tests/auto/qimagereader/images/tiff_oriented/rgb_orientation_4.tiff diff --git a/tests/auto/qimagereader/images/tiff_oriented/rgb_orientation_5.tiff b/tests/auto/qimagereader/images/tiff_oriented/rgb_orientation_5.tiff Binary files differnew file mode 100644 index 0000000..70e5478 --- /dev/null +++ b/tests/auto/qimagereader/images/tiff_oriented/rgb_orientation_5.tiff diff --git a/tests/auto/qimagereader/images/tiff_oriented/rgb_orientation_6.tiff b/tests/auto/qimagereader/images/tiff_oriented/rgb_orientation_6.tiff Binary files differnew file mode 100644 index 0000000..b2635fe --- /dev/null +++ b/tests/auto/qimagereader/images/tiff_oriented/rgb_orientation_6.tiff diff --git a/tests/auto/qimagereader/images/tiff_oriented/rgb_orientation_7.tiff b/tests/auto/qimagereader/images/tiff_oriented/rgb_orientation_7.tiff Binary files differnew file mode 100644 index 0000000..1fb0cd9 --- /dev/null +++ b/tests/auto/qimagereader/images/tiff_oriented/rgb_orientation_7.tiff diff --git a/tests/auto/qimagereader/images/tiff_oriented/rgb_orientation_8.tiff b/tests/auto/qimagereader/images/tiff_oriented/rgb_orientation_8.tiff Binary files differnew file mode 100644 index 0000000..666b1b4 --- /dev/null +++ b/tests/auto/qimagereader/images/tiff_oriented/rgb_orientation_8.tiff diff --git a/tests/auto/qimagereader/tst_qimagereader.cpp b/tests/auto/qimagereader/tst_qimagereader.cpp index dad771b..ba3d83e 100644 --- a/tests/auto/qimagereader/tst_qimagereader.cpp +++ b/tests/auto/qimagereader/tst_qimagereader.cpp @@ -149,6 +149,9 @@ private slots: void tiffCompression_data(); void tiffCompression(); void tiffEndianness(); + + void tiffOrientation_data(); + void tiffOrientation(); #endif void autoDetectImageFormat(); @@ -1308,6 +1311,48 @@ void tst_QImageReader::tiffEndianness() QCOMPARE(littleEndian, bigEndian); } +void tst_QImageReader::tiffOrientation_data() +{ + QTest::addColumn<QString>("expected"); + QTest::addColumn<QString>("oriented"); + QTest::newRow("Indexed TIFF, orientation1") << "tiff_oriented/original_indexed.tiff" << "tiff_oriented/indexed_orientation_1.tiff"; + QTest::newRow("Indexed TIFF, orientation2") << "tiff_oriented/original_indexed.tiff" << "tiff_oriented/indexed_orientation_2.tiff"; + QTest::newRow("Indexed TIFF, orientation3") << "tiff_oriented/original_indexed.tiff" << "tiff_oriented/indexed_orientation_3.tiff"; + QTest::newRow("Indexed TIFF, orientation4") << "tiff_oriented/original_indexed.tiff" << "tiff_oriented/indexed_orientation_4.tiff"; + QTest::newRow("Indexed TIFF, orientation5") << "tiff_oriented/original_indexed.tiff" << "tiff_oriented/indexed_orientation_5.tiff"; + QTest::newRow("Indexed TIFF, orientation6") << "tiff_oriented/original_indexed.tiff" << "tiff_oriented/indexed_orientation_6.tiff"; + QTest::newRow("Indexed TIFF, orientation7") << "tiff_oriented/original_indexed.tiff" << "tiff_oriented/indexed_orientation_7.tiff"; + QTest::newRow("Indexed TIFF, orientation8") << "tiff_oriented/original_indexed.tiff" << "tiff_oriented/indexed_orientation_8.tiff"; + + QTest::newRow("Mono TIFF, orientation1") << "tiff_oriented/original_mono.tiff" << "tiff_oriented/mono_orientation_1.tiff"; + QTest::newRow("Mono TIFF, orientation2") << "tiff_oriented/original_mono.tiff" << "tiff_oriented/mono_orientation_2.tiff"; + QTest::newRow("Mono TIFF, orientation3") << "tiff_oriented/original_mono.tiff" << "tiff_oriented/mono_orientation_3.tiff"; + QTest::newRow("Mono TIFF, orientation4") << "tiff_oriented/original_mono.tiff" << "tiff_oriented/mono_orientation_4.tiff"; + QTest::newRow("Mono TIFF, orientation5") << "tiff_oriented/original_mono.tiff" << "tiff_oriented/mono_orientation_5.tiff"; + QTest::newRow("Mono TIFF, orientation6") << "tiff_oriented/original_mono.tiff" << "tiff_oriented/mono_orientation_6.tiff"; + QTest::newRow("Mono TIFF, orientation7") << "tiff_oriented/original_mono.tiff" << "tiff_oriented/mono_orientation_7.tiff"; + QTest::newRow("Mono TIFF, orientation8") << "tiff_oriented/original_mono.tiff" << "tiff_oriented/mono_orientation_8.tiff"; + + QTest::newRow("RGB TIFF, orientation1") << "tiff_oriented/original_rgb.tiff" << "tiff_oriented/rgb_orientation_1.tiff"; + QTest::newRow("RGB TIFF, orientation2") << "tiff_oriented/original_rgb.tiff" << "tiff_oriented/rgb_orientation_2.tiff"; + QTest::newRow("RGB TIFF, orientation3") << "tiff_oriented/original_rgb.tiff" << "tiff_oriented/rgb_orientation_3.tiff"; + QTest::newRow("RGB TIFF, orientation4") << "tiff_oriented/original_rgb.tiff" << "tiff_oriented/rgb_orientation_4.tiff"; + QTest::newRow("RGB TIFF, orientation5") << "tiff_oriented/original_rgb.tiff" << "tiff_oriented/rgb_orientation_5.tiff"; + QTest::newRow("RGB TIFF, orientation6") << "tiff_oriented/original_rgb.tiff" << "tiff_oriented/rgb_orientation_6.tiff"; + QTest::newRow("RGB TIFF, orientation7") << "tiff_oriented/original_rgb.tiff" << "tiff_oriented/rgb_orientation_7.tiff"; + QTest::newRow("RGB TIFF, orientation8") << "tiff_oriented/original_rgb.tiff" << "tiff_oriented/rgb_orientation_8.tiff"; +} + +void tst_QImageReader::tiffOrientation() +{ + QFETCH(QString, expected); + QFETCH(QString, oriented); + + QImage expectedImage(prefix + expected); + QImage orientedImage(prefix + oriented); + QCOMPARE(expectedImage, orientedImage); +} + #endif void tst_QImageReader::dotsPerMeter_data() |