mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-08 04:50:08 +03:00
LibGfx/JBIG2: Scan for the first PageInformation segment and decode it
This allows `file` to correctly print the dimensions of a .jbig2 file, and it allows us to write a test that covers much of all the code written so far.
This commit is contained in:
parent
1eaaa8c3e9
commit
8f4930f2df
Notes:
sideshowbarker
2024-07-17 05:02:42 +09:00
Author: https://github.com/nico Commit: https://github.com/SerenityOS/serenity/commit/8f4930f2df Pull-request: https://github.com/SerenityOS/serenity/pull/23503 Reviewed-by: https://github.com/LucasChollet ✅
@ -13,6 +13,7 @@
|
||||
#include <LibGfx/ImageFormats/ICOLoader.h>
|
||||
#include <LibGfx/ImageFormats/ILBMLoader.h>
|
||||
#include <LibGfx/ImageFormats/ImageDecoder.h>
|
||||
#include <LibGfx/ImageFormats/JBIG2Loader.h>
|
||||
#include <LibGfx/ImageFormats/JPEGLoader.h>
|
||||
#include <LibGfx/ImageFormats/JPEGXLLoader.h>
|
||||
#include <LibGfx/ImageFormats/PAMLoader.h>
|
||||
@ -316,6 +317,14 @@ TEST_CASE(test_ilbm_malformed_frame)
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE(test_jbig2_size)
|
||||
{
|
||||
auto file = TRY_OR_FAIL(Core::MappedFile::map(TEST_INPUT("jbig2/bitmap.jbig2"sv)));
|
||||
EXPECT(Gfx::JBIG2ImageDecoderPlugin::sniff(file->bytes()));
|
||||
auto plugin_decoder = TRY_OR_FAIL(Gfx::JBIG2ImageDecoderPlugin::create(file->bytes()));
|
||||
EXPECT_EQ(plugin_decoder->size(), Gfx::IntSize(399, 400));
|
||||
}
|
||||
|
||||
TEST_CASE(test_jpeg_sof0_one_scan)
|
||||
{
|
||||
auto file = TRY_OR_FAIL(Core::MappedFile::map(TEST_INPUT("jpg/rgb24.jpg"sv)));
|
||||
|
@ -266,6 +266,38 @@ static ErrorOr<void> decode_segment_headers(JBIG2LoadingContext& context, Readon
|
||||
return {};
|
||||
}
|
||||
|
||||
// 7.4.8 Page information segment syntax
|
||||
struct [[gnu::packed]] PageInformationSegment {
|
||||
BigEndian<u32> bitmap_width;
|
||||
BigEndian<u32> bitmap_height;
|
||||
BigEndian<u32> page_x_resolution; // In pixels/meter.
|
||||
BigEndian<u32> page_y_resolution; // In pixels/meter.
|
||||
u8 flags;
|
||||
BigEndian<u16> striping_information;
|
||||
};
|
||||
static_assert(AssertSize<PageInformationSegment, 19>());
|
||||
|
||||
static ErrorOr<PageInformationSegment> decode_page_information_segment(ReadonlyBytes data)
|
||||
{
|
||||
// 7.4.8 Page information segment syntax
|
||||
if (data.size() != sizeof(PageInformationSegment))
|
||||
return Error::from_string_literal("JBIG2ImageDecoderPlugin: Invalid page information segment size");
|
||||
return *(PageInformationSegment const*)data.data();
|
||||
}
|
||||
|
||||
static ErrorOr<void> scan_for_page_size(JBIG2LoadingContext& context)
|
||||
{
|
||||
// We only decode the first page at the moment.
|
||||
for (auto const& segment : context.segments) {
|
||||
if (segment.header.type != SegmentType::PageInformation)
|
||||
continue;
|
||||
auto page_information = TRY(decode_page_information_segment(segment.data));
|
||||
context.size = { page_information.bitmap_width, page_information.bitmap_height };
|
||||
return {};
|
||||
}
|
||||
return Error::from_string_literal("JBIG2ImageDecoderPlugin: No page information segment found");
|
||||
}
|
||||
|
||||
JBIG2ImageDecoderPlugin::JBIG2ImageDecoderPlugin()
|
||||
{
|
||||
m_context = make<JBIG2LoadingContext>();
|
||||
@ -289,6 +321,8 @@ ErrorOr<NonnullOwnPtr<ImageDecoderPlugin>> JBIG2ImageDecoderPlugin::create(Reado
|
||||
data = data.slice(sizeof(id_string) + sizeof(u8) + (plugin->m_context->number_of_pages.has_value() ? sizeof(u32) : 0));
|
||||
TRY(decode_segment_headers(*plugin->m_context, data));
|
||||
|
||||
TRY(scan_for_page_size(*plugin->m_context));
|
||||
|
||||
return plugin;
|
||||
}
|
||||
|
||||
@ -312,6 +346,8 @@ ErrorOr<ByteBuffer> JBIG2ImageDecoderPlugin::decode_embedded(Vector<ReadonlyByte
|
||||
for (auto const& segment_data : data)
|
||||
TRY(decode_segment_headers(*plugin->m_context, segment_data));
|
||||
|
||||
TRY(scan_for_page_size(*plugin->m_context));
|
||||
|
||||
return Error::from_string_literal("JBIG2ImageDecoderPlugin: Cannot decode embedded JBIG2 yet");
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user