Files
cam2ip/camera/convert_test.go
Milan Nikolic 57f14f3e81 Add more tests
2026-06-30 04:51:48 +02:00

184 lines
4.5 KiB
Go

package camera
import (
"image"
"testing"
)
func TestPackedYUV422ToYCbCr(t *testing.T) {
// 2x2 image, one macropixel per row.
wantY := []byte{10, 30, 50, 70}
wantCb := []byte{20, 60}
wantCr := []byte{40, 80}
tests := []struct {
name string
y0, y1, cb, cr int
data []byte
}{
{"YUYV", 0, 2, 1, 3, []byte{10, 20, 30, 40, 50, 60, 70, 80}},
{"UYVY", 1, 3, 0, 2, []byte{20, 10, 40, 30, 60, 50, 80, 70}},
{"YVYU", 0, 2, 3, 1, []byte{10, 40, 30, 20, 50, 80, 70, 60}},
{"VYUY", 1, 3, 2, 0, []byte{40, 10, 20, 30, 80, 50, 60, 70}},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
dst := image.NewYCbCr(image.Rect(0, 0, 2, 2), image.YCbCrSubsampleRatio422)
if err := packedYUV422ToYCbCr(tt.data, dst, tt.y0, tt.y1, tt.cb, tt.cr); err != nil {
t.Fatal(err)
}
assertBytes(t, "Y", dst.Y, wantY)
assertBytes(t, "Cb", dst.Cb, wantCb)
assertBytes(t, "Cr", dst.Cr, wantCr)
})
}
}
func TestPackedYUV422Errors(t *testing.T) {
dst422 := image.NewYCbCr(image.Rect(0, 0, 2, 2), image.YCbCrSubsampleRatio422)
if err := packedYUV422ToYCbCr(make([]byte, 7), dst422, 0, 2, 1, 3); err == nil {
t.Error("expected error for wrong data length")
}
dst420 := image.NewYCbCr(image.Rect(0, 0, 2, 2), image.YCbCrSubsampleRatio420)
if err := packedYUV422ToYCbCr(make([]byte, 8), dst420, 0, 2, 1, 3); err == nil {
t.Error("expected error for wrong subsample ratio")
}
}
func TestPlanar420ToYCbCr(t *testing.T) {
wantY := []byte{11, 12, 13, 14}
wantCb := []byte{21}
wantCr := []byte{22}
tests := []struct {
name string
swapUV bool
data []byte
}{
{"YU12", false, []byte{11, 12, 13, 14, 21, 22}},
{"YV12", true, []byte{11, 12, 13, 14, 22, 21}},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
dst := image.NewYCbCr(image.Rect(0, 0, 2, 2), image.YCbCrSubsampleRatio420)
if err := planar420ToYCbCr(tt.data, dst, tt.swapUV); err != nil {
t.Fatal(err)
}
assertBytes(t, "Y", dst.Y, wantY)
assertBytes(t, "Cb", dst.Cb, wantCb)
assertBytes(t, "Cr", dst.Cr, wantCr)
})
}
}
func TestNV12ToYCbCr(t *testing.T) {
dst := image.NewYCbCr(image.Rect(0, 0, 2, 2), image.YCbCrSubsampleRatio420)
if err := nv12ToYCbCr([]byte{11, 12, 13, 14, 21, 22}, dst); err != nil {
t.Fatal(err)
}
assertBytes(t, "Y", dst.Y, []byte{11, 12, 13, 14})
assertBytes(t, "Cb", dst.Cb, []byte{21})
assertBytes(t, "Cr", dst.Cr, []byte{22})
}
func TestRgb24ToRgba(t *testing.T) {
tests := []struct {
name string
bgr bool
data []byte
}{
{"RGB", false, []byte{10, 20, 30, 40, 50, 60}},
{"BGR", true, []byte{30, 20, 10, 60, 50, 40}},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
dst := image.NewRGBA(image.Rect(0, 0, 2, 1))
if err := rgb24ToRgba(tt.data, dst, tt.bgr); err != nil {
t.Fatal(err)
}
assertBytes(t, "Pix", dst.Pix, []byte{10, 20, 30, 0xFF, 40, 50, 60, 0xFF})
})
}
}
func TestGreyToGray(t *testing.T) {
dst := image.NewGray(image.Rect(0, 0, 2, 2))
if err := greyToGray([]byte{1, 2, 3, 4}, dst); err != nil {
t.Fatal(err)
}
assertBytes(t, "Pix", dst.Pix, []byte{1, 2, 3, 4})
}
func TestPacked422Offsets(t *testing.T) {
for _, f := range []uint32{yuyvFourCC, yuy2FourCC, uyvyFourCC, yvyuFourCC, vyuyFourCC} {
if !is422Format(f) {
t.Errorf("format %d should be 4:2:2", f)
}
}
if is422Format(nv12FourCC) {
t.Error("NV12 is not 4:2:2")
}
if _, _, _, _, ok := packed422Offsets(fourcc("XVID")); ok {
t.Error("XVID should have no offsets")
}
}
func TestBmpToRgba(t *testing.T) {
// 2x1 image, bottom-up BGR(X) source rows.
tests := []struct {
name string
bpp int
data []byte
}{
{"RGB24", 3, []byte{30, 20, 10, 60, 50, 40, 0, 0}}, // 6 data + 2 pad to 8-byte row
{"RGB32", 4, []byte{30, 20, 10, 0, 60, 50, 40, 0}},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
dst := image.NewRGBA(image.Rect(0, 0, 2, 1))
if err := bmpToRgba(tt.data, dst, tt.bpp); err != nil {
t.Fatal(err)
}
assertBytes(t, "Pix", dst.Pix, []byte{10, 20, 30, 0xFF, 40, 50, 60, 0xFF})
})
}
dst := image.NewRGBA(image.Rect(0, 0, 2, 2))
if err := bmpToRgba(make([]byte, 4), dst, 3); err == nil {
t.Error("expected error for short data")
}
}
func assertBytes(t *testing.T, name string, got, want []byte) {
t.Helper()
if len(got) != len(want) {
t.Fatalf("%s: length = %d, want %d", name, len(got), len(want))
}
for i := range want {
if got[i] != want[i] {
t.Errorf("%s[%d] = %d, want %d", name, i, got[i], want[i])
}
}
}