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

Implement a JS WebP encoder/decoder and a PHP WebP decoder #6168

Open
wants to merge 8 commits into
base: 6.1
Choose a base branch
from

Conversation

dtdesign
Copy link
Member

WoltLab Suite 6.1 introduced a new upload pipeline that yields resized images in the much more efficient WebP graphics format.

Part of the resizing process is to strip the EXIF meta data because the underlying nodeca/pica library does not support metadata and discards it. This not only means that the EXIF data is lost but also that any possible image rotation (which is stored in EXIF) is discarded alongside with it. We solved this issue in earlier versions by removing the EXIF data and embedded it into the generated JPEG again.

Unfortunately, there is no library around to accomplish the same in JS for WebP without relying on some CLI binaries.

This PR adds WoltLab/Core/Image/WebP, a pure JavaScript decoder/encoder for WebP (with focus on VP8X encoding) based on the official specs at https://developers.google.com/speed/webp/docs/riff_container.

To add insult to injury, PHP doesn’t support reading EXIF metadata from WebP either, let alone process it in any way. This PR also adds wcf\system\image\WebPDecoder which is a very basic port of our JS WebP decoder but focused on extracting the EXIF chunk only. Parsing the EXIF data is done by creating an empty 100 byte JPEG that serves as the host for the EXIF metadata, allowing us to utilize \exif_read_data().

Fixes https://www.woltlab.com/community/thread/310622-bild-liegt-auf-der-seite/

@dtdesign dtdesign added the Bug label Jan 17, 2025
@dtdesign dtdesign requested a review from BurntimeX January 17, 2025 16:58
Copy link
Member

@BurntimeX BurntimeX left a comment

Choose a reason for hiding this comment

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

LGTM

The previous check was ported from the JS ExifUtil and is meant as a safety check.

An earlier version used a slightly different JPEG (that included a JFIF tag) but was replaced to some 30 bytes with this version.

This also means that any changes to the encoded image could break the following logic thus we convert it into `assert()` to fail hard if adjusted improperly.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants