discord / lilliput

Resize images and animated GIFs in Go
https://discord.com/blog/how-discord-resizes-150-million-images-every-day-with-go-and-c
Other
1.95k stars 123 forks source link

Discord breaks webp image on upload #159

Closed nico closed 1 month ago

nico commented 4 months ago

wow.zip

The webp file in the attached zip is an animated lossless webp that displays fine in all browsers I've tried.

If I upload the webp file in the attached zip, Discord:

a) fails to show it b) turns it into a file that no longer renders in browsers

The webp has different rects for different animation frames – new frames don't store data that's identical to old frames.

For b), it looks like lilliput takes the width and height of the last animation frame and writes that into the vp8x header. That is incorrect, since the last frame is smaller than the animation.

For animated images, ideally the original size from the vp8x header would be written to the output unmodified. Failing that, the dimensions of the first animation frame are probably a better guess than the dimensions of the last animation frame.

It also looks like the flags byte in the vp8x header isn't quite right. On input, they are 0x12. In the file that comes back it's 0x0a.

0xa means "has exif, has animation". Discord added an (empty) EXIF chunk, so it's fine that that bit gets added. But the 0x10 bit, which means has alpha, got cleared. This animation definitely has alpha.

If I manually fix up the dimensions in the vp8x header, the image starts playing in browsers. But e.g. Safari no longer shows the transparent pixels as transparent, because this bit got cleared.

nico commented 4 months ago

(It'd generally be nice if animated webp would work like animated gif.)

nico commented 4 months ago

Also, it looks like the EXIF chunk is added at the front. Per https://developers.google.com/speed/webp/docs/riff_container#extended_file_format that's invalid: EXIF must follow image data (which for animated files is a sequence of ANMF chunks).

skidder commented 4 months ago

@nico Thank you for reporting this issue, lots of great detail :) I'll take a look at this more closely in the next week.

nico commented 3 months ago

Let me know if I can help answer any questions. I know a bit about webp format internals.

skidder commented 1 month ago

Quick update, I'm making some improvements & fixes to Lilliput's support for animated image formats, and hope to cover this animated WebP issue as part of that work in the coming weeks.

6446plm commented 1 month ago

كيف اديرها

skidder commented 1 month ago

@nico I too was able to reproduce this issue consistently in Discord. Although Lilliput currently lacks support for transformations of animated WebP content, Discord should not be corrupting animated WebP files uploaded by users.

The root-cause of the corruption is actually external to Lilliput. Discord uses the Piexif library to remove EXIF data from media uploads. The corruption stems from two defects I found in Piexif:

I will close this issue out once those defects have been corrected in our fork of Piexif.

skidder commented 1 month ago

@nico this has been fixed in Discord, you should now see animated WebP uploads presented as a single frame in Discord, and viewing the original animated WebP in browser (or any other WebP viewer) should work. We're working on full animated WebP support in Discord, soon 😄

Thanks again for raising this, and please file an issue should anything else come up!

nico commented 3 weeks ago

Super cool, thanks! I can confirm that uploaded animated webps are no longer getting corrupted.

Looking forward to full support! :)

nico commented 3 weeks ago

(ps: Is there an issue I could follow to get updates for full support?)

skidder commented 3 weeks ago

(ps: Is there an issue I could follow to get updates for full support?)

Definitely! Earlier this week I merged in full support for animated WebP support to Lilliput, and we're in the process of integrating those changes with the rest of Discord infrastructure.

I plan on partial integration of animated WebP (a subset of use-cases (e.g. only attachments), likely as an experiment) by end of September. Naturally we want to be cautious rolling out such a big change, as well as ensure we can measure any changes in performance (client & server). Most images generated by Discord are non-animated WebP, and it's important that we not break that behavior.

The Discord engineering blog has a monthly patch-notes post with recent changes. Animated WebP support will be reported in the 'Media' section. I'll also try to tag you on this Github issue once fully rolled out.

Thanks again!

skidder commented 1 week ago

@nico fyi you should see animated WebP attachments display on web & Discord desktop clients! We plan to enable retrieval of animated WebP attachments on mobile clients very soon. Please open an issue against Lilliput if you see any issues or areas to improve.