mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-22 15:40:19 +00:00
LibGfx/TIFF: Add support for bit-depth up to 32 bits per sample
This makes us support every "minisblack" and "rgb-contig" images from the depth folder of libtiff's test suite: https://libtiff.gitlab.io/libtiff/images.html
This commit is contained in:
parent
25993cd93b
commit
234d084876
Notes:
sideshowbarker
2024-07-17 17:49:11 +09:00
Author: https://github.com/LucasChollet Commit: https://github.com/SerenityOS/serenity/commit/234d084876 Pull-request: https://github.com/SerenityOS/serenity/pull/22223 Reviewed-by: https://github.com/nico
3 changed files with 44 additions and 10 deletions
|
@ -431,6 +431,18 @@ TEST_CASE(test_tiff_grayscale)
|
|||
EXPECT_EQ(frame.image->get_pixel(60, 75), Gfx::Color(130, 130, 130));
|
||||
}
|
||||
|
||||
TEST_CASE(test_tiff_16_bits)
|
||||
{
|
||||
auto file = MUST(Core::MappedFile::map(TEST_INPUT("tiff/16_bits.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, { 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)));
|
||||
|
|
BIN
Tests/LibGfx/test-inputs/tiff/16_bits.tiff
Normal file
BIN
Tests/LibGfx/test-inputs/tiff/16_bits.tiff
Normal file
Binary file not shown.
|
@ -76,6 +76,34 @@ private:
|
|||
BigEndian,
|
||||
};
|
||||
|
||||
static ErrorOr<u8> read_component(BigEndianInputBitStream& stream, u8 bits)
|
||||
{
|
||||
// FIXME: This function truncates everything to 8-bits
|
||||
auto const value = TRY(stream.read_bits<u32>(bits));
|
||||
|
||||
if (bits > 8)
|
||||
return value >> (bits - 8);
|
||||
return value << (8 - bits);
|
||||
}
|
||||
|
||||
ErrorOr<Color> read_color(BigEndianInputBitStream& stream)
|
||||
{
|
||||
auto bits_per_sample = *m_metadata.bits_per_sample();
|
||||
if (m_metadata.samples_per_pixel().value_or(3) == 3) {
|
||||
auto const first_component = TRY(read_component(stream, bits_per_sample[0]));
|
||||
auto const second_component = TRY(read_component(stream, bits_per_sample[1]));
|
||||
auto const third_component = TRY(read_component(stream, bits_per_sample[2]));
|
||||
return Color(first_component, second_component, third_component);
|
||||
}
|
||||
|
||||
if (*m_metadata.samples_per_pixel() == 1) {
|
||||
auto const luminosity = TRY(read_component(stream, bits_per_sample[0]));
|
||||
return Color(luminosity, luminosity, luminosity);
|
||||
}
|
||||
|
||||
return Error::from_string_literal("Unsupported number of sample per pixel");
|
||||
}
|
||||
|
||||
template<CallableAs<ErrorOr<ReadonlyBytes>, u32> StripDecoder>
|
||||
ErrorOr<void> loop_over_pixels(StripDecoder&& strip_decoder)
|
||||
{
|
||||
|
@ -87,6 +115,7 @@ private:
|
|||
|
||||
auto const decoded_bytes = TRY(strip_decoder(strip_byte_counts[strip_index]));
|
||||
auto decoded_strip = make<FixedMemoryStream>(decoded_bytes);
|
||||
auto decoded_stream = make<BigEndianInputBitStream>(move(decoded_strip));
|
||||
|
||||
for (u32 row = 0; row < *m_metadata.rows_per_strip(); row++) {
|
||||
auto const scanline = row + *m_metadata.rows_per_strip() * strip_index;
|
||||
|
@ -96,16 +125,7 @@ private:
|
|||
Optional<Color> last_color {};
|
||||
|
||||
for (u32 column = 0; column < *m_metadata.image_width(); ++column) {
|
||||
Color color {};
|
||||
|
||||
if (m_metadata.samples_per_pixel().value_or(3) == 3) {
|
||||
color = Color { TRY(decoded_strip->template read_value<u8>()), TRY(decoded_strip->template read_value<u8>()), TRY(decoded_strip->template read_value<u8>()) };
|
||||
} else if (*m_metadata.samples_per_pixel() == 1) {
|
||||
auto luminosity = TRY(decoded_strip->template read_value<u8>());
|
||||
color = Color { luminosity, luminosity, luminosity };
|
||||
} else {
|
||||
return Error::from_string_literal("Unsupported number of sample per pixel");
|
||||
}
|
||||
auto color = TRY(read_color(*decoded_stream));
|
||||
|
||||
if (m_metadata.predictor() == Predictor::HorizontalDifferencing && last_color.has_value()) {
|
||||
color.set_red(last_color->red() + color.red());
|
||||
|
@ -116,6 +136,8 @@ private:
|
|||
last_color = color;
|
||||
m_bitmap->set_pixel(column, scanline, color);
|
||||
}
|
||||
|
||||
decoded_stream->align_to_byte_boundary();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue