Files
cam2ip/image/decode_test.go
2026-06-30 16:13:32 +02:00

83 lines
1.8 KiB
Go

//go:build !libjpeg
package image_test
import (
"bytes"
"image/jpeg"
"testing"
"github.com/gen2brain/jpegn"
"github.com/gen2brain/cam2ip/image"
)
// stripDHT removes the Huffman table segments, like webcams that rely on the standard tables (issue #20).
func stripDHT(data []byte) []byte {
out := append([]byte{}, data[0], data[1])
for i := 2; i+4 <= len(data); {
if data[i] != 0xFF {
break
}
marker := data[i+1]
if marker == 0xDA {
return append(out, data[i:]...)
}
length := int(data[i+2])<<8 | int(data[i+3])
if marker != 0xC4 {
out = append(out, data[i:i+2+length]...)
}
i += 2 + length
}
return out
}
func TestDecodeMissingDHT(t *testing.T) {
src, err := jpeg.Decode(bytes.NewReader(testJpg))
if err != nil {
t.Fatal(err)
}
// stdlib uses the standard tables; strip the DHT so the stream relies on the decoder's defaults.
var buf bytes.Buffer
if err := jpeg.Encode(&buf, src, &jpeg.Options{Quality: 90}); err != nil {
t.Fatal(err)
}
data := stripDHT(buf.Bytes())
if _, err := jpeg.Decode(bytes.NewReader(data)); err == nil {
t.Log("note: stdlib decoded a DHT-less stream")
}
img, err := image.NewDecoder(bytes.NewReader(data)).Decode()
if err != nil {
t.Fatalf("decode without DHT: %v", err)
}
if img.Bounds() != src.Bounds() {
t.Fatalf("bounds = %v, want %v", img.Bounds(), src.Bounds())
}
}
func TestDecodeLeadingGarbage(t *testing.T) {
data := append([]byte{0x00, 0x00, 0xFF, 0x12, 0x34}, testJpg...)
if _, err := jpegn.Decode(bytes.NewReader(data)); err == nil {
t.Log("note: jpegn decoded leading garbage directly")
}
img, err := image.NewDecoder(bytes.NewReader(data)).Decode()
if err != nil {
t.Fatalf("decode with leading garbage: %v", err)
}
if img.Bounds().Dx() == 0 || img.Bounds().Dy() == 0 {
t.Fatal("empty image")
}
}