diff options
author | Lucas CHOLLET <lucas.chollet@free.fr> | 2023-03-17 22:10:49 -0400 |
---|---|---|
committer | Linus Groh <mail@linusgroh.de> | 2023-04-03 17:06:21 +0100 |
commit | 8806e66f66d45ac1bdc8d3c0840c3f0a4d285f5b (patch) | |
tree | ca5e14277177a4c5655568696444050b27e0ddcd /Userland/Libraries/LibGfx | |
parent | 731c876ff7cedddd428d6ffe9625983eef84e0bf (diff) | |
download | serenity-8806e66f66d45ac1bdc8d3c0840c3f0a4d285f5b.zip |
LibGfx/JPEG: Handle ZRL as a special case
When reading the stream, interpreted as a normal value 0xF0 means skip
15 values and assign the 16th to 0. On the other hand, the marker ZRL
- which has the value 0xF0, means skip 16 values. For baseline JPEGs,
ZRL doesn't need to be interpreted differently as writing the 16th value
has no consequence. This is no longer the case with refining scans.
That's why this patch implement correctly ZRL.
Diffstat (limited to 'Userland/Libraries/LibGfx')
-rw-r--r-- | Userland/Libraries/LibGfx/ImageFormats/JPEGLoader.cpp | 12 |
1 files changed, 11 insertions, 1 deletions
diff --git a/Userland/Libraries/LibGfx/ImageFormats/JPEGLoader.cpp b/Userland/Libraries/LibGfx/ImageFormats/JPEGLoader.cpp index 8ecae9cbb4..554781036c 100644 --- a/Userland/Libraries/LibGfx/ImageFormats/JPEGLoader.cpp +++ b/Userland/Libraries/LibGfx/ImageFormats/JPEGLoader.cpp @@ -395,20 +395,30 @@ static ErrorOr<void> add_ac(JPEGLoadingContext& context, Macroblock& macroblock, u32 to_skip = 0; Optional<u8> saved_symbol; + bool in_zrl = false; + for (int j = first_coefficient; j <= scan.spectral_selection_end; ++j) { // AC symbols encode 2 pieces of information, the high 4 bits represent // number of zeroes to be stuffed before reading the coefficient. Low 4 // bits represent the magnitude of the coefficient. - if (scan.end_of_bands_run_count == 0 && !saved_symbol.has_value()) { + if (!in_zrl && scan.end_of_bands_run_count == 0 && !saved_symbol.has_value()) { saved_symbol = TRY(get_next_symbol(scan.huffman_stream, ac_table)); if (!TRY(read_eob(scan, *saved_symbol))) { to_skip = *saved_symbol >> 4; + + in_zrl = *saved_symbol == JPEG_ZRL; + if (in_zrl) { + to_skip++; + saved_symbol.clear(); + } } } if (to_skip > 0) { --to_skip; + if (to_skip == 0) + in_zrl = false; continue; } |