Skip to content

Commit

Permalink
LibGfx/JBIG2: Implement support for TPGDON
Browse files Browse the repository at this point in the history
  • Loading branch information
nico committed Mar 16, 2024
1 parent 157664f commit c206e7f
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 3 deletions.
17 changes: 17 additions & 0 deletions Tests/LibGfx/TestImageDecoder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,23 @@ TEST_CASE(test_jbig2_generic_region_arithmetic_code)
EXPECT_EQ(frame.image->get_pixel(x, y), bmp_frame.image->get_pixel(x, y));
}

TEST_CASE(test_jbig2_generic_region_arithmetic_code_tpgdon)
{
auto file = TRY_OR_FAIL(Core::MappedFile::map(TEST_INPUT("jbig2/bitmap-tpgdon.jbig2"sv)));
EXPECT(Gfx::JBIG2ImageDecoderPlugin::sniff(file->bytes()));
auto plugin_decoder = TRY_OR_FAIL(Gfx::JBIG2ImageDecoderPlugin::create(file->bytes()));

auto bmp_file = TRY_OR_FAIL(Core::MappedFile::map(TEST_INPUT("bmp/bitmap.bmp"sv)));
auto bmp_plugin_decoder = TRY_OR_FAIL(Gfx::JBIG2ImageDecoderPlugin::create(file->bytes()));

auto frame = TRY_OR_FAIL(expect_single_frame_of_size(*plugin_decoder, { 399, 400 }));
auto bmp_frame = TRY_OR_FAIL(expect_single_frame_of_size(*bmp_plugin_decoder, { 399, 400 }));

for (int y = 0; y < frame.image->height(); ++y)
for (int x = 0; x < frame.image->width(); ++x)
EXPECT_EQ(frame.image->get_pixel(x, y), bmp_frame.image->get_pixel(x, y));
}

TEST_CASE(test_jbig2_arithmetic_decoder)
{
// https://www.itu.int/rec/T-REC-T.88-201808-I
Expand Down
19 changes: 16 additions & 3 deletions Userland/Libraries/LibGfx/ImageFormats/JBIG2Loader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -743,9 +743,6 @@ static ErrorOr<NonnullOwnPtr<BitBuffer>> generic_region_decoding_procedure(Gener
|| inputs.adaptive_template_pixels[3].x != -2 || inputs.adaptive_template_pixels[3].y != -2)
return Error::from_string_literal("JBIG2ImageDecoderPlugin: Cannot handle custom adaptive pixels yet");

if (inputs.is_typical_prediction_used)
return Error::from_string_literal("JBIG2ImageDecoderPlugin: Cannot decode TPGDON yet");

if (inputs.is_extended_reference_template_used)
return Error::from_string_literal("JBIG2ImageDecoderPlugin: Cannot decode EXTTEMPLATE yet");

Expand Down Expand Up @@ -785,7 +782,23 @@ static ErrorOr<NonnullOwnPtr<BitBuffer>> generic_region_decoding_procedure(Gener
Vector<JBIG2::ArithmeticDecoder::Context> contexts;
contexts.resize(1 << 16);

// Figure 8 – Reused context for coding the SLTP value when GBTEMPLATE is 0
constexpr u16 sltp_context_for_template_0 = 0b10011'0110010'0101;

// 6.2.5.7 Decoding the bitmap
bool ltp = false; // "LTP" in spec. "Line (uses) Typical Prediction" maybe?
for (size_t y = 0; y < inputs.region_height; ++y) {
if (inputs.is_typical_prediction_used) {
// "SLTP" in spec. "Swap LTP" or "Switch LTP" maybe?
bool sltp = decoder.get_next_bit(contexts[sltp_context_for_template_0]);
ltp = ltp ^ sltp;
if (ltp) {
for (size_t x = 0; x < inputs.region_width; ++x)
result->set_bit(x, y, get_pixel(result, (int)x, (int)y - 1));
continue;
}
}

for (size_t x = 0; x < inputs.region_width; ++x) {
u16 context = compute_context(result, x, y);
bool bit = decoder.get_next_bit(contexts[context]);
Expand Down

0 comments on commit c206e7f

Please sign in to comment.