package main import ( "bytes" "encoding/json" "flag" "fmt" "git.tuxpa.in/a/nori/renderer" "gitlab.com/gfxlabs/gfximg/apng" "golang.org/x/sync/errgroup" "io/ioutil" "os" "path/filepath" "strings" "time" "git.tuxpa.in/a/nori" "git.tuxpa.in/a/nori/utils" "git.tuxpa.in/a/zlog/log" ) var ( dumpPtr = flag.Bool("d", false, "dump nri file to zip") silentPtr = flag.Bool("s", false, "silent") bulkDumpPtr = flag.Bool("b", false, "bulk dump nris from a folder") jsonDumpPtr = flag.Bool("j", false, "bulk dump nri animation names from a folder") directoryPtr = flag.String("dir", "nri", "directory to bulk dump from") destinationPtr = flag.String("dest", "", "directory to bulk dump to") filePtr = flag.String("f", "example.nri", "file to load") outputPtr = flag.String("o", "output.zip", "output zip file") ) func main() { flag.Parse() if *dumpPtr { filename := *filePtr output := *outputPtr if _, err := os.Stat(filename); err != nil { printIf("could not find file %s\n", filename) return } dump(filename, output) return } dir := *directoryPtr dest := *destinationPtr if dest == "" { dest = dir } printIf("output: %s\n", dest) if *bulkDumpPtr || *jsonDumpPtr { files, err := ioutil.ReadDir(dir) if err != nil { printIf("%s: %s\n", dir, err) return } egg := errgroup.Group{} egg.SetLimit(12) for _, ff := range files { f := ff if strings.HasSuffix(f.Name(), ".nri") { egg.Go(func() error { if *bulkDumpPtr { dump_nozip(dir+"/"+f.Name(), dest) } if *jsonDumpPtr { dump_anim_json(dir+"/"+f.Name(), dest) } return nil }) } } if err := egg.Wait(); err != nil { log.Panicf("oh fuck: %s\n", err) return } } flag.PrintDefaults() } func printIf(s string, args ...interface{}) { if !*silentPtr { fmt.Printf(s, args...) } } func dump_anim_json(filename string, destination string) { start := time.Now() printIf("reading file '%s'\n", filename) n, err := nori.FromFile(filename) if err != nil { log.Panicln("decode: %s", err) } names, err := nori.GetAnimationNames(n) if err != nil { log.Panicln("animation: %s", err) } json, err := json.Marshal(names) if err != nil { log.Panicln("could not marshal json: %s\n", err) } baseName := filepath.Base(strings.TrimSuffix(filename, filepath.Ext(filename))) output := fmt.Sprintf("%s/%s.json", destination, baseName) f, fErr := os.OpenFile(output, os.O_CREATE, 0740) if fErr != nil { panic(fErr) } defer f.Close() if _, err := f.Write(json); err != nil { return } printIf("done in %v \n", time.Now().Sub(start)) } func dump_nozip(filename string, destination string) { start := time.Now() printIf("reading file '%s'\n", filename) n, err := nori.FromFile(filename) if err != nil { log.Panicln("decode: %s", err) } // printIf("rendering %d animation(s)\n", n.AnimationCount) animations, err := renderer.RenderAnimationsApng(n) if err != nil { log.Panicln("animation: %s", err) } baseName := filepath.Base(strings.TrimSuffix(filename, filepath.Ext(filename))) for i, v := range animations { output := fmt.Sprintf(destination+"/%s_%d.png", baseName, i) // printIf("saving to %s \n", output) f, fErr := os.OpenFile(output, os.O_CREATE, 0740) if fErr != nil { panic(fErr) } defer f.Close() if err := apng.Encode(f, *v); err != nil { return } } // //if err := utils.ZipApngs(out, animations); err != nil { // log.Panicln("zipping: %s", err) //} printIf("done in %v \n", time.Now().Sub(start)) //os.WriteFile(output, out.Bytes(), 0740) } func dump(filename string, output string) { start := time.Now() printIf("reading file '%s'\n", filename) n, err := nori.FromFile(filename) if err != nil { log.Panicln("decode: %s", err) } out := new(bytes.Buffer) printIf("rendering %d animation(s)\n", n.AnimationCount) animations, err := renderer.RenderAnimationsApng(n) if err != nil { log.Panicln("animation: %s", err) } printIf("saving to %s \n", output) if err := utils.ZipApngs(out, animations); err != nil { log.Panicln("zipping: %s", err) } printIf("done in %v \n", time.Now().Sub(start)) os.WriteFile(output, out.Bytes(), 0740) }