phongn opened a new issue, #13771: URL: https://github.com/apache/trafficserver/issues/13771
All three browser engines are turning on JPEG XL decoding by default. Chrome plans to enable it in [155](https://chromestatus.com/feature/5114042131808256) on desktop, Android and WebView. Firefox plans to enable it in [158](https://groups.google.com/a/mozilla.org/g/dev-platform/c/3YMV4MS34KA), moved from 157. Safari 17+ has decoded still images since 2023. Each engine adds `image/jxl` to its image `Accept` header when support is on ([Chromium](https://chromium.googlesource.com/chromium/src/+/main/third_party/blink/common/loader/network_utils.cc), [Gecko](https://github.com/mozilla-firefox/firefox/blob/main/netwerk/protocol/http/nsHttpHandler.cpp), [WebKit](https://github.com/WebKit/WebKit/blob/main/Source/WebCore/loader/cache/CachedResourceRequest.cpp)). So `webp_transform` could negotiate JPEG XL the same way it negotiates `image/webp` today. ### Why JPEG XL fits this plugin When the origin image is a JPEG, libjxl can recompress it losslessly. It repacks the JPEG's existing DCT coefficients instead of decoding to pixels. The result is about 20% smaller, and the original JPEG can be rebuilt bit for bit. Today's JPEG to WebP path is a lossy re-encode. One public data point is in ImageMagick/ImageMagick#8992. There, `cjxl -j 1` recompressed an 837 KB JPEG to 655 KB. Encoding the same image losslessly from pixels produced 3.17 MB, so a lossless encode from pixels can't replace recompression. A lossy encode from pixels would be much smaller, but like WebP it can't be reversed. ### The obstacle Lossless recompression goes through the libjxl call `JxlEncoderAddJPEGFrame`. Neither ImageMagick nor libvips calls it: both decode to pixels and encode with `JxlEncoderAddImageFrame`. A reply on ImageMagick/ImageMagick#8354 points out that ImageMagick decodes every input to pixels and does not keep the compressed form. So waiting for ImageMagick to add JPEG recompression may not get us there. ### Options 1. **Re-encode pixels with ImageMagick's existing JXL coder.** - No new ATS dependency, but ImageMagick must be built with libjxl. - This is a lossy re-encode like WebP, so it misses the main benefit, and the encoder is slower. 2. **Call libjxl directly, for JPEG input only.** - A small, optional code path. PNG and WebP handling stay as they are. - Adds libjxl (BSD-3) as an optional build dependency. libjxl in turn needs highway and brotli, and it bundles skcms (or can use lcms2) for color management. - Distro packages are old: EPEL 9 ships 0.7.2, while the libjxl README asks users to "update to v0.12 ASAP due to numerous security fixes". Operators would probably build libjxl themselves. 3. **Defer** until users ask for it, or until a library ATS already uses supports JPEG recompression. Any of these would need three things: - **Opt-in.** For example, a `convert_to_jxl` argument, so existing deployments see no change. - **A precedence rule.** Every browser that accepts JPEG XL also sends `image/webp`, so the plugin must pick one. - **Encoder limits.** Cap memory use and avoid a thread pool per request, because the transform runs inline on the transaction's thread. ### Question Would the project accept libjxl as an optional dependency of `webp_transform` (option 2), or would it prefer option 1 or 3? -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
