mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-08 12:56:23 +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/ICOLoader.h>
|
||||||
#include <LibGfx/ImageFormats/ILBMLoader.h>
|
#include <LibGfx/ImageFormats/ILBMLoader.h>
|
||||||
#include <LibGfx/ImageFormats/ImageDecoder.h>
|
#include <LibGfx/ImageFormats/ImageDecoder.h>
|
||||||
|
#include <LibGfx/ImageFormats/JBIG2Loader.h>
|
||||||
#include <LibGfx/ImageFormats/JPEGLoader.h>
|
#include <LibGfx/ImageFormats/JPEGLoader.h>
|
||||||
#include <LibGfx/ImageFormats/JPEGXLLoader.h>
|
#include <LibGfx/ImageFormats/JPEGXLLoader.h>
|
||||||
#include <LibGfx/ImageFormats/PAMLoader.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)
|
TEST_CASE(test_jpeg_sof0_one_scan)
|
||||||
{
|
{
|
||||||
auto file = TRY_OR_FAIL(Core::MappedFile::map(TEST_INPUT("jpg/rgb24.jpg"sv)));
|
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 {};
|
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()
|
JBIG2ImageDecoderPlugin::JBIG2ImageDecoderPlugin()
|
||||||
{
|
{
|
||||||
m_context = make<JBIG2LoadingContext>();
|
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));
|
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(decode_segment_headers(*plugin->m_context, data));
|
||||||
|
|
||||||
|
TRY(scan_for_page_size(*plugin->m_context));
|
||||||
|
|
||||||
return plugin;
|
return plugin;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -312,6 +346,8 @@ ErrorOr<ByteBuffer> JBIG2ImageDecoderPlugin::decode_embedded(Vector<ReadonlyByte
|
|||||||
for (auto const& segment_data : data)
|
for (auto const& segment_data : data)
|
||||||
TRY(decode_segment_headers(*plugin->m_context, segment_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");
|
return Error::from_string_literal("JBIG2ImageDecoderPlugin: Cannot decode embedded JBIG2 yet");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user