Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

LibGfx+Utilities: Add animation utility, make it write animated webps #24269

Merged
merged 4 commits into from May 11, 2024

Conversation

nico
Copy link
Collaborator

@nico nico commented May 8, 2024

The high-level design is that we have a static method on WebPWriter that
returns an AnimationWriter object. AnimationWriter has a virtual method
for writing individual frames. This allows streaming animations to disk,
without having to buffer up the entire animation in memory first.
The semantics of this function, add_frame(), are that data is flushed
to disk every time the function is called, so that no explicit close()
method is needed.

For some formats that store animation length at the start of the file,
including WebP, this means that this needs to write to a SeekableStream,
so that add_frame() can seek to the start and update the size when a
frame is written.

This design should work for GIF and APNG writing as well. We can move
AnimationWriter to a new header if we add writers for these.

Currently, animation can read any animated image format we can read
(apng, gif, webp) and convert it to an animated webp file.

The written animated webp file is not compressed whatsoever, so this
creates large output files at the moment.

For VP8L it arguably makes sense to separate the two, but for
fixed-size chunk like VP8X it doesn't.

No behavior change.
@github-actions github-actions bot added the 👀 pr-needs-review PR needs review from a maintainer or community member label May 8, 2024
@nico
Copy link
Collaborator Author

nico commented May 8, 2024

I'm not married to adding an animation tool – maybe image should be able to do this, and there a thousand other alternative viable approaches. For now, this is simple and works, and I'm more interested in the writing code than in the tool I invoke to ultimately call that code :)

Here's

% curl -O 'https://media2.giphy.com/media/v1.Y2lkPTc5MGI3NjExOHhwZzRsMGV0bm83dmtjY2VnMmdiZmtybnhoM3phdGl0ejJja3RtbyZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/XT9HMdwmpHqqOu1f1a/giphy.gif'    
% Build/lagom/bin/animation -o wow.webp giphy.gif

(the .gif is 184K, the .webp is 21M (!))

…hm, can't attach webp files on github yet, apparently! https://github.com/orgs/community/discussions/5470

Well, it looks like the gif, except that it's 114 times is size. (Again, ahis is due to our webp encoder not yet doing any compression. It's a 480 x 480 image with 24 frames. At 4 bytes per pixel, that's 22MB / 21 MiB.)

@nico
Copy link
Collaborator Author

nico commented May 8, 2024

Red "Lagom / CI (macOS, macos-14) (pull_request)" is unrelated.

Copy link
Member

@LucasChollet LucasChollet left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@LucasChollet LucasChollet added the ✅ pr-community-approved PR has been approved by a community member label May 10, 2024
Copy link
Member

@trflynn89 trflynn89 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One small thing, otherwise lgtm

Userland/Libraries/LibGfx/ImageFormats/WebPWriter.cpp Outdated Show resolved Hide resolved
nico added 3 commits May 11, 2024 15:18
The high-level design is that we have a static method on WebPWriter that
returns an AnimationWriter object. AnimationWriter has a virtual method
for writing individual frames. This allows streaming animations to disk,
without having to buffer up the entire animation in memory first.
The semantics of this function, add_frame(), are that data is flushed
to disk every time the function is called, so that no explicit `close()`
method is needed.

For some formats that store animation length at the start of the file,
including WebP, this means that this needs to write to a SeekableStream,
so that add_frame() can seek to the start and update the size when a
frame is written.

This design should work for GIF and APNG writing as well. We can move
AnimationWriter to a new header if we add writers for these.

Currently, `animation` can read any animated image format we can read
(apng, gif, webp) and convert it to an animated webp file.

The written animated webp file is not compressed whatsoever, so this
creates large output files at the moment.
Once we see a frame with transparent pixels, we now toggle the
"has alpha" bit in the header.

To not require a SeekableStream opened for reading, we now pass the
unmodified original flag bit to WebPAnimationWriter.
@github-actions github-actions bot removed the ✅ pr-community-approved PR has been approved by a community member label May 11, 2024
@trflynn89 trflynn89 merged commit 4b1c1d1 into SerenityOS:master May 11, 2024
11 of 12 checks passed
@github-actions github-actions bot removed the 👀 pr-needs-review PR needs review from a maintainer or community member label May 11, 2024
@nico nico deleted the webp-anim branch May 11, 2024 19:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants