diff --git a/Tests/LibGfx/TestImageDecoder.cpp b/Tests/LibGfx/TestImageDecoder.cpp index 444f98f0e4..f9f7022d1a 100644 --- a/Tests/LibGfx/TestImageDecoder.cpp +++ b/Tests/LibGfx/TestImageDecoder.cpp @@ -546,6 +546,19 @@ TEST_CASE(test_tiff_deflate) EXPECT_EQ(frame.image->get_pixel(60, 75), Gfx::Color::NamedColor::Red); } +TEST_CASE(test_tiff_orientation) +{ + auto file = MUST(Core::MappedFile::map(TEST_INPUT("tiff/orientation.tiff"sv))); + EXPECT(Gfx::TIFFImageDecoderPlugin::sniff(file->bytes())); + auto plugin_decoder = TRY_OR_FAIL(Gfx::TIFFImageDecoderPlugin::create(file->bytes())); + + auto frame = TRY_OR_FAIL(expect_single_frame_of_size(*plugin_decoder, { 300, 400 })); + + // Orientation is Rotate90Clockwise + EXPECT_EQ(frame.image->get_pixel(0, 0), Gfx::Color::NamedColor::White); + EXPECT_EQ(frame.image->get_pixel(300 - 75, 60), Gfx::Color::NamedColor::Red); +} + TEST_CASE(test_tiff_packed_bits) { auto file = MUST(Core::MappedFile::map(TEST_INPUT("tiff/packed_bits.tiff"sv))); diff --git a/Tests/LibGfx/test-inputs/tiff/orientation.tiff b/Tests/LibGfx/test-inputs/tiff/orientation.tiff new file mode 100644 index 0000000000..4ff6e25b02 Binary files /dev/null and b/Tests/LibGfx/test-inputs/tiff/orientation.tiff differ diff --git a/Userland/Libraries/LibGfx/ImageFormats/TIFFLoader.cpp b/Userland/Libraries/LibGfx/ImageFormats/TIFFLoader.cpp index 4cb4ca7ac2..7517269233 100644 --- a/Userland/Libraries/LibGfx/ImageFormats/TIFFLoader.cpp +++ b/Userland/Libraries/LibGfx/ImageFormats/TIFFLoader.cpp @@ -13,6 +13,7 @@ #include #include #include +#include #include namespace Gfx { @@ -69,7 +70,7 @@ public: IntSize size() const { - return { *m_metadata.image_width(), *m_metadata.image_height() }; + return ExifOrientedBitmap::oriented_size({ *m_metadata.image_width(), *m_metadata.image_height() }, *m_metadata.orientation()); } Metadata const& metadata() const @@ -207,6 +208,8 @@ private: auto const strips_offset = *m_metadata.strip_offsets(); auto const strip_byte_counts = *m_metadata.strip_byte_counts(); + auto oriented_bitmap = TRY(ExifOrientedBitmap::create(BitmapFormat::BGRA8888, { *metadata().image_width(), *metadata().image_height() }, *metadata().orientation())); + for (u32 strip_index = 0; strip_index < strips_offset.size(); ++strip_index) { TRY(m_stream->seek(strips_offset[strip_index])); @@ -231,20 +234,20 @@ private: } last_color = color; - m_bitmap->set_pixel(column, scanline, color); + oriented_bitmap.set_pixel(column, scanline, color); } decoded_stream->align_to_byte_boundary(); } } + m_bitmap = oriented_bitmap.bitmap(); + return {}; } ErrorOr decode_frame_impl() { - m_bitmap = TRY(Bitmap::create(BitmapFormat::BGRA8888, size())); - switch (*m_metadata.compression()) { case Compression::NoCompression: { auto identity = [&](u32 num_bytes) {