Serve and accept JPEG XL as an image format (part of #222)
check / check (push) Waiting to run
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 is turned into a distance, 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, and a CMYK image with no ICC profile is converted to sRGB too, as libvips cannot save CMYK as JPEG XL. Model: opus-5-5
This commit is contained in:
@@ -0,0 +1,72 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/davidbyttow/govips/v2/vips"
|
||||
)
|
||||
|
||||
// TestImageProxyFlowJPEGXL requests the JPEG XL testdata/red.jxl, 64x48 and
|
||||
// made with libvips, through pixa's router, upstream fetcher, image processor
|
||||
// and disk cache: resized as PNG, resized as JPEG XL, and at its own size and
|
||||
// format, which is JPEG XL. The second request for each URL is a cache hit.
|
||||
func TestImageProxyFlowJPEGXL(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
source, err := os.ReadFile("testdata/red.jxl")
|
||||
if err != nil {
|
||||
t.Fatalf("reading the test image: %v", err)
|
||||
}
|
||||
|
||||
upstream := httptest.NewServer(http.HandlerFunc(
|
||||
func(w http.ResponseWriter, _ *http.Request) {
|
||||
w.Header().Set("Content-Type", "image/jxl")
|
||||
_, _ = w.Write(source)
|
||||
}))
|
||||
t.Cleanup(upstream.Close)
|
||||
|
||||
s, _, _ := startImageProxy(t, upstream)
|
||||
|
||||
tests := []struct {
|
||||
sizeFormat string // the <size>.<format> part of the image URL
|
||||
contentType string
|
||||
imageType vips.ImageType
|
||||
width, height int
|
||||
}{
|
||||
{"32x24.png", "image/png", vips.ImageTypePNG, 32, 24},
|
||||
{"32x24.jxl", "image/jxl", vips.ImageTypeJXL, 32, 24},
|
||||
{"orig.orig", "image/jxl", vips.ImageTypeJXL, 64, 48},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
target := "/v1/image/" + upstreamHost + "/red.jxl/" + tt.sizeFormat
|
||||
|
||||
for _, wantCache := range []string{"MISS", "HIT"} {
|
||||
rec := getImage(t, s, target)
|
||||
gotType := rec.Header().Get("Content-Type")
|
||||
gotCache := rec.Header().Get("X-Pixa-Cache")
|
||||
|
||||
if gotType != tt.contentType || gotCache != wantCache {
|
||||
t.Errorf("%s: %s, X-Pixa-Cache %s, want %s, %s",
|
||||
target, gotType, gotCache, tt.contentType, wantCache)
|
||||
}
|
||||
|
||||
img, err := vips.NewImageFromBuffer(rec.Body.Bytes())
|
||||
if err != nil {
|
||||
t.Fatalf("%s: loading the image: %v", target, err)
|
||||
}
|
||||
|
||||
if img.Format() != tt.imageType ||
|
||||
img.Width() != tt.width || img.Height() != tt.height {
|
||||
t.Errorf("%s: %s %dx%d, want %s %dx%d", target,
|
||||
vips.ImageTypes[img.Format()], img.Width(), img.Height(),
|
||||
vips.ImageTypes[tt.imageType], tt.width, tt.height)
|
||||
}
|
||||
|
||||
img.Close()
|
||||
}
|
||||
}
|
||||
}
|
||||
Vendored
BIN
Binary file not shown.
Reference in New Issue
Block a user