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) } }) } }