From 7dd5457b8f82b783502fb5813fb0399633dd1eb9 Mon Sep 17 00:00:00 2001 From: Nico Weber Date: Thu, 21 Mar 2024 12:14:41 -0400 Subject: [PATCH] LibGfx/JBIG2: Add support for refinement coding template 1 This is used when refining a symbol in 0000337.pdf. --- .../LibGfx/ImageFormats/JBIG2Loader.cpp | 30 +++++++++++++++---- 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/Userland/Libraries/LibGfx/ImageFormats/JBIG2Loader.cpp b/Userland/Libraries/LibGfx/ImageFormats/JBIG2Loader.cpp index bfdd591283f..45f8bf03cb5 100644 --- a/Userland/Libraries/LibGfx/ImageFormats/JBIG2Loader.cpp +++ b/Userland/Libraries/LibGfx/ImageFormats/JBIG2Loader.cpp @@ -1092,9 +1092,6 @@ static ErrorOr> generic_refinement_region_decoding_proc } // GRTEMPLATE 1 never uses adaptive pixels. - if (inputs.gr_template == 1) - return Error::from_string_literal("JBIG2ImageDecoderPlugin: Cannot decode GRTEMPLATE 1 yet"); - // 6.3.5.3 Fixed templates and adaptive templates static constexpr auto get_pixel = [](BitBuffer const& buffer, int x, int y) -> bool { if (x < 0 || x >= (int)buffer.width() || y < 0 || y >= (int)buffer.height()) @@ -1103,7 +1100,7 @@ static ErrorOr> generic_refinement_region_decoding_proc }; // Figure 12 – 13-pixel refinement template showing the AT pixels at their nominal locations - constexpr auto compute_context = [](BitBuffer const& reference, int reference_x, int reference_y, BitBuffer const& buffer, int x, int y) -> u16 { + constexpr auto compute_context_0 = [](BitBuffer const& reference, int reference_x, int reference_y, BitBuffer const& buffer, int x, int y) -> u16 { u16 result = 0; for (int dy = -1; dy <= 1; ++dy) @@ -1117,6 +1114,27 @@ static ErrorOr> generic_refinement_region_decoding_proc return result; }; + // Figure 13 – 10-pixel refinement template + constexpr auto compute_context_1 = [](BitBuffer const& reference, int reference_x, int reference_y, BitBuffer const& buffer, int x, int y) -> u16 { + u16 result = 0; + + for (int dy = -1; dy <= 1; ++dy) { + for (int dx = -1; dx <= 1; ++dx) { + if ((dy == -1 && (dx == -1 || dx == 1)) || (dy == 1 && dx == -1)) + continue; + result = (result << 1) | (u16)get_pixel(reference, reference_x + dx, reference_y + dy); + } + } + + for (int i = 0; i < 3; ++i) + result = (result << 1) | (u16)get_pixel(buffer, x - 1 + i, y - 1); + result = (result << 1) | (u16)get_pixel(buffer, x - 1, y); + + return result; + }; + + auto compute_context = inputs.gr_template == 0 ? compute_context_0 : compute_context_1; + // 6.3.5.6 Decoding the refinement bitmap auto result = TRY(BitBuffer::create(inputs.region_width, inputs.region_height)); for (size_t y = 0; y < result->height(); ++y) { @@ -1257,7 +1275,7 @@ static ErrorOr> text_region_decoding_procedure(TextRegi JBIG2::ArithmeticIntegerDecoder has_refinement_image_decoder(decoder); Vector refinement_contexts; if (inputs.uses_refinement_coding) - refinement_contexts.resize(1 << 13); + refinement_contexts.resize(1 << (inputs.refinement_template == 0 ? 13 : 10)); OwnPtr refinement_result; auto read_bitmap = [&](u32 id) -> ErrorOr { if (id >= inputs.symbols.size()) @@ -1598,7 +1616,7 @@ static ErrorOr>> symbol_dictionary_decoding_procedu refinement_inputs.is_typical_prediction_used = false; refinement_inputs.adaptive_template_pixels = inputs.refinement_adaptive_template_pixels; if (refinement_contexts.is_empty()) - refinement_contexts.resize(1 << 13); + refinement_contexts.resize(1 << (inputs.refinement_template == 0 ? 13 : 10)); return generic_refinement_region_decoding_procedure(refinement_inputs, decoder, refinement_contexts); };