1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-21 16:05:07 +00:00
Commit graph

13 commits

Author SHA1 Message Date
Nico Weber
a2d8de180c WebP/Lossy: Add support for images with more than one partition
Each secondary partition has an independent BooleanDecoder.
Their bitstreams interleave per macroblock row, that is the first
macroblock row is read from the first decoder, the second from the
second, ..., until it wraps around again.

All partitions share a single prediction state though: The second
macroblock row (which reads coefficients off the second decoder) is
predicted using the result of decoding the frist macroblock row (which
reads coefficients off the first decoder).

So if I understand things right, in theory the coefficient reading could
be parallelized, but prediction can't be. (IDCT can also be
parallelized, but that's true with just a single partition too.)

I created the test image by running

    examples/cwebp -low_memory -partitions 3 -o foo.webp \
        ~/src/serenity/Tests/LibGfx/test-inputs/4.webp

using a cwebp hacked up as described in #19149. Since creating
multi-partition lossy webps requires hacking up `cwebp`, they're likely
very rare in practice. (But maybe other programs using the libwebp API
create them.)

Fixes #19149.

With this, webp lossy support is complete (*) :^)

And with that, webp support is complete: Lossless, lossy, lossy with
alpha, animated lossless, animated lossy, animated lossy with alpha all
work.

(*: Loop filtering isn't implemented yet, which has a minor visual
effect on the output. But it's only visible when carefully comparing
a webp decoded without loop filtering to the same decoded with it.
But it's technically a part of the spec that's still missing.

The upsampling of UV in the YUV->RGB code is also low-quality. This
produces somewhat visible banding in practice in some images (e.g.
in the fire breather's face in 5.webp), so we should probably improve
that at some point. Our JPG decoder has the same issue.)
2023-05-31 14:07:15 +02:00
Nico Weber
f3beff0930 WebP/Lossy: Tweak some comments 2023-05-30 06:14:56 +02:00
Nico Weber
74b50c046b WebP/Lossy: Check that file contains enough data for first partition 2023-05-30 06:14:56 +02:00
Nico Weber
f8e4a0a268 WebP/Lossy: Implement prediction and inverse DCT
This could be a bit prettier, but it works :^)
2023-05-29 19:44:45 +02:00
Nico Weber
d1b5eec154 WebP/Lossy: Implement macroblock coefficient decoding
This basically adds the line

    u8 token = TRY(
        tree_decode(decoder, COEFFICIENT_TREE,
        header.coefficient_probabilities[plane][band][tricky],
        last_decoded_value == DCT_0 ? 2 : 0));

and calls it once for the 16 coefficients of a discrete cosine transform
that covers a 4x4 pixel subblock.

And then it does this 24 or 25 times per macroblock, for the 4x4 Y
subblocks and the 2x2 each U and V subblocks (plus an optional Y2 block
for some macroblocks).

It then adds a whole bunch of machinery to be able to compute `plane`,
`band`, and in particular `tricky` (which depends on if the
corresponding left or above subblock has non-zero coefficients).

(It also does dequantization, and does an inverse Walsh-Hadamard
transform when needed, to end up with complete DCT coefficients
in all cases.)
2023-05-29 10:41:53 -06:00
Nico Weber
d15ae9fa93 WebP/Lossy: It's 'macroblock', not 'metablock'
Somehow my brain decided to change the name of this concept.
Not sure why, the spec consistently uses 'macroblock'.

No behavior change.
2023-05-28 18:01:31 +02:00
Nico Weber
ea54c58930 WebP/Lossy: Variable naming fix for constants from last pull request 2023-05-27 15:25:00 -06:00
Nico Weber
bd5290dd45 WebP/Lossy: Add code to read macroblock metadata 2023-05-27 15:25:00 -06:00
Nico Weber
8defd55349 WebP/Lossy: Add code to read the frame header in the first partition 2023-05-27 08:31:03 -06:00
Nico Weber
bbc1f57d1e WebP/Lossy: Add a comment with a summary of the file format 2023-05-27 08:31:03 -06:00
Nico Weber
703bd4c8a3 WebP/Lossy: Validate show_frame and version when reading header 2023-05-24 16:09:40 +02:00
Nico Weber
dd2ca56ee4 LibGfx/WebP: Add two missing closing quotes for spec comments 2023-05-09 06:35:56 +02:00
Nico Weber
bc207fd0a0 LibGfx/WebP: Move lossy decoder to its own file
Pure code move (except of removing `static` on the two public functions
in the new header), not behavior change.

There isn't a lot of lossy decoder yet, but it'll make implementing it
more convenient.

No behavior change.
2023-05-09 06:35:56 +02:00