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

Request: support Animated PNG (APNG) #305

Open
bean-z opened this issue Apr 3, 2024 · 12 comments · Fixed by #307
Open

Request: support Animated PNG (APNG) #305

bean-z opened this issue Apr 3, 2024 · 12 comments · Fixed by #307
Assignees
Labels
bug Something isn't working enhancement New feature or request

Comments

@bean-z
Copy link

bean-z commented Apr 3, 2024

Is your feature request related to a problem? Please describe.
Animated PNG (APNG) is an extension of PNG and uses the same file extension (.png) and MIME type (image/png). An example APNG is a bouncing ball animation by Holger Will. The zune-png crate that Oculante uses doesn't support APNG.

Describe the solution you'd like
I would like to open APNG files as if they were GIF files. The png crate ((docs and crate page) seems to be about as fast as zune-png now.

@bean-z bean-z changed the title Support Animated PNG Request: support Animated PNG Apr 3, 2024
@bean-z bean-z changed the title Request: support Animated PNG Request: support Animated PNG (APNG) Apr 3, 2024
@woelper
Copy link
Owner

woelper commented Apr 3, 2024

Thanks! Great idea! Do you happen to know what is required to know if a PNG is animated? The extension is the same as PNG, so I guess some pre-check for animation would need to be done.

@bean-z
Copy link
Author

bean-z commented Apr 3, 2024

The way that the png docs demonstrate is creating a Decoder, calling the read_info() method (which returns a Reader), and passing a mutable reference to a vec! buffer into the Reader's next_frame() method. I think it works like this: If there is only one frame (i.e. not APNG) then the first next_frame() call will return something that matches Ok(variable_to_bind_info) (and will fill the buffer with the first frame's bytes) and a second call will return something that matches Err(Format(FormatError)) (where Format(FormatError) is a variant of the enum DecodingError).

Internally, the .png file should contain the acTL chunk (whose header contains the four hex bytes 61 63 54 4c i.e. "acTL") prior to the IDAT chunk (whose header contains the four bytes 49 44 41 54 i.e. "IDAT").

@woelper
Copy link
Owner

woelper commented Apr 6, 2024

Thanks!

It seems that zune_png supports apng, it just needs manual handling. I have made a branch that successfully decodes the sample animation you linked (thank you for such a well-written feature request by the way!). I'll test this a bit more and release.

@woelper
Copy link
Owner

woelper commented Apr 6, 2024

I've found one animation that looks like the offset is incorrectly calculated here:
http://littlesvr.ca/apng/images/clock.png
I am using https://docs.rs/zune-png/latest/zune_png/fn.post_process_image.html to do post processing, so the bug is likely there, or in the image itself. All other examples decoded correctly as far as I could see.

@woelper woelper linked a pull request Apr 6, 2024 that will close this issue
@woelper
Copy link
Owner

woelper commented Apr 6, 2024

I've released v0.8.18 with APNG support now. Please let me know if this works as expected. Thank you again for this request.

@bean-z
Copy link
Author

bean-z commented Apr 7, 2024

The bouncing ball animation has minor visual artifacts at the top and bottom edges of the ball when displayed in Oculante version 0.8.18. Here's a recording of Oculante on the left and Brave (a Chromium-based browser) on the right:

bouncing-ball-left-oculante-right-chromium-browser.mp4

From what I can tell, Oculante correctly displays this brain scan animation and this elephant animation.

@woelper
Copy link
Owner

woelper commented Apr 7, 2024

Well spotted!

This seems like to be an issue in zune_png. I've made a minimal example based on their example to decode an animation here:

https://github.com/woelper/apng_test

I think it looks like I need to open an issue in their repo. I could try using the png crate, but I'd love to not mix multiple libraries if possible.

@woelper woelper reopened this Apr 7, 2024
@woelper
Copy link
Owner

woelper commented Apr 7, 2024

I have added an issue here:

etemesi254/zune-image#185

@woelper woelper self-assigned this Apr 7, 2024
@woelper woelper added bug Something isn't working enhancement New feature or request labels Apr 7, 2024
@woelper
Copy link
Owner

woelper commented May 18, 2024

I've merged the latest rc from zune-png and all examples look correct now.

@woelper woelper closed this as completed May 18, 2024
@bean-z
Copy link
Author

bean-z commented May 20, 2024

Version 0.8.22 can open the clock and the MRI scan images, but I get a crash if I try to open the bouncing ball or the elephant.

I got a log in my terminal by running /Applications/oculante.app/Contents/MacOS/oculante with the environment variable RUST_BACKTRACE=1. First I dragged the MRI scan image into the app. Then I dragged in the bouncing ball.

[2024-05-20T02:04:53Z INFO  oculante::image_loader] Image is animated
[2024-05-20T02:05:04Z INFO  oculante::image_loader] Image is animated
thread '<unnamed>' panicked at /Users/runner/.cargo/registry/src/index.crates.io-6f17d22bba15001f/zune-png-0.5.0-rc1/src/apng.rs:269:28:
range end index 400 out of range for slice of length 100
stack backtrace:
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

@Richardn2002
Copy link

Same here

thread '<unnamed>' panicked at /build/.cargo/registry/src/index.crates.io-6f17d22bba15001f/zune-png-0.5.0-rc1/src/apng.rs:269:28:
range end index 4400 out of range for slice of length 1000

File in question attached.
Richardn

@woelper
Copy link
Owner

woelper commented Jun 30, 2024

I've opened an issue here:
etemesi254/zune-image#210

@woelper woelper reopened this Jun 30, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants