switch to big-endian format

This commit is contained in:
Lars Hoogestraat 2020-12-05 18:50:58 +01:00
parent f02a707e5f
commit 61b71fc549
2 changed files with 33 additions and 29 deletions

View File

@ -5,7 +5,6 @@
package rgb565
import (
"encoding/binary"
"image"
"image/color"
"math"
@ -13,7 +12,7 @@ import (
// RGBA is an in-memory image whose At method returns color.RGBA values.
type RGB565 struct {
// Pix holds the image's pixels, as RGB565 values. The pixel at
// Pix holds the image's pixels, as RGB565 values in big-endian format. The pixel at
// (x, y) starts at Pix[(y-p.Rect.Min.Y)*p.Stride + (x-p.Rect.Min.X)*2].
Pix []uint8
// Stride is the Pix stride (in bytes) between vertically adjacent pixels.
@ -26,7 +25,9 @@ type RGB565 struct {
var Model = color.ModelFunc(rgb565Model)
//Color represents a RGB565 color.
type Color uint16
type Color struct {
RGB565 uint16
}
// NewRGB565 returns a new RGB565 image with the given bounds.
func NewRGB565(r image.Rectangle) *RGB565 {
@ -43,16 +44,16 @@ func (p *RGB565) Bounds() image.Rectangle {
func (p *RGB565) At(x, y int) color.Color {
if !(image.Point{x, y}.In(p.Rect)) {
return Color(0)
return Color{0}
}
i := p.PixOffset(x, y)
return Color(binary.LittleEndian.Uint16(p.Pix[i : i+2]))
return Color{uint16(p.Pix[i])<<8 | uint16(p.Pix[i+1])}
}
func (p *RGB565) PixOffset(x, y int) int {
return (y-p.Rect.Min.Y)*p.Stride + (x-p.Rect.Min.X)*2
return 2*(x-p.Rect.Min.X) + (y-p.Rect.Min.Y)*p.Stride
}
func (p *RGB565) Set(x, y int, c color.Color) {
@ -60,7 +61,10 @@ func (p *RGB565) Set(x, y int, c color.Color) {
return
}
i := p.PixOffset(x, y)
binary.LittleEndian.PutUint16(p.Pix[i:i+2], uint16(Model.Convert(c).(Color)))
c1 := Model.Convert(c).(Color)
p.Pix[i+0] = uint8(c1.RGB565 >> 8)
p.Pix[i+1] = uint8(c1.RGB565)
}
func (p *RGB565) ColorModel() color.Model {
@ -68,9 +72,9 @@ func (p *RGB565) ColorModel() color.Model {
}
func (c Color) RGBA() (r, g, b, a uint32) {
r = uint32(c&0b1111100000000000) >> 11
g = uint32(c&0b0000011111100000) >> 5
b = uint32(c&0b0000000000011111) >> 0
r = uint32(c.RGB565&0b1111100000000000) >> 11
g = uint32(c.RGB565&0b0000011111100000) >> 5
b = uint32(c.RGB565&0b0000000000011111) >> 0
r = uint32(math.Round(float64(r)*255/31)) << 8
g = uint32(math.Round(float64(g)*255/63)) << 8
@ -88,5 +92,5 @@ func rgb565Model(c color.Color) color.Color {
r, g, b, _ := c.RGBA()
return Color((r<<8)&0b1111100000000000 | (g<<3)&0b0000011111100000 | (b>>3)&0b0000000000011111)
return Color{uint16((r<<8)&0b1111100000000000 | (g<<3)&0b0000011111100000 | (b>>3)&0b0000000000011111)}
}

View File

@ -8,37 +8,37 @@ import (
)
var rgb565TestCases = []struct {
rgb color.RGBA
rgb565 rgb565.Color
rgbColor color.RGBA
rgb565Color rgb565.Color
}{
{rgb: color.RGBA{R: 0x00, G: 0x00, B: 0x00, A: 0xff}, rgb565: 0x0000},
{rgb: color.RGBA{R: 0x84, G: 0x00, B: 0x00, A: 0xff}, rgb565: 0x8000},
{rgb: color.RGBA{R: 0x00, G: 0x82, B: 0x00, A: 0xff}, rgb565: 0x0400},
{rgb: color.RGBA{R: 0x00, G: 0x00, B: 0x84, A: 0xff}, rgb565: 0x0010},
{rgb: color.RGBA{R: 0x00, G: 0x2d, B: 0x84, A: 0xff}, rgb565: 0x170},
{rgb: color.RGBA{R: 0x84, G: 0x2d, B: 0x84, A: 0xff}, rgb565: 0x8170},
{rgb: color.RGBA{R: 0x84, G: 0xff, B: 0xff, A: 0xff}, rgb565: 0x87ff},
{rgb: color.RGBA{R: 0x84, G: 0x82, B: 0xff, A: 0xff}, rgb565: 0x841f},
{rgb: color.RGBA{R: 0x84, G: 0x82, B: 0x84, A: 0xff}, rgb565: 0x8410},
{rgb: color.RGBA{R: 0xff, G: 0xff, B: 0xff, A: 0xff}, rgb565: 0xFFFF},
{rgbColor: color.RGBA{R: 0x00, G: 0x00, B: 0x00, A: 0xff}, rgb565Color: rgb565.Color{RGB565: 0x0000}},
{rgbColor: color.RGBA{R: 0x84, G: 0x00, B: 0x00, A: 0xff}, rgb565Color: rgb565.Color{RGB565: 0x8000}},
{rgbColor: color.RGBA{R: 0x00, G: 0x82, B: 0x00, A: 0xff}, rgb565Color: rgb565.Color{RGB565: 0x0400}},
{rgbColor: color.RGBA{R: 0x00, G: 0x00, B: 0x84, A: 0xff}, rgb565Color: rgb565.Color{RGB565: 0x0010}},
{rgbColor: color.RGBA{R: 0x00, G: 0x2d, B: 0x84, A: 0xff}, rgb565Color: rgb565.Color{RGB565: 0x170}},
{rgbColor: color.RGBA{R: 0x84, G: 0x2d, B: 0x84, A: 0xff}, rgb565Color: rgb565.Color{RGB565: 0x8170}},
{rgbColor: color.RGBA{R: 0x84, G: 0xff, B: 0xff, A: 0xff}, rgb565Color: rgb565.Color{RGB565: 0x87ff}},
{rgbColor: color.RGBA{R: 0x84, G: 0x82, B: 0xff, A: 0xff}, rgb565Color: rgb565.Color{RGB565: 0x841f}},
{rgbColor: color.RGBA{R: 0x84, G: 0x82, B: 0x84, A: 0xff}, rgb565Color: rgb565.Color{RGB565: 0x8410}},
{rgbColor: color.RGBA{R: 0xff, G: 0xff, B: 0xff, A: 0xff}, rgb565Color: rgb565.Color{RGB565: 0xFFFF}},
}
func TestRGBToRGB565(t *testing.T) {
for _, test := range rgb565TestCases {
got := rgb565.Model.Convert(test.rgb)
want := test.rgb565
got := rgb565.Model.Convert(test.rgbColor)
want := test.rgb565Color
if got != want {
t.Errorf("unexpected RGB565 value for %+v: got: %016b, want: %016b", test.rgb, got, want)
t.Errorf("unexpected RGB565 value for %+v: got: %016b, want: %016b", test.rgbColor, got, want)
}
}
}
func TestRGB565ToRGBA(t *testing.T) {
for _, test := range rgb565TestCases {
got := color.RGBAModel.Convert(test.rgb565).(color.RGBA)
want := test.rgb
got := color.RGBAModel.Convert(test.rgb565Color).(color.RGBA)
want := test.rgbColor
if got != want {
t.Errorf("unexpected RGBA value for %x: got: %+v, want: %+v", test.rgb565, got, want)
t.Errorf("unexpected RGBA value for %x: got: %+v, want: %+v", test.rgb565Color, got, want)
}
}
}