2022-03-25 21:00:43 +00:00
|
|
|
package nori
|
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/binary"
|
|
|
|
"fmt"
|
|
|
|
"image/color"
|
|
|
|
"io"
|
|
|
|
)
|
|
|
|
|
|
|
|
type PaletteSection struct {
|
2024-08-06 04:27:48 +00:00
|
|
|
Version uint32
|
|
|
|
Params [4]uint32
|
|
|
|
OpaqueIndexCount uint32
|
|
|
|
DataLength uint32
|
|
|
|
Palette [256]*color.RGBA
|
|
|
|
MainBounds [2]uint32
|
2022-03-25 21:00:43 +00:00
|
|
|
|
|
|
|
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)
|
|
|
|
}
|
2024-08-06 04:27:48 +00:00
|
|
|
p.Palette = [256]*color.RGBA{}
|
2022-03-25 21:00:43 +00:00
|
|
|
if err := binary.Read(rd, end, &p.Version); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if err := binary.Read(rd, end, p.Params[:]); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2024-08-06 04:27:48 +00:00
|
|
|
if err := binary.Read(rd, end, &p.OpaqueIndexCount); err != nil {
|
2022-03-25 21:00:43 +00:00
|
|
|
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,
|
|
|
|
}
|
|
|
|
}
|
2024-08-06 04:41:04 +00:00
|
|
|
// 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)
|
2024-08-06 04:27:48 +00:00
|
|
|
|
|
|
|
for i := uint32(0); i < p.OpaqueIndexCount; i++ {
|
|
|
|
var first uint32
|
|
|
|
if err := binary.Read(rd, end, &first); err != nil {
|
2022-03-25 21:00:43 +00:00
|
|
|
return err
|
|
|
|
}
|
2024-08-06 04:27:48 +00:00
|
|
|
|
|
|
|
var last uint32
|
|
|
|
if err := binary.Read(rd, end, &last); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2024-08-06 04:41:04 +00:00
|
|
|
//log.Println("oic", p.OpaqueIndexCount, i, first, last)
|
2024-08-06 04:27:48 +00:00
|
|
|
// TODO: figure out what setBoard actually does
|
|
|
|
//p.setBoard(first, last, 255)
|
2022-03-25 21:00:43 +00:00
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
2024-08-06 04:27:48 +00:00
|
|
|
|
|
|
|
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)
|
|
|
|
}
|
|
|
|
}
|