返回 DeepSeek-Reasonix
imagecompress_test.go
根目录 / internal / control / imagecompress_test.go
1 package control
2
3 import (
4 "bytes"
5 "image"
6 "image/color"
7 "image/jpeg"
8 "image/png"
9 "testing"
10 )
11
12 func makeTestPNG(t *testing.T, w, h int) []byte {
13 t.Helper()
14 img := image.NewRGBA(image.Rect(0, 0, w, h))
15 for y := 0; y < h; y++ {
16 for x := 0; x < w; x++ {
17 img.Set(x, y, color.RGBA{R: uint8(x), G: uint8(y), B: uint8(x ^ y), A: 255})
18 }
19 }
20 var buf bytes.Buffer
21 if err := png.Encode(&buf, img); err != nil {
22 t.Fatalf("encode png: %v", err)
23 }
24 return buf.Bytes()
25 }
26
27 func TestCompressForVisionDownscalesOversizedPNG(t *testing.T) {
28 raw := makeTestPNG(t, 3000, 1500)
29 out, mime := compressForVision(raw, "image/png")
30 if mime != "image/png" {
31 t.Errorf("mime = %q, want image/png", mime)
32 }
33 cfg, _, err := image.DecodeConfig(bytes.NewReader(out))
34 if err != nil {
35 t.Fatalf("decode out: %v", err)
36 }
37 // Pixel count is what governs vision token cost; assert the reduction there
38 // (byte size isn't a robust invariant for synthetic, highly-compressible input).
39 if cfg.Width != maxVisionDim || cfg.Height != 1500*maxVisionDim/3000 {
40 t.Errorf("dims = %dx%d, want %dx%d", cfg.Width, cfg.Height, maxVisionDim, 1500*maxVisionDim/3000)
41 }
42 if cfg.Width*cfg.Height >= 3000*1500 {
43 t.Errorf("pixel count %d not reduced from %d", cfg.Width*cfg.Height, 3000*1500)
44 }
45 }
46
47 func TestCompressForVisionKeepsSmallImageVerbatim(t *testing.T) {
48 raw := makeTestPNG(t, 100, 80)
49 out, mime := compressForVision(raw, "image/png")
50 if mime != "image/png" || !bytes.Equal(out, raw) {
51 t.Errorf("an in-budget image must pass through unchanged (got %d bytes, mime %q)", len(out), mime)
52 }
53 }
54
55 func TestCompressForVisionJPEGStaysJPEG(t *testing.T) {
56 var buf bytes.Buffer
57 if err := jpeg.Encode(&buf, image.NewRGBA(image.Rect(0, 0, 2400, 1200)), nil); err != nil {
58 t.Fatal(err)
59 }
60 out, mime := compressForVision(buf.Bytes(), "image/jpeg")
61 if mime != "image/jpeg" {
62 t.Fatalf("mime = %q, want image/jpeg", mime)
63 }
64 if cfg, _, _ := image.DecodeConfig(bytes.NewReader(out)); cfg.Width != maxVisionDim {
65 t.Errorf("width = %d, want %d", cfg.Width, maxVisionDim)
66 }
67 }
68
69 func TestCompressForVisionPassesThroughUndecodable(t *testing.T) {
70 raw := []byte("<svg xmlns='...'></svg>")
71 out, mime := compressForVision(raw, "image/svg+xml")
72 if mime != "image/svg+xml" || !bytes.Equal(out, raw) {
73 t.Error("an undecodable mime must pass through unchanged")
74 }
75 }
76
76 lines GO