This commit is contained in:
elee 2022-03-25 01:00:01 -05:00
parent 023563f713
commit 86b1432f60
10 changed files with 111 additions and 11 deletions

View File

@ -109,7 +109,6 @@ func (a *Animation) Decode(rd *bufio.Reader, version int) error {
return err return err
} }
var cast uint32 var cast uint32
if err := binary.Read(rd, end, &cast); err != nil { if err := binary.Read(rd, end, &cast); err != nil {
return err return err
} }

19
common/nori/export.go Normal file
View File

@ -0,0 +1,19 @@
package nori
import "gitlab.com/gfxlabs/gfximg/apng"
func (n *Nori) ExportAnimation() *apng.APNG {
g := n.Gawi
a := &apng.APNG{
Frames: make([]apng.Frame, 0, len(g.Images)),
}
for i := 0; i < len(g.Images); i++ {
fr := apng.Frame{
Image: g.Images[i].Frame,
DelayNumerator: uint16(g.Images[i].Delay),
DelayDenominator: 1000,
}
a.Frames = append(a.Frames, fr)
}
return a
}

View File

@ -25,13 +25,24 @@ type Image struct {
Frame image.Image Frame image.Image
} }
func (i *Image) Decode(rd *bufio.Reader) error {
func (i *Image) Decode(rd *bufio.Reader, palette *PaletteSection) error {
cf := image.NewRGBA64(image.Rect(0, 0, int(i.Width), int(i.Height))) cf := image.NewRGBA64(image.Rect(0, 0, int(i.Width), int(i.Height)))
i.Frame = cf i.Frame = cf
switch i.Bpp { switch i.Bpp {
case 8: case 8:
rd.Discard(int(i.Size)) if palette == nil {
return fmt.Errorf("bpp = 8, but no palette") return fmt.Errorf("bpp = 8, but no palette")
}
for idx := 0; idx < int(i.Size); idx++ {
b, err := rd.ReadByte()
if err != nil {
return err
}
col := palette.Palette[b]
cf.Set(idx%int(i.Width), idx/int(i.Width), col)
}
return nil
case 16: case 16:
var bgr uint16 var bgr uint16
for idx := 0; idx < int(i.Size/2); idx++ { for idx := 0; idx < int(i.Size/2); idx++ {
@ -69,3 +80,4 @@ func (i *Image) Decode(rd *bufio.Reader) error {
return fmt.Errorf("unsupported bpp, %d", i.Bpp) return fmt.Errorf("unsupported bpp, %d", i.Bpp)
} }
} }

View File

@ -1,14 +1,14 @@
package nori package nori
import "image/color"
type PaletteSection struct { type PaletteSection struct {
Version uint32 Version uint32
Param01 uint32 Params [4]uint32
Param02 uint32
Param03 uint32
Param04 uint32
Divided bool Divided bool
DataLength uint32 DataLength uint32
// Graphics::Palette color_data Palette [256]color.Color
MainBound [2]uint32
} }
type GawiSection struct { type GawiSection struct {

View File

@ -1,8 +1,11 @@
package nori package nori
import ( import (
"bytes"
"os" "os"
"testing" "testing"
"gitlab.com/gfxlabs/gfximg/apng"
) )
func TestParseFile1(t *testing.T) { func TestParseFile1(t *testing.T) {
@ -28,3 +31,24 @@ func TestParseFile2(t *testing.T) {
} }
t.Logf("\n nori: %+v\n gawi: %+v", nori, nori.Gawi) t.Logf("\n nori: %+v\n gawi: %+v", nori, nori.Gawi)
} }
func TestParsePalette(t *testing.T) {
rd, err := os.OpenFile("./nori_test/palette.nri", os.O_RDONLY, 0666)
if err != nil {
t.Logf("open file: %s", err)
t.Fail()
}
nori, err := NewReader(rd).Decode()
if err != nil {
t.Errorf("decode: %s", err)
}
t.Logf("\n nori: %+v\n gawi: %+v\n palette: %+v\n", nori, nori.Gawi, nori.Gawi.Palette)
out := new(bytes.Buffer)
a := nori.ExportAnimation()
err = apng.Encode(out, *a)
if err != nil {
t.Errorf("encode: %s", err)
}
os.WriteFile("./nori_test/palette.apng", out.Bytes(), 0740)
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 969 KiB

Binary file not shown.

View File

@ -4,6 +4,7 @@ import (
"bufio" "bufio"
"encoding/binary" "encoding/binary"
"fmt" "fmt"
"image/color"
"io" "io"
) )
@ -98,8 +99,11 @@ func (n *Reader) decodeGawi() error {
return err return err
} }
if g.HasPalette { if g.HasPalette {
n.decodePalette() if err := n.decodePalette(); err != nil {
return err
} }
}
fmt.Printf("\n-------\n n:'%+v'\n g:'%+v'", n, g)
if _, err := n.r.Discard(4 * int(g.BmpCount)); err != nil { if _, err := n.r.Discard(4 * int(g.BmpCount)); err != nil {
return err return err
} }
@ -118,9 +122,47 @@ func (n *Reader) decodeGawi() error {
} }
func (n *Reader) decodePalette() error { func (n *Reader) decodePalette() error {
if _, err := io.ReadFull(n, n.nori.lastSignature[:]); err != nil {
return err
}
if sig, target := string(n.nori.lastSignature[:]), "PAL_"; sig != target { if sig, target := string(n.nori.lastSignature[:]), "PAL_"; sig != target {
return fmt.Errorf("bad sig: want %s, got %s", target, sig) return fmt.Errorf("bad sig: want %s, got %s", target, sig)
} }
cp := &PaletteSection{
Palette: [256]color.Color{},
}
n.nori.Gawi.Palette = cp
if err := binary.Read(n, end, &cp.Version); err != nil {
return err
}
if err := binary.Read(n, end, cp.Params[:]); err != nil {
return err
}
var cast uint32
if err := binary.Read(n, end, &cast); err != nil {
return err
}
cp.Divided = (cast > 0)
if err := binary.Read(n, end, &cp.DataLength); err != nil {
return err
}
for i := 0; i < 256; i++ {
rgb := [3]byte{}
_, err := io.ReadFull(n, rgb[:])
if err != nil {
return err
}
cp.Palette[i] = &color.RGBA{
rgb[0], rgb[1], rgb[2],
0xff,
}
}
if cp.Divided {
if err := binary.Read(n, end, cp.MainBound[:]); err != nil {
return err
}
}
return nil return nil
} }
func (n *Reader) decodeImage(img *Image) error { func (n *Reader) decodeImage(img *Image) error {
@ -154,7 +196,7 @@ func (n *Reader) decodeImage(img *Image) error {
if err := binary.Read(n, end, &img.OffsetY); err != nil { if err := binary.Read(n, end, &img.OffsetY); err != nil {
return err return err
} }
if err := img.Decode(n.r); err != nil { if err := img.Decode(n.r, n.nori.Gawi.Palette); err != nil {
return err return err
} }
return nil return nil

2
go.mod
View File

@ -1,3 +1,5 @@
module git.tuxpa.in/a/gotagonist module git.tuxpa.in/a/gotagonist
go 1.18 go 1.18
require gitlab.com/gfxlabs/gfximg v0.0.5

2
go.sum Normal file
View File

@ -0,0 +1,2 @@
gitlab.com/gfxlabs/gfximg v0.0.5 h1:jtHE6In6axz0zGPy7YnLIZV9RFdcFEZzpdqoXb52K9s=
gitlab.com/gfxlabs/gfximg v0.0.5/go.mod h1:IAYZwCoqy3JFKwkKafragpfecp5Up6FFIzI7VvK2Zzo=