color/internal/helper/rgb_test.go
2025-03-06 13:01:21 -05:00

124 lines
3.8 KiB
Go

package helper
import (
"fmt"
"image/color"
"testing"
)
type testNRGBA struct {
color.NRGBA64
}
func (c testNRGBA) NRGBA() (_, _, _, _ uint32) {
return uint32(c.R), uint32(c.G), uint32(c.B), uint32(c.A)
}
type testNLRGBA struct {
color.NRGBA64
}
func (c testNLRGBA) NLRGBA() (_, _, _, _ float64) {
return Linearize(uint32(c.R)), Linearize(uint32(c.G)), Linearize(uint32(c.B)), float64(c.A) / 0xffff
}
type testNXYZA struct {
color.NRGBA64
}
func (c testNXYZA) NXYZA() (_, _, _, _ float64) {
x, y, z := LRGBtoXYZ(Linearize(uint32(c.R)), Linearize(uint32(c.G)), Linearize(uint32(c.B)))
return x, y, z, float64(c.A) / 0xffff
}
type testNOkLabA struct {
color.NRGBA64
}
func (c testNOkLabA) NOkLabA() (_, _, _, _ float64) {
l, a, b := LMStoOkLab(LRGBtoLMS(Linearize(uint32(c.R)), Linearize(uint32(c.G)), Linearize(uint32(c.B))))
return l, a, b, float64(c.A) / 0xffff
}
func TestColorToNLRGBA(t *testing.T) {
tests := []struct {
input color.Color
want [4]float64
}{
{
// test special NRGBA handling.
color.NRGBA{0x01, 0x23, 0x45, 0x67},
[4]float64{Linearize(0x0101), Linearize(0x2323), Linearize(0x4545), float64(0x6767) / 0xffff},
}, {
// test special NRGBA64 handling.
color.NRGBA64{0x0123, 0x4567, 0x89ab, 0xcdef},
[4]float64{Linearize(0x0123), Linearize(0x4567), Linearize(0x89ab), float64(0xcdef) / 0xffff},
}, {
// test a colour that can returns is NRGBA values directly.
testNRGBA{color.NRGBA64{0x0123, 0x4567, 0x89ab, 0xcdef}},
[4]float64{Linearize(0x0123), Linearize(0x4567), Linearize(0x89ab), float64(0xcdef) / 0xffff},
}, {
// test a colour that can return its NLRGBA values directly.
testNLRGBA{color.NRGBA64{0x0123, 0x4567, 0x89ab, 0xcdef}},
[4]float64{Linearize(0x0123), Linearize(0x4567), Linearize(0x89ab), float64(0xcdef) / 0xffff},
}, {
// test a colour that can returns its NXYZA values directly.
testNXYZA{color.NRGBA64{0x0123, 0x4567, 0x89ab, 0xcdef}},
[4]float64{Linearize(0x0123), Linearize(0x4567), Linearize(0x89ab), float64(0xcdef) / 0xffff},
}, {
// test a colour that can returns its NOkLabA values directly.
testNOkLabA{color.NRGBA64{0x0123, 0x4567, 0x89ab, 0xcdef}},
[4]float64{Linearize(0x0123), Linearize(0x4567), Linearize(0x89ab), float64(0xcdef) / 0xffff},
}, {
// the FromRGBA codepath with partial transparency
color.RGBA64{0x0123, 0x4567, 0x89ab, 0xcdef},
[4]float64{
Linearize((0x0123*0xffff + 0xcdee - 1) / 0xcdef),
Linearize((0x4567*0xffff + 0xcdee - 1) / 0xcdef),
Linearize((0x89ab*0xffff + 0xcdee - 1) / 0xcdef),
float64(0xcdef) / 0xffff,
},
}, {
// the FromRGBA codepath with full transparency
color.RGBA64{0x0000, 0x0000, 0x0000, 0x0000},
[4]float64{0, 0, 0, 0},
}, {
// the FromRGBA codepath with full opacity
color.RGBA64{0x0123, 0x4567, 0x89ab, 0xffff},
[4]float64{Linearize(0x0123), Linearize(0x4567), Linearize(0x89ab), 1},
},
}
for _, tt := range tests {
t.Run(fmt.Sprintf("%#+v", tt.input), func(t *testing.T) {
if got := collect4(ColorToNLRGBA(tt.input)); !EqFloat64SliceFuzzy(got[:], tt.want[:]) {
t.Errorf("ColorToNLRGBA(%#+v) = %v, want %v", tt.input, got, tt.want)
}
})
}
}
func TestNLRGBAtoRGBA(t *testing.T) {
tests := []struct {
input [4]float64
want [4]uint32
}{
{
[4]float64{0, .5, 1, 0},
[4]uint32{0, 0, 0, 0},
}, {
[4]float64{.25, .5, .75, 1},
[4]uint32{Delinearize(.25), Delinearize(.5), Delinearize(.75), 0xffff},
}, {
[4]float64{.25, .5, .75, .5},
[4]uint32{Delinearize(.25) / 2, Delinearize(.5) / 2, Delinearize(.75) / 2, 0x8000},
},
}
for _, tt := range tests {
t.Run(fmt.Sprintf("%v", tt.input), func(t *testing.T) {
if got := collect4(NLRGBAtoRGBA(tt.input[0], tt.input[1], tt.input[2], tt.input[3])); got != tt.want {
t.Errorf("NLRGBAtoRGBA(%v) = %v, want %v", tt.input, got, tt.want)
}
})
}
}