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

A JPEG XL source, a bare codestream or one in its container, is
fetched, detected and decoded, 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, and auto chooses it first when Accept names
image/jxl.

govips sends libvips a JPEG XL distance with every save, and libvips
then ignores the quality, so q is turned into a distance with libvips'
formula, keeping 100 lossy. govips cannot have libvips strip metadata
from JPEG XL, so it is removed from the image before saving; libvips
8.16 and later still add an EXIF block of their own, with nothing from
the source. The conversion to sRGB moved ahead of the format switch.

Model: opus-5-5
This commit is contained in:
2026-10-08 05:26:00 +00:00
parent d2944aa891
commit c465049e67
16 changed files with 491 additions and 36 deletions
+58
View File
@@ -0,0 +1,58 @@
package magic
import "testing"
// testMIMEJXL is the MIME type of JPEG XL.
const testMIMEJXL = "image/jxl"
// TestDetectFormatJPEGXL verifies that both JPEG XL signatures, that of a
// bare codestream and that of the container, are detected as image/jxl.
func TestDetectFormatJPEGXL(t *testing.T) {
t.Parallel()
tests := []struct {
name string
data []byte
}{
{"codestream", pad(0xFF, 0x0A)},
{"container", pad(
0x00, 0x00, 0x00, 0x0C, 0x4A, 0x58, 0x4C, 0x20, 0x0D, 0x0A, 0x87, 0x0A,
)},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
got, err := DetectFormat(tt.data)
if err != nil || got != MIMETypeJXL {
t.Errorf("DetectFormat() = %q, %v, want %q", got, err, testMIMEJXL)
}
err = ValidateMagicBytes(tt.data, testMIMEJXL)
if err != nil {
t.Errorf("ValidateMagicBytes(%q) error = %v", testMIMEJXL, err)
}
})
}
}
// TestJPEGXLMIMEType verifies that image/jxl is a supported input type and
// maps to and from the format jxl.
func TestJPEGXLMIMEType(t *testing.T) {
t.Parallel()
if !IsSupportedMIMEType(testMIMEJXL) {
t.Errorf("IsSupportedMIMEType(%q) = false", testMIMEJXL)
}
format, ok := MIMEToImageFormat(testMIMEJXL)
if format != FormatJXL || !ok {
t.Errorf("MIMEToImageFormat(%q) = %q, %v, want %q, true",
testMIMEJXL, format, ok, FormatJXL)
}
if got := ImageFormatToMIME(FormatJXL); got != testMIMEJXL {
t.Errorf("ImageFormatToMIME(%q) = %q, want %q", FormatJXL, got, testMIMEJXL)
}
}