Serve and accept JPEG XL as an image format (part of #222)
check / check (push) Waiting to run

A JPEG XL source is accepted, and orig of one is JPEG XL. The format
jxl works in plain and encrypted URLs and on the generator page,
served as image/jxl; auto chooses it first when Accept names
image/jxl.

govips sends libvips a JPEG XL distance, which overrides the quality,
so q becomes a distance, keeping 100 lossy. Metadata is removed from
the image before the JPEG XL save, as govips cannot have libvips strip
it, and the image is given 72 dpi so that the EXIF block libvips 8.16
adds holds nothing from the source. The sRGB conversion moved ahead of
the format switch, and a CMYK image with no ICC profile is converted
to sRGB, as libvips cannot save CMYK as JPEG XL.

Model: opus-5-5
This commit was merged in pull request #230.
This commit is contained in:
2026-10-08 11:01:12 +02:00
parent 99e4aa3bb2
commit 8597253ffd
18 changed files with 645 additions and 36 deletions
+2
View File
@@ -45,6 +45,7 @@ const (
contentTypeGIF = "image/gif"
contentTypeWebP = "image/webp"
contentTypeAVIF = "image/avif"
contentTypeJXL = "image/jxl"
contentTypeSVG = "image/svg+xml"
contentTypeOctetStream = "application/octet-stream"
)
@@ -156,6 +157,7 @@ func DefaultConfig() *Config {
contentTypeGIF,
contentTypeWebP,
contentTypeAVIF,
contentTypeJXL,
contentTypeSVG,
},
AllowHTTP: false,
@@ -0,0 +1,20 @@
package httpfetcher
import "testing"
// TestJPEGXLContentType verifies that the fetcher accepts an upstream answer
// of type image/jxl by default, and that the mock fetcher serves a .jxl file
// as image/jxl.
func TestJPEGXLContentType(t *testing.T) {
t.Parallel()
const jxlType = "image/jxl"
if !New(DefaultConfig()).isAllowedContentType(jxlType) {
t.Errorf("isAllowedContentType(%q) = false, want true", jxlType)
}
if got := detectContentTypeFromPath("images/photo.jxl"); got != jxlType {
t.Errorf("detectContentTypeFromPath(photo.jxl) = %q, want %q", got, jxlType)
}
}
+2
View File
@@ -109,6 +109,8 @@ func detectContentTypeFromPath(path string) string {
return contentTypeWebP
case strings.HasSuffix(path, ".avif"):
return contentTypeAVIF
case strings.HasSuffix(path, ".jxl"):
return contentTypeJXL
case strings.HasSuffix(path, ".svg"):
return contentTypeSVG
default: