mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 20:28:11 +00:00
![]() 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. |
||
---|---|---|
.. | ||
ISOBMFF | ||
BMPLoader.cpp | ||
BMPLoader.h | ||
BMPWriter.cpp | ||
BMPWriter.h | ||
BooleanDecoder.cpp | ||
BooleanDecoder.h | ||
CCITTDecoder.cpp | ||
CCITTDecoder.h | ||
DDSLoader.cpp | ||
DDSLoader.h | ||
ExifOrientedBitmap.h | ||
GIFLoader.cpp | ||
GIFLoader.h | ||
ICOLoader.cpp | ||
ICOLoader.h | ||
ILBMLoader.cpp | ||
ILBMLoader.h | ||
ImageDecoder.cpp | ||
ImageDecoder.h | ||
JPEGLoader.cpp | ||
JPEGLoader.h | ||
JPEGShared.h | ||
JPEGWriter.cpp | ||
JPEGWriter.h | ||
JPEGWriterTables.h | ||
JPEGXLLoader.cpp | ||
JPEGXLLoader.h | ||
PAMLoader.cpp | ||
PAMLoader.h | ||
PBMLoader.cpp | ||
PBMLoader.h | ||
PGMLoader.cpp | ||
PGMLoader.h | ||
PNGLoader.cpp | ||
PNGLoader.h | ||
PNGShared.h | ||
PNGWriter.cpp | ||
PNGWriter.h | ||
PortableFormatWriter.cpp | ||
PortableFormatWriter.h | ||
PortableImageLoaderCommon.h | ||
PortableImageMapLoader.h | ||
PPMLoader.cpp | ||
PPMLoader.h | ||
QOILoader.cpp | ||
QOILoader.h | ||
QOIWriter.cpp | ||
QOIWriter.h | ||
TGALoader.cpp | ||
TGALoader.h | ||
TIFFLoader.cpp | ||
TIFFLoader.h | ||
TinyVGLoader.cpp | ||
TinyVGLoader.h | ||
WebPLoader.cpp | ||
WebPLoader.h | ||
WebPLoaderLossless.cpp | ||
WebPLoaderLossless.h | ||
WebPLoaderLossy.cpp | ||
WebPLoaderLossy.h | ||
WebPLoaderLossyTables.h |