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) } }