mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-26 09:30:24 +00:00
LibGfx/JPEG: More support for scans with a single component
Introduced in2c98eff
, 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 in2c98eff
, 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.
This commit is contained in:
parent
b820f9ffbd
commit
3f9c5af553
Notes:
sideshowbarker
2024-07-17 06:00:02 +09:00
Author: https://github.com/LucasChollet Commit: https://github.com/SerenityOS/serenity/commit/3f9c5af553 Pull-request: https://github.com/SerenityOS/serenity/pull/17709 Reviewed-by: https://github.com/gmta ✅ Reviewed-by: https://github.com/kennethmyhra Reviewed-by: https://github.com/nico
3 changed files with 24 additions and 1 deletions
|
@ -134,6 +134,17 @@ TEST_CASE(test_jpeg_sof2_spectral_selection)
|
||||||
EXPECT_EQ(frame.image->size(), Gfx::IntSize(592, 800));
|
EXPECT_EQ(frame.image->size(), Gfx::IntSize(592, 800));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE(test_jpeg_sof0_several_scans_odd_number_mcu)
|
||||||
|
{
|
||||||
|
auto file = MUST(Core::MappedFile::map(TEST_INPUT("several_scans_odd_number_mcu.jpg"sv)));
|
||||||
|
EXPECT(Gfx::JPEGImageDecoderPlugin::sniff(file->bytes()));
|
||||||
|
auto plugin_decoder = MUST(Gfx::JPEGImageDecoderPlugin::create(file->bytes()));
|
||||||
|
EXPECT(plugin_decoder->initialize());
|
||||||
|
|
||||||
|
auto frame = MUST(plugin_decoder->frame(0));
|
||||||
|
EXPECT_EQ(frame.image->size(), Gfx::IntSize(600, 600));
|
||||||
|
}
|
||||||
|
|
||||||
TEST_CASE(test_pbm)
|
TEST_CASE(test_pbm)
|
||||||
{
|
{
|
||||||
auto file = MUST(Core::MappedFile::map(TEST_INPUT("buggie-raw.pbm"sv)));
|
auto file = MUST(Core::MappedFile::map(TEST_INPUT("buggie-raw.pbm"sv)));
|
||||||
|
|
BIN
Tests/LibGfx/test-inputs/several_scans_odd_number_mcu.jpg
Normal file
BIN
Tests/LibGfx/test-inputs/several_scans_odd_number_mcu.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 12 KiB |
|
@ -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++) {
|
for (u8 hfactor_i = 0; hfactor_i < scan_component.component.hsample_factor; hfactor_i++) {
|
||||||
// A.2.3 - Interleaved order
|
// A.2.3 - Interleaved order
|
||||||
u32 macroblock_index = (vcursor + vfactor_i) * context.mblock_meta.hpadded_count + (hfactor_i + hcursor);
|
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));
|
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
|
// G.1.2.2 - Progressive encoding of AC coefficients with Huffman coding
|
||||||
if (context.current_scan.end_of_bands_run_count > 0) {
|
if (context.current_scan.end_of_bands_run_count > 0) {
|
||||||
--context.current_scan.end_of_bands_run_count;
|
--context.current_scan.end_of_bands_run_count;
|
||||||
|
|
Loading…
Reference in a new issue