LibGfx/TIFF: Add support for images with PackBits compression

This commit is contained in:
Lucas CHOLLET 2023-10-29 17:02:45 -04:00 committed by Andreas Kling
parent ed8d82f3de
commit 81794df280
3 changed files with 55 additions and 1 deletions

View file

@ -382,6 +382,18 @@ TEST_CASE(test_tiff_uncompressed)
EXPECT_EQ(frame.image->get_pixel(60, 75), Gfx::Color::NamedColor::Red);
}
TEST_CASE(test_tiff_packed_bits)
{
auto file = MUST(Core::MappedFile::map(TEST_INPUT("tiff/packed_bits.tiff"sv)));
EXPECT(Gfx::TIFFImageDecoderPlugin::sniff(file->bytes()));
auto plugin_decoder = MUST(Gfx::TIFFImageDecoderPlugin::create(file->bytes()));
auto frame = expect_single_frame_of_size(*plugin_decoder, { 400, 300 });
EXPECT_EQ(frame.image->get_pixel(0, 0), Gfx::Color::NamedColor::White);
EXPECT_EQ(frame.image->get_pixel(60, 75), Gfx::Color::NamedColor::Red);
}
TEST_CASE(test_webp_simple_lossy)
{
auto file = MUST(Core::MappedFile::map(TEST_INPUT("webp/simple-vp8.webp"sv)));

Binary file not shown.

View file

@ -130,8 +130,50 @@ private:
case Compression::NoCompression:
TRY(loop_over_pixels([this]() { return read_value<u8>(); }));
break;
case Compression::PackBits: {
// Section 9: PackBits Compression
Optional<i8> n;
Optional<u8> saved_byte;
auto read_packed_byte = [&]() -> ErrorOr<u8> {
while (true) {
if (!n.has_value())
n = TRY(read_value<i8>());
if (n.value() >= 0 && !saved_byte.has_value()) {
n.value() = n.value() - 1;
if (n.value() == -1)
n.clear();
return read_value<u8>();
}
if (n.value() == -128) {
n.clear();
continue;
}
if (!saved_byte.has_value())
saved_byte = TRY(read_value<u8>());
n.value() = n.value() + 1;
auto const byte_backup = *saved_byte;
if (n == 1) {
saved_byte.clear();
n.clear();
}
return byte_backup;
}
};
TRY(loop_over_pixels(move(read_packed_byte)));
break;
}
default:
return Error::from_string_literal("Compressed TIFF are not supported yet :^)");
return Error::from_string_literal("This compression type is not supported yet :^)");
}
return {};