diff --git a/formats/dc6/dc6.go b/formats/dc6/dc6.go index 49c1fb6..7417267 100644 --- a/formats/dc6/dc6.go +++ b/formats/dc6/dc6.go @@ -1,6 +1,7 @@ package dc6 import ( + "bytes" "encoding/binary" "io" ) @@ -28,7 +29,7 @@ type FrameHeader struct { OffsetY uint32 AllocSize uint32 NextBlock uint32 - Block uint32 + Length uint32 } type Frame struct { @@ -71,20 +72,18 @@ func New(reader io.ReadSeeker) (*Dc6, error) { return nil, err } + buff := bytes.NewBuffer(make([]byte, frameHeader.Width*frameHeader.Height)) + // if err := extractFrame(reader, buff, frameHeader); err != nil { + if err := extractFrame(reader, nil, frameHeader); err != nil { + return nil, err + } + frame := Frame{ int(frameHeader.Width), int(frameHeader.Height), int(frameHeader.OffsetX), int(frameHeader.OffsetY), - make([]byte, frameHeader.Width*frameHeader.Height), - } - - if _, err := io.ReadFull(reader, frame.Data); err != nil { - return nil, err - } - - if err := extractFrame(reader, frameHeader); err != nil { - return nil, err + buff.Bytes(), } sprite.Frames = append(sprite.Frames, frame) @@ -93,6 +92,36 @@ func New(reader io.ReadSeeker) (*Dc6, error) { return sprite, nil } -func extractFrame(reader io.ReadSeeker, header FrameHeader) error { +func extractFrame(reader io.ReadSeeker, writer io.WriteSeeker, header FrameHeader) error { + var ( + x uint32 + y = header.Height - 1 + ) + + var offset uint32 + for offset < header.Length { + var chunkSize byte + if err := binary.Read(reader, binary.LittleEndian, &chunkSize); err != nil { + return err + } + + if chunkSize == 0x80 { + x = 0 + y-- + } else if (chunkSize & 0x80) != 0 { + x += uint32(chunkSize & 0x7f) + } else { + if _, err := writer.Seek(int64(header.Width*y+x), io.SeekStart); err != nil { + return err + } + if _, err := io.CopyN(writer, reader, int64(chunkSize)); err != nil { + return err + } + + offset += uint32(chunkSize) + x += uint32(chunkSize) + } + } + return nil }