Browse Source

Docs and better color names

master 0.0.2
maze 1 year ago
parent
commit
02ebbf68ad
6 changed files with 42 additions and 12 deletions
  1. +30
    -7
      color.go
  2. +1
    -1
      color_test.go
  3. +2
    -2
      image.go
  4. +1
    -0
      rundmd.go
  5. +7
    -1
      vpin.go
  6. +1
    -1
      vpin_test.go

+ 30
- 7
color.go View File

@ -6,13 +6,17 @@ import (
"image/color"
"io"
"io/ioutil"
"math/bits"
"os"
)
// RGB24 is a color with 8-bit red, green and blue channels.
type RGB24 struct {
R, G, B uint8
}
// RGBA returns the alpha-premultiplied red, green, blue and alpha values
// for the color.
func (c RGB24) RGBA() (r, g, b, a uint32) {
r = uint32(c.R) | uint32(c.R)<<8
g = uint32(c.G) | uint32(c.G)<<8
@ -21,7 +25,8 @@ func (c RGB24) RGBA() (r, g, b, a uint32) {
return
}
func readRGB24(r io.Reader) (RGB24, error) {
// DecodeRGB24 decodes one RGB24 color from the supplied Reader.
func DecodeRGB24(r io.Reader) (RGB24, error) {
var c RGB24
if err := binary.Read(r, binary.BigEndian, &c); err != nil {
return c, err
@ -29,9 +34,17 @@ func readRGB24(r io.Reader) (RGB24, error) {
return c, nil
}
type RGBA4Bit uint16
// RGBA16 is a color with 4-bit red, green, blue and alpha channels.
type RGBA16 uint16
func (c RGBA4Bit) RGBA() (r, g, b, a uint32) {
// ByteSwap swaps the endianness of the color.
func (c *RGBA16) ByteSwap() {
*c = RGBA16(bits.Reverse16(uint16(*c)))
}
// RGBA returns the alpha-premultiplied red, green, blue and alpha values
// for the color.
func (c RGBA16) RGBA() (r, g, b, a uint32) {
r = uint32((c&0xf000)>>12) * 0x1111
g = uint32((c&0x0f00)>>8) * 0x1111
b = uint32((c&0x00f0)>>4) * 0x1111
@ -39,6 +52,15 @@ func (c RGBA4Bit) RGBA() (r, g, b, a uint32) {
return
}
// DecodeRGBA16 decodes one RGBA16 color from the supplied Reader.
func DecodeRGBA16(r io.Reader, byteOrder binary.ByteOrder) (RGBA16, error) {
var c RGBA16
if err := binary.Read(r, byteOrder, &c); err != nil {
return c, err
}
return c, nil
}
// Pin2DMDColoring contains a coloring description.
type Pin2DMDColoring struct {
Version uint8
@ -140,17 +162,18 @@ func (c *Pin2DMDColoring) FindMapping(p *Plane, reverse bool) *Mapping {
}
*/
// LoadPin2DMDColoring loads *.pal files.
// LoadPin2DMDColoring loads *.pal Pin2DMD colorization files.
func LoadPin2DMDColoring(name string) (*Pin2DMDColoring, error) {
f, err := os.Open(name)
if err != nil {
return nil, err
}
defer func() { _ = f.Close() }()
return ReadPin2DMDColoring(f)
return DecodePin2DMDColoring(f)
}
func ReadPin2DMDColoring(r io.Reader) (c *Pin2DMDColoring, err error) {
// DecodePin2DMDColoring decodes palette mappings from the supplied Reader.
func DecodePin2DMDColoring(r io.Reader) (c *Pin2DMDColoring, err error) {
c = new(Pin2DMDColoring)
if err = binary.Read(r, binary.BigEndian, &c.Version); err != nil {
return
@ -204,7 +227,7 @@ func ReadPalette(r io.Reader) (p *Palette, err error) {
A: 0xff,
}
/*
if p.Colors[i], err = readRGB24(r); err != nil {
if p.Colors[i], err = DecodeRGB24(r); err != nil {
return nil, err
}
*/


+ 1
- 1
color_test.go View File

@ -21,7 +21,7 @@ func TestReadColoring(t *testing.T) {
}
defer f.Close()
c, err := ReadPin2DMDColoring(f)
c, err := DecodePin2DMDColoring(f)
if err != nil {
it.Fatal(err)
}


+ 2
- 2
image.go View File

@ -20,7 +20,7 @@ func (i RGBA4BitImage) At(x, y int) color.Color {
return color.Transparent
}
o := (y*i.Rect.Max.X + x) * 2
return RGBA4Bit(binary.LittleEndian.Uint16(i.Pix[o:]))
return RGBA16(binary.LittleEndian.Uint16(i.Pix[o:]))
}
func (i RGBA4BitImage) Set(x, y int, c color.Color) {
@ -28,7 +28,7 @@ func (i RGBA4BitImage) Set(x, y int, c color.Color) {
return
}
o := y*i.Rect.Dx()*2 + x*2
if v, ok := c.(RGBA4Bit); ok {
if v, ok := c.(RGBA16); ok {
binary.LittleEndian.PutUint16(i.Pix[o:], uint16(v))
} else {
r, g, b, a := c.RGBA()


+ 1
- 0
rundmd.go View File

@ -19,6 +19,7 @@ const (
runDMDHeaderSize = 0x0200
)
// DecodeRunDMD can decode animations in a (raw) Run-DMD SD card image.
func DecodeRunDMD(r io.ReadSeeker) (Animations, error) {
var magic [3]byte
if _, err := io.ReadFull(r, magic[:]); err != nil {


+ 7
- 1
vpin.go View File

@ -13,10 +13,16 @@ import (
"maze.io/x/dmd/internal/heatshrink"
)
// DecodeVPIN calls DecodeVPINWithColoring.
func DecodeVPIN(r io.Reader) (Animations, error) {
return DecodeVPINWithColoring(r, nil)
}
// DecodeVPINWithColoring can decode animations from a Virtual Pinball animation file.
//
// Typically, these animation file are called "pin2dmd.vni" or "pin2dmd.ani". If you
// have a machine palette file ("pin2dmd.pal"), you can load the coloring definitions
// with LoadPin2DMDColoring / DecodePin2DMDColoring.
func DecodeVPINWithColoring(r io.Reader, c *Pin2DMDColoring) (Animations, error) {
var (
magic [4]byte
@ -178,7 +184,7 @@ func decodeVPINPalettesAndColors(r io.Reader, a *imageAnimation) (index int, err
a.palette = make(color.Palette, header.Colors)
for i := 0; i < int(header.Colors); i++ {
if a.palette[i], err = readRGB24(r); err != nil {
if a.palette[i], err = DecodeRGB24(r); err != nil {
return
}
}


+ 1
- 1
vpin_test.go View File

@ -38,7 +38,7 @@ func TestDecodeVPIN(t *testing.T) {
}
defer func() { _ = f.Close() }()
if c, err = ReadPin2DMDColoring(f); err != nil {
if c, err = DecodePin2DMDColoring(f); err != nil {
it.Fatal(err)
}
}


Loading…
Cancel
Save