Skip to content

Commit b9afac0

Browse files
LucasCholletgmta
authored andcommitted
LibGfx/CCITT: Consider the UseFillBits option
1 parent cbfea68 commit b9afac0

File tree

3 files changed

+26
-2
lines changed

3 files changed

+26
-2
lines changed

Tests/LibGfx/TestImageDecoder.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -616,6 +616,20 @@ TEST_CASE(test_tiff_ccitt3)
616616
EXPECT_EQ(frame.image->get_pixel(60, 75), Gfx::Color::NamedColor::Black);
617617
}
618618

619+
TEST_CASE(test_tiff_ccitt3_fill)
620+
{
621+
auto file = TRY_OR_FAIL(Core::MappedFile::map(TEST_INPUT("tiff/ccitt3_1d_fill.tiff"sv)));
622+
EXPECT(Gfx::TIFFImageDecoderPlugin::sniff(file->bytes()));
623+
auto plugin_decoder = TRY_OR_FAIL(Gfx::TIFFImageDecoderPlugin::create(file->bytes()));
624+
625+
auto frame = TRY_OR_FAIL(expect_single_frame_of_size(*plugin_decoder, { 6, 4 }));
626+
627+
EXPECT_EQ(frame.image->get_pixel(0, 0), Gfx::Color::NamedColor::White);
628+
EXPECT_EQ(frame.image->get_pixel(3, 0), Gfx::Color::NamedColor::Black);
629+
EXPECT_EQ(frame.image->get_pixel(2, 2), Gfx::Color::NamedColor::White);
630+
EXPECT_EQ(frame.image->get_pixel(5, 3), Gfx::Color::NamedColor::White);
631+
}
632+
619633
TEST_CASE(test_tiff_lzw)
620634
{
621635
auto file = TRY_OR_FAIL(Core::MappedFile::map(TEST_INPUT("tiff/lzw.tiff"sv)));
284 Bytes
Binary file not shown.

Userland/Libraries/LibGfx/ImageFormats/CCITTDecoder.cpp

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -318,9 +318,19 @@ ErrorOr<void> decode_single_ccitt3_1d_line(BigEndianInputBitStream& input_bit_st
318318
return {};
319319
}
320320

321-
static ErrorOr<void> read_eol(BigEndianInputBitStream& bit_stream)
321+
static ErrorOr<void> read_eol(BigEndianInputBitStream& bit_stream, Group3Options::UseFillBits use_fill_bits)
322322
{
323323
constexpr u16 EOL = 0b0000'0000'0001;
324+
325+
if (use_fill_bits == Group3Options::UseFillBits::Yes) {
326+
// TIFF specification, description of the T4Options tag:
327+
// "Fill bits have been added as necessary before EOL codes such that
328+
// EOL always ends on a byte boundary, thus ensuring an EOL-sequence of 1 byte
329+
// preceded by a zero nibble: xxxx-0000 0000-0001."
330+
auto const to_skip = (12 + bit_stream.bits_until_next_byte_boundary()) % 8;
331+
TRY(bit_stream.read_bits(to_skip));
332+
}
333+
324334
auto const read = TRY(bit_stream.read_bits<u16>(12));
325335
if (read != EOL)
326336
return Error::from_string_literal("CCITTDecoder: Invalid EndOfLine code");
@@ -368,7 +378,7 @@ ErrorOr<ByteBuffer> decode_ccitt_group3(ReadonlyBytes bytes, u32 image_width, u3
368378
// NOTE: For whatever reason, the last EOL doesn't seem to be included
369379

370380
for (u32 i = 0; i < image_height; ++i) {
371-
TRY(read_eol(*bit_stream));
381+
TRY(read_eol(*bit_stream, options.use_fill_bits));
372382
TRY(decode_single_ccitt3_1d_line(*bit_stream, *decoded_bits, image_width));
373383
}
374384

0 commit comments

Comments
 (0)