diff options
author | Lucas CHOLLET <lucas.chollet@free.fr> | 2023-02-19 23:37:30 -0500 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2023-02-22 09:22:45 +0100 |
commit | bae37676c24bc9f28ce2afbca5915820b55809c1 (patch) | |
tree | d687b95eed3a7ebacca264639a9f210dfca30896 /Userland/Libraries/LibGfx | |
parent | c0c48afe062f6715db3a9106ef65818b575c2772 (diff) | |
download | serenity-bae37676c24bc9f28ce2afbca5915820b55809c1.zip |
LibGfx: Prepare the decoder to handle multiples scans
This means that we should read markers in a loop instead of quiting on
the first scan. This is useless for now as `SOF0` frames only have one
scan, but this is a step forward `SOF2` support.
Diffstat (limited to 'Userland/Libraries/LibGfx')
-rw-r--r-- | Userland/Libraries/LibGfx/JPEGLoader.cpp | 30 |
1 files changed, 25 insertions, 5 deletions
diff --git a/Userland/Libraries/LibGfx/JPEGLoader.cpp b/Userland/Libraries/LibGfx/JPEGLoader.cpp index ce060d95da..69c1a623ae 100644 --- a/Userland/Libraries/LibGfx/JPEGLoader.cpp +++ b/Userland/Libraries/LibGfx/JPEGLoader.cpp @@ -1184,9 +1184,7 @@ static ErrorOr<void> parse_header(AK::SeekableStream& stream, JPEGLoadingContext case JPEG_SOF0: TRY(read_start_of_frame(stream, context)); context.state = JPEGLoadingContext::FrameDecoded; - break; - case JPEG_SOS: - return read_start_of_scan(stream, context); + return {}; default: if (auto result = skip_segment(stream); result.is_error()) { dbgln_if(JPEG_DEBUG, "{}: Error skipping marker: {:x}!", TRY(stream.tell()), marker); @@ -1248,11 +1246,33 @@ static ErrorOr<void> decode_header(JPEGLoadingContext& context) return {}; } +static ErrorOr<Vector<Macroblock>> construct_macroblocks(JPEGLoadingContext& context) +{ + // B.6 - Summary + // See: Figure B.16 – Flow of compressed data syntax + // This function handles the "Multi-scan" loop. + + Marker marker = TRY(read_marker_at_cursor(*context.stream)); + while (true) { + if (is_miscellaneous_or_table_marker(marker)) { + TRY(handle_miscellaneous_or_table(*context.stream, context, marker)); + } else if (marker == JPEG_SOS) { + TRY(read_start_of_scan(*context.stream, context)); + TRY(scan_huffman_stream(*context.stream, context)); + return TRY(decode_huffman_stream(context)); + } else { + dbgln_if(JPEG_DEBUG, "{}: Unexpected marker {:x}!", TRY(context.stream->tell()), marker); + return Error::from_string_literal("Unexpected marker"); + } + + marker = TRY(read_marker_at_cursor(*context.stream)); + } +} + static ErrorOr<void> decode_jpeg(JPEGLoadingContext& context) { TRY(decode_header(context)); - TRY(scan_huffman_stream(*context.stream, context)); - auto macroblocks = TRY(decode_huffman_stream(context)); + auto macroblocks = TRY(construct_macroblocks(context)); dequantize(context, macroblocks); inverse_dct(context, macroblocks); ycbcr_to_rgb(context, macroblocks); |