summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibGfx
diff options
context:
space:
mode:
authorLucas CHOLLET <lucas.chollet@free.fr>2023-03-17 22:10:49 -0400
committerLinus Groh <mail@linusgroh.de>2023-04-03 17:06:21 +0100
commit8806e66f66d45ac1bdc8d3c0840c3f0a4d285f5b (patch)
treeca5e14277177a4c5655568696444050b27e0ddcd /Userland/Libraries/LibGfx
parent731c876ff7cedddd428d6ffe9625983eef84e0bf (diff)
downloadserenity-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.cpp12
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;
}