nori/palette.go

88 lines
2.0 KiB
Go

package nori
import (
"encoding/binary"
"fmt"
"image/color"
"io"
)
type PaletteSection struct {
Version uint32
Params [4]uint32
OpaqueIndexCount uint32
DataLength uint32
Palette [256]*color.RGBA
MainBounds [2]uint32
lastSignature [4]byte
}
func (p *PaletteSection) Decode(rd io.Reader) error {
if _, err := io.ReadFull(rd, p.lastSignature[:]); err != nil {
return err
}
if sig, target := string(p.lastSignature[:]), "PAL_"; sig != target {
return fmt.Errorf("bad sig: want %s, got %s", target, sig)
}
p.Palette = [256]*color.RGBA{}
if err := binary.Read(rd, end, &p.Version); err != nil {
return err
}
if err := binary.Read(rd, end, p.Params[:]); err != nil {
return err
}
if err := binary.Read(rd, end, &p.OpaqueIndexCount); err != nil {
return err
}
if err := binary.Read(rd, end, &p.DataLength); err != nil {
return err
}
for i := 0; i < 256; i++ {
rgb := [3]byte{}
_, err := io.ReadFull(rd, rgb[:])
if err != nil {
return err
}
alpha := uint8(0xff)
if rgb[0] == 0x00 && rgb[1] == 0xff && rgb[2] == 0x00 {
alpha = 0x00
}
if rgb[0] == 0xff && rgb[1] == 0x00 && rgb[2] == 0xff {
alpha = 0x00
}
p.Palette[i] = &color.RGBA{
rgb[0], rgb[1], rgb[2],
alpha,
}
}
// NOTE: for some reason, the images do not render right if the first pallette colour alpha is not set to 0
p.setBoard(0, 0, 0)
for i := uint32(0); i < p.OpaqueIndexCount; i++ {
var first uint32
if err := binary.Read(rd, end, &first); err != nil {
return err
}
var last uint32
if err := binary.Read(rd, end, &last); err != nil {
return err
}
//log.Println("oic", p.OpaqueIndexCount, i, first, last)
// TODO: figure out what setBoard actually does
//p.setBoard(first, last, 255)
}
return nil
}
func (p *PaletteSection) setBoard(start uint32, end uint32, alpha int32) {
if !(start >= 0 && end >= 0 && start < 256 && end < 256) {
return
}
for i := start; i <= end; i++ {
p.Palette[i].A = uint8(alpha)
}
}