mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-22 15:40:19 +00:00
LibGfx/JBIG2: Store location of segment data bodies
They're in different places for Sequential/Embedded (right after the header) and RandomAccess (which has all headers first, followed by all data bits next). We don't do anything with the data yet, but now everything's in place to actually process segment data.
This commit is contained in:
parent
953f6c5d9b
commit
379ef45688
Notes:
sideshowbarker
2024-07-17 05:02:35 +09:00
Author: https://github.com/nico Commit: https://github.com/SerenityOS/serenity/commit/379ef45688 Pull-request: https://github.com/SerenityOS/serenity/pull/23503 Reviewed-by: https://github.com/LucasChollet ✅
1 changed files with 39 additions and 5 deletions
|
@ -62,6 +62,11 @@ struct SegmentHeader {
|
|||
Optional<u32> data_length;
|
||||
};
|
||||
|
||||
struct SegmentData {
|
||||
SegmentHeader header;
|
||||
ReadonlyBytes data;
|
||||
};
|
||||
|
||||
struct JBIG2LoadingContext {
|
||||
enum class State {
|
||||
NotDecoded = 0,
|
||||
|
@ -74,6 +79,8 @@ struct JBIG2LoadingContext {
|
|||
IntSize size;
|
||||
|
||||
Optional<u32> number_of_pages;
|
||||
|
||||
Vector<SegmentData> segments;
|
||||
};
|
||||
|
||||
static ErrorOr<void> decode_jbig2_header(JBIG2LoadingContext& context)
|
||||
|
@ -184,18 +191,45 @@ static ErrorOr<void> decode_segment_headers(JBIG2LoadingContext& context)
|
|||
if (context.organization != Organization::Embedded)
|
||||
data = data.slice(sizeof(id_string) + sizeof(u8) + (context.number_of_pages.has_value() ? sizeof(u32) : 0));
|
||||
FixedMemoryStream stream(data);
|
||||
|
||||
Vector<ReadonlyBytes> segment_datas;
|
||||
auto store_and_skip_segment_data = [&](SegmentHeader const& segment_header) -> ErrorOr<void> {
|
||||
if (!segment_header.data_length.has_value())
|
||||
return Error::from_string_literal("JBIG2ImageDecoderPlugin: Can't handle segment without data length yet");
|
||||
|
||||
size_t start_offset = TRY(stream.tell());
|
||||
if (start_offset + segment_header.data_length.value() > data.size())
|
||||
return Error::from_string_literal("JBIG2ImageDecoderPlugin: Segment data length exceeds file size");
|
||||
ReadonlyBytes segment_data = data.slice(start_offset, segment_header.data_length.value());
|
||||
segment_datas.append(segment_data);
|
||||
|
||||
TRY(stream.seek(segment_header.data_length.value(), SeekMode::FromCurrentPosition));
|
||||
return {};
|
||||
};
|
||||
|
||||
Vector<SegmentHeader> segment_headers;
|
||||
while (!stream.is_eof()) {
|
||||
auto segment_header = TRY(decode_segment_header(stream));
|
||||
if (context.organization != Organization::RandomAccess) {
|
||||
if (!segment_header.data_length.has_value())
|
||||
return Error::from_string_literal("JBIG2ImageDecoderPlugin: Can't handle non-random-access organization segment without data length yet");
|
||||
TRY(stream.seek(segment_header.data_length.value(), SeekMode::FromCurrentPosition));
|
||||
}
|
||||
segment_headers.append(segment_header);
|
||||
|
||||
if (context.organization != Organization::RandomAccess)
|
||||
TRY(store_and_skip_segment_data(segment_header));
|
||||
|
||||
// Required per spec for files with RandomAccess organization.
|
||||
if (segment_header.type == SegmentType::EndOfFile)
|
||||
break;
|
||||
}
|
||||
|
||||
if (context.organization == Organization::RandomAccess) {
|
||||
for (auto const& segment_header : segment_headers)
|
||||
TRY(store_and_skip_segment_data(segment_header));
|
||||
}
|
||||
|
||||
if (segment_headers.size() != segment_datas.size())
|
||||
return Error::from_string_literal("JBIG2ImageDecoderPlugin: Segment headers and segment datas have different sizes");
|
||||
for (size_t i = 0; i < segment_headers.size(); ++i)
|
||||
context.segments.append({ segment_headers[i], segment_datas[i] });
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue