1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-31 20:28:11 +00:00
serenity/Userland/Libraries/LibGfx/ImageFormats
Nico Weber 69964e10f4 LibGfx+Tests: Improve calculation of restart interval
JPEGs can store a `restart_interval`, which controls how many
minimum coded units (MCUs) apart the stream state resets.
This can be used for error correction, decoding parts of a jpeg
in parallel, etc.

We tried to use

    u32 i = vcursor * context.mblock_meta.hpadded_count + hcursor;
    i % (context.dc_restart_interval *
         context.sampling_factors.vertical *
         context.sampling_factors.horizontal) == 0

to check if we hit a multiple of an MCU.

`hcursor` is the horizontal offset into 8x8 blocks, vcursor the
vertical offset, and hpadded_count stores how many 8x8 blocks
we have per row, padded to a multiple of the sampling factor.

This isn't quite right if hcursor isn't divisible by both
the vertical and horizontal sampling factor. Tweak things so
that they work.

Also rename `i` to `number_of_mcus_decoded_so_far` since that
what it is, at least now.

For the test case, I converted an existing image to a ppm:

    Build/lagom/bin/image -o out.ppm \
        Tests/LibGfx/test-inputs/jpg/12-bit.jpg

Then I resized it to 102x77px in Photoshop and saved it again.
Then I turned it into a jpeg like so:

    path/to/cjpeg \
        -outfile Tests/LibGfx/test-inputs/jpg/odd-restart.jpg \
        -sample 2x2,1x1,1x1 -quality 5 -restart 3B out.ppm

The trick here is to:

a) Pick a size that's not divisible by the data size width (8),
   and that when rounded to a block size (13) still isn't divisible
   by the subsample factor -- done by picking a width of 102.
b) Pick a huffman table that doesn't happen to contain the bit
   pattern for a restart marker, so that reading a restart marker
   from the bitstream as data causes a failure (-quality 5 happens
   to do this)
c) Pick a restart interval where we fail to skip it if our calculation
   is off (-restart 3B)

Together with #22987, fixes #22780.
2024-01-30 14:50:43 +01:00
..
ISOBMFF LibGfx: Simplify ISOBMFF enums with RIFF ChunkID 2024-01-15 23:23:26 -07:00
BMPLoader.cpp LibGfx/ICO: Do not try to decode a mask if we already reached EOF 2024-01-07 12:32:02 -05:00
BMPLoader.h LibGfx: Provide a default implementation for animation-related methods 2023-07-18 14:34:35 +01:00
BMPWriter.cpp
BMPWriter.h
BooleanDecoder.cpp LibGfx/LibVideo: Check for overreads only at end of a VPX range decode 2023-06-10 07:17:12 +02:00
BooleanDecoder.h LibGfx/LibVideo: Check for overreads only at end of a VPX range decode 2023-06-10 07:17:12 +02:00
CCITTDecoder.cpp LibGfx/TIFF+CCITT: Start to decode CCITT Group 3 images 2024-01-18 14:00:56 +01:00
CCITTDecoder.h LibGfx/TIFF+CCITT: Start to decode CCITT Group 3 images 2024-01-18 14:00:56 +01:00
DDSLoader.cpp Everywhere: Rename {Deprecated => Byte}String 2023-12-17 18:25:10 +03:30
DDSLoader.h AK: Rename GenericTraits to DefaultTraits 2023-11-09 10:05:51 -05:00
ExifOrientedBitmap.h LibGfx/ExifOrientedBitmap: Add support for CMYKBitmap 2024-01-24 22:16:22 -07:00
GIFLoader.cpp LibGfx/GIF: Avoid a silly loop in GIF logical screen parsing 2024-01-05 13:20:00 +01:00
GIFLoader.h LibGfx: Provide an implementation for ImageDecoderPlugin::icc_data() 2023-10-29 07:21:10 +00:00
ICOLoader.cpp AK: Rename GenericTraits to DefaultTraits 2023-11-09 10:05:51 -05:00
ICOLoader.h LibGfx: Provide an implementation for ImageDecoderPlugin::icc_data() 2023-10-29 07:21:10 +00:00
ILBMLoader.cpp LibGfx/ILBMLoader: Properly display images with a bitplane mask 2024-01-18 13:59:17 +01:00
ILBMLoader.h LibGfx: Provide an implementation for ImageDecoderPlugin::icc_data() 2023-10-29 07:21:10 +00:00
ImageDecoder.cpp LibGfx: Add a .pam loader 2024-01-26 07:36:53 +01:00
ImageDecoder.h LibGfx: Remove unused parameter from cmyk_frame() 2024-01-25 15:53:44 +01:00
JPEGLoader.cpp LibGfx+Tests: Improve calculation of restart interval 2024-01-30 14:50:43 +01:00
JPEGLoader.h LibGfx/JPEG: Expose the Exif metadata 2024-01-22 20:16:32 -07:00
JPEGShared.h LibGfx/JPEG: Put generic definitions in a shared header 2023-06-22 21:13:04 +02:00
JPEGWriter.cpp LibGfx/JPEGWriter: Rename y<=>x, u<=>v 2024-01-27 10:20:56 +00:00
JPEGWriter.h LibGfx+image: Implement writing ICC profiles to jpeg files 2024-01-26 14:03:20 -05:00
JPEGWriterTables.h LibGfx/JPEG: Add a JPEG encoder :^) 2023-06-22 21:13:04 +02:00
JPEGXLLoader.cpp LibGfx/ExifOrientedBitmap: Add support for CMYKBitmap 2024-01-24 22:16:22 -07:00
JPEGXLLoader.h LibGfx/JPEGXL: Add a JPEG-XL decoder :^) 2023-07-21 10:47:34 -06:00
PAMLoader.cpp LibGfx/PNM: Remove unnecessary line 2024-01-26 14:53:33 +01:00
PAMLoader.h LibGFX/PAM: Allow reading CMYK .pam files 2024-01-26 07:36:53 +01:00
PBMLoader.cpp LibGfx/PNM: Remove unnecessary line 2024-01-26 14:53:33 +01:00
PBMLoader.h LibGfx/PortableFormat: Propagate errors from read_image_data() 2023-03-24 10:56:58 +01:00
PGMLoader.cpp LibGfx/PNM: Remove unnecessary line 2024-01-26 14:53:33 +01:00
PGMLoader.h LibGfx/PortableFormat: Propagate errors from read_image_data() 2023-03-24 10:56:58 +01:00
PNGLoader.cpp LibGfx/PNG: Spec comment for PNGImageDecoderPlugin::unfilter_scanline() 2024-01-15 23:42:45 +01:00
PNGLoader.h LibGfx: Make unfilter_scanline() a static PNGImageDecoderPlugin method 2023-11-17 19:09:50 +01:00
PNGShared.h LibGfx+LibPDF: Create filter_type() for converting u8 to FilterType 2023-11-17 19:09:50 +01:00
PNGWriter.cpp Userland: Prefer _string over _short_string 2023-08-08 07:37:21 +02:00
PNGWriter.h
PortableFormatWriter.cpp LibGfx/PortableFormat: Use FixedArray::unchecked_at 2023-05-09 11:18:46 +02:00
PortableFormatWriter.h LibGfx/PortableFormat+image: Make encode take a Stream 2023-05-09 11:18:46 +02:00
PortableImageLoaderCommon.h LibGfx: Add a .pam loader 2024-01-26 07:36:53 +01:00
PortableImageMapLoader.h LibGFX/PAM: Allow reading CMYK .pam files 2024-01-26 07:36:53 +01:00
PPMLoader.cpp LibGfx/PNM: Remove unnecessary line 2024-01-26 14:53:33 +01:00
PPMLoader.h LibGfx/PortableFormat: Propagate errors from read_image_data() 2023-03-24 10:56:58 +01:00
QOILoader.cpp LibGfx: Provide an implementation for ImageDecoderPlugin::icc_data() 2023-10-29 07:21:10 +00:00
QOILoader.h AK: Rename GenericTraits to DefaultTraits 2023-11-09 10:05:51 -05:00
QOIWriter.cpp Everywhere: Remove unused DeprecatedString includes 2023-04-09 22:00:54 +02:00
QOIWriter.h
TGALoader.cpp AK: Rename GenericTraits to DefaultTraits 2023-11-09 10:05:51 -05:00
TGALoader.h LibGfx: Provide an implementation for ImageDecoderPlugin::icc_data() 2023-10-29 07:21:10 +00:00
TIFFLoader.cpp LibGfx/TIFF: Add support for CMYK 2024-01-24 22:16:22 -07:00
TIFFLoader.h LibGfx/TIFF: Add an alternative entry point to only request metadata 2024-01-22 20:16:32 -07:00
TinyVGLoader.cpp LibGfx/TinyVG: Clamp RGBAF32 color values from 0 and 255 2023-12-02 10:47:39 +01:00
TinyVGLoader.h LibGfx+ImageViewer: Replace ImageDecoder::is_vector() with an enum 2024-01-10 09:39:00 +01:00
WebPLoader.cpp LibGfx: Use LibRIFF for WebP loading 2024-01-15 23:23:26 -07:00
WebPLoader.h LibGfx/WebP: Decode the first chunk in create() 2023-07-15 09:34:07 +02:00
WebPLoaderLossless.cpp LibGfx/WebPLoaderLossless: Fix grammar-o in comment 2024-01-29 09:12:06 -05:00
WebPLoaderLossless.h LibGfx/WebP: Minor cosmetical changes in WebPLoaderLossless.h 2023-05-09 06:35:56 +02:00
WebPLoaderLossy.cpp LibGfx/LibVideo: Check for overreads only at end of a VPX range decode 2023-06-10 07:17:12 +02:00
WebPLoaderLossy.h WebP/Lossy: Implement macroblock coefficient decoding 2023-05-29 10:41:53 -06:00
WebPLoaderLossyTables.h WebP/Lossy: Add const annotations to functions in Tables.h 2023-06-01 16:23:46 +02:00