Browse Source

Split off the container bits to separate package

master
maze 11 months ago
parent
commit
f20822c990
3 changed files with 72 additions and 104 deletions
  1. +59
    -0
      container/dmd1.go
  2. +4
    -0
      container/doc.go
  3. +9
    -104
      dmd1.go

+ 59
- 0
container/dmd1.go View File

@ -0,0 +1,59 @@
package container
import (
"encoding/binary"
"io"
)
// DMD1Chunk is a named chunk.
type DMD1Chunk struct {
// Name of the chunk.
Name [4]byte
// Size of the chunk, including the name of the chunk.
Size uint32
// Data is the payload of the chunk.
Data []byte
}
func (chunk *DMD1Chunk) ReadFrom(r io.Reader) (n int64, err error) {
if err = binary.Read(r, binary.LittleEndian, &chunk.Name); err != nil {
return
}
if err = binary.Read(r, binary.LittleEndian, &chunk.Size); err != nil {
return
}
chunk.Data = make([]byte, chunk.Size)
if chunk.Size > 0 {
if _, err = io.ReadFull(r, chunk.Data); err != nil {
return
}
}
return 8 + int64(chunk.Size), nil
}
func (chunk *DMD1Chunk) WriteTo(w io.Writer) (n int64, err error) {
if err = binary.Write(w, binary.LittleEndian, chunk.Name); err != nil {
return
}
n += 4
chunk.Size = uint32(len(chunk.Data))
if err = binary.Write(w, binary.LittleEndian, chunk.Size); err != nil {
return
}
n += 4
if chunk.Size > 0 {
var m int
if m, err = w.Write(chunk.Data); err != nil {
return
}
n += int64(m)
}
return
}
var (
_ io.ReaderFrom = (*DMD1Chunk)(nil)
_ io.WriterTo = (*DMD1Chunk)(nil)
)

+ 4
- 0
container/doc.go View File

@ -0,0 +1,4 @@
/*
Package container contains helpers for animation(set) containers.
*/
package container

+ 9
- 104
dmd1.go View File

@ -10,6 +10,8 @@ import (
"path/filepath"
"time"
"maze.io/x/dmd/container"
"maze.io/x/dmd/bitmap"
)
@ -25,7 +27,7 @@ const (
// DecodeDMD1 decodes one DMD1 animation (as used in RPI2DMD).
func DecodeDMD1(r io.Reader) (Animation, error) {
var chunk DMD1Chunk
var chunk container.DMD1Chunk
if _, err := chunk.ReadFrom(r); err != nil {
return nil, err
} else if name := string(chunk.Name[:]); name != dmd1Magic {
@ -51,7 +53,7 @@ func DecodeDMD1(r io.Reader) (Animation, error) {
// log.Printf("dmd: DMD1 chunk %q of size %d", name, chunk.size)
switch name {
case dmd1VersionChunk:
if chunk.size != 4 {
if chunk.Size != 4 {
return nil, fmt.Errorf("dmd1: unexpected %q chunk size", name)
}
var version uint32
@ -71,7 +73,7 @@ func DecodeDMD1(r io.Reader) (Animation, error) {
}
func decodeDMD1Animation(r io.Reader, a *imageAnimation) error {
var chunk DMD1Chunk
var chunk container.DMD1Chunk
for {
if _, err := chunk.ReadFrom(r); err == io.EOF {
return nil
@ -117,14 +119,14 @@ func decodeDMD1Animation(r io.Reader, a *imageAnimation) error {
}
func decodeDMD1Frame(r io.Reader, width, height int) (i image.Image, d time.Duration, err error) {
var chunk DMD1Chunk
var chunk container.DMD1Chunk
// TIME chunk.
if _, err = chunk.ReadFrom(r); err != nil {
return
} else if name := string(chunk.Name[:]); name != dmd1FrameTimeChunk {
return nil, 0, fmt.Errorf("dmd: expected DMD1 %q chunk, got %q", dmd1FrameTimeChunk, name)
} else if chunk.size != 4 {
} else if chunk.Size != 4 {
return nil, 0, fmt.Errorf("dmd: unexpected DMD1 %q chunk size", name)
}
d = time.Duration(binary.LittleEndian.Uint32(chunk.Data)) * time.Millisecond
@ -134,8 +136,8 @@ func decodeDMD1Frame(r io.Reader, width, height int) (i image.Image, d time.Dura
return
} else if name := string(chunk.Name[:]); name != dmd1FrameDataChunk {
return nil, 0, fmt.Errorf("dmd: expected DMD1 %q chunk, got %q", dmd1FrameDataChunk, name)
} else if need := uint32(width*height*4) / 2; chunk.size < need {
return nil, 0, fmt.Errorf("dmd: expected DMD1 %q chunk size of %d, got %d", dmd1FrameDataChunk, need, chunk.size)
} else if need := uint32(width*height*4) / 2; chunk.Size < need {
return nil, 0, fmt.Errorf("dmd: expected DMD1 %q chunk size of %d, got %d", dmd1FrameDataChunk, need, chunk.Size)
}
img := bitmap.NewRGBA16Image(image.Rect(0, 0, width, height))
@ -151,102 +153,5 @@ func decodeDMD1Frame(r io.Reader, width, height int) (i image.Image, d time.Dura
img.Pix[i] |= 0x0f
}
/*
img := image.NewRGBA(image.Rect(0, 0, width, height))
for y := 0; y < height; y++ {
o := y * width * 2
for x := 0; x < width; x, o = x+1, o+2 {
c := binary.LittleEndian.Uint16(chunk.Data[o:])
r := uint8((c & 0xf000) >> 12)
r |= r << 4
g := uint8((c & 0x0f00) >> 8)
g |= g << 4
b := uint8((c & 0x00f0) >> 4)
b |= b << 4
img.Set(x, y, color.RGBA{R: r, G: g, B: b, A: 0xff})
}
}
*/
/*
for y := 0; y < height; y++ {
o := y * width
for x := 0; x < width; x, o = x+1, o+1 {
// Pixel data is stored in nibbles, so the nth pixel starts at the n*3rd nibble.
// 01 23 45 67 89 ..
// RG BR GB RG BR GB
n := o * 3 // nibble
if n&1 == 0 {
// Starts at byte.
n /= 2
r := chunk.Data[n] >> 4
r |= r << 4
g := chunk.Data[n] & 0xf
g |= g << 4
b := chunk.Data[n+1] >> 4
b |= b << 4
img.Set(x, y, color.RGBA{R: r, G: g, B: b, A: 0xff})
} else {
// Starts at nibble.
n /= 2
r := chunk.Data[n] & 0xf
r |= r << 4
g := chunk.Data[n+1] >> 4
g |= g << 4
b := chunk.Data[n+1] & 0xf
b |= b << 4
img.Set(x, y, color.RGBA{R: r, G: g, B: b, A: 0xff})
}
}
}
*/
return img, d, nil
}
type DMD1Chunk struct {
Name [4]byte
size uint32
Data []byte
}
func (chunk *DMD1Chunk) ReadFrom(r io.Reader) (n int64, err error) {
if err = binary.Read(r, binary.LittleEndian, &chunk.Name); err != nil {
return
}
if err = binary.Read(r, binary.LittleEndian, &chunk.size); err != nil {
return
}
chunk.Data = make([]byte, chunk.size)
if chunk.size > 0 {
if _, err = io.ReadFull(r, chunk.Data); err != nil {
return
}
}
return 8 + int64(chunk.size), nil
}
func (chunk *DMD1Chunk) WriteTo(w io.Writer) (n int64, err error) {
if err = binary.Write(w, binary.LittleEndian, chunk.Name); err != nil {
return
}
n += 4
chunk.size = uint32(len(chunk.Data))
if err = binary.Write(w, binary.LittleEndian, chunk.size); err != nil {
return
}
n += 4
if chunk.size > 0 {
var m int
if m, err = w.Write(chunk.Data); err != nil {
return
}
n += int64(m)
}
return
}
var (
_ io.ReaderFrom = (*DMD1Chunk)(nil)
_ io.WriterTo = (*DMD1Chunk)(nil)
)

Loading…
Cancel
Save