From 8806e66f66d45ac1bdc8d3c0840c3f0a4d285f5b Mon Sep 17 00:00:00 2001 From: Lucas CHOLLET Date: Fri, 17 Mar 2023 22:10:49 -0400 Subject: [PATCH] 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. --- .../Libraries/LibGfx/ImageFormats/JPEGLoader.cpp | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) 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 add_ac(JPEGLoadingContext& context, Macroblock& macroblock, u32 to_skip = 0; Optional 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; }