summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibGfx
diff options
context:
space:
mode:
authorLucas CHOLLET <lucas.chollet@free.fr>2023-03-03 23:45:47 -0500
committerJelle Raaijmakers <jelle@gmta.nl>2023-03-25 21:31:21 +0100
commit3f9c5af5537b1d49bd09a4eee41c48724744a795 (patch)
tree5043b55a35ec6ed1b9269b6023d0ce532fc61c59 /Userland/Libraries/LibGfx
parentb820f9ffbd7ee372b5e29c10cbc52a9c2bbf3633 (diff)
downloadserenity-3f9c5af5537b1d49bd09a4eee41c48724744a795.zip
LibGfx/JPEG: More support for scans with a single component
Introduced in 2c98eff, support for non-interleaved scans was not working for frames with a number of MCU per line or column that is odd. Indeed, the decoder assumed that they have scans that include a fabricated MCU like scans with multiple components. This patch makes the decoder handle images with a number of MCU per line or column that is odd. To do so, as in the current decoder state we do not know if components are interleaved at allocation time, we skip over falsely-created macroblocks when filling them. As stated in 2c98eff, this is probably not a good solution and a whole refactor will be welcome. It also comes with a test that open a square image with a side of 600px, meaning 75 MCUs.
Diffstat (limited to 'Userland/Libraries/LibGfx')
-rw-r--r--Userland/Libraries/LibGfx/ImageFormats/JPEGLoader.cpp14
1 files changed, 13 insertions, 1 deletions
diff --git a/Userland/Libraries/LibGfx/ImageFormats/JPEGLoader.cpp b/Userland/Libraries/LibGfx/ImageFormats/JPEGLoader.cpp
index 24ff773710..c6f6a628e2 100644
--- a/Userland/Libraries/LibGfx/ImageFormats/JPEGLoader.cpp
+++ b/Userland/Libraries/LibGfx/ImageFormats/JPEGLoader.cpp
@@ -446,9 +446,21 @@ static ErrorOr<void> build_macroblocks(JPEGLoadingContext& context, Vector<Macro
for (u8 hfactor_i = 0; hfactor_i < scan_component.component.hsample_factor; hfactor_i++) {
// A.2.3 - Interleaved order
u32 macroblock_index = (vcursor + vfactor_i) * context.mblock_meta.hpadded_count + (hfactor_i + hcursor);
- if (!context.current_scan.are_components_interleaved())
+ if (!context.current_scan.are_components_interleaved()) {
macroblock_index = vcursor * context.mblock_meta.hpadded_count + (hfactor_i + (hcursor * scan_component.component.vsample_factor) + (vfactor_i * scan_component.component.hsample_factor));
+ // A.2.4 Completion of partial MCU
+ // If the component is [and only if!] to be interleaved, the encoding process
+ // shall also extend the number of samples by one or more additional blocks.
+
+ // Horizontally
+ if (macroblock_index >= context.mblock_meta.hcount && macroblock_index % context.mblock_meta.hpadded_count >= context.mblock_meta.hcount)
+ continue;
+ // Vertically
+ if (macroblock_index >= context.mblock_meta.hpadded_count * context.mblock_meta.vcount)
+ continue;
+ }
+
// G.1.2.2 - Progressive encoding of AC coefficients with Huffman coding
if (context.current_scan.end_of_bands_run_count > 0) {
--context.current_scan.end_of_bands_run_count;