92 lines
2.0 KiB
Go
92 lines
2.0 KiB
Go
package main
|
|
|
|
import (
|
|
"encoding/binary"
|
|
"fmt"
|
|
"image"
|
|
"image/png"
|
|
"os"
|
|
"path/filepath"
|
|
|
|
"golang.org/x/image/draw"
|
|
)
|
|
|
|
func main() {
|
|
in := filepath.Join("assets", "navis-icon.png")
|
|
out := filepath.Join("assets", "navis.ico")
|
|
f, err := os.Open(in)
|
|
if err != nil {
|
|
fatal(err)
|
|
}
|
|
defer f.Close()
|
|
src, err := png.Decode(f)
|
|
if err != nil {
|
|
fatal(err)
|
|
}
|
|
|
|
sizes := []int{16, 32, 48, 64, 128, 256}
|
|
type entry struct {
|
|
size int
|
|
png []byte
|
|
}
|
|
var entries []entry
|
|
for _, size := range sizes {
|
|
dst := image.NewRGBA(image.Rect(0, 0, size, size))
|
|
draw.CatmullRom.Scale(dst, dst.Bounds(), src, src.Bounds(), draw.Over, nil)
|
|
tmp := filepath.Join(os.TempDir(), fmt.Sprintf("navis-%d.png", size))
|
|
tf, err := os.Create(tmp)
|
|
if err != nil {
|
|
fatal(err)
|
|
}
|
|
if err := png.Encode(tf, dst); err != nil {
|
|
tf.Close()
|
|
fatal(err)
|
|
}
|
|
tf.Close()
|
|
b, err := os.ReadFile(tmp)
|
|
_ = os.Remove(tmp)
|
|
if err != nil {
|
|
fatal(err)
|
|
}
|
|
entries = append(entries, entry{size: size, png: b})
|
|
}
|
|
|
|
var blob []byte
|
|
offset := 6 + 16*len(entries)
|
|
for _, e := range entries {
|
|
blob = append(blob, e.png...)
|
|
}
|
|
|
|
buf := make([]byte, offset+len(blob))
|
|
binary.LittleEndian.PutUint16(buf[0:], 0) // reserved
|
|
binary.LittleEndian.PutUint16(buf[2:], 1) // icon
|
|
binary.LittleEndian.PutUint16(buf[4:], uint16(len(entries)))
|
|
dataOff := offset
|
|
for i, e := range entries {
|
|
dir := buf[6+i*16:]
|
|
w, h := e.size, e.size
|
|
if w >= 256 {
|
|
dir[0], dir[1] = 0, 0
|
|
} else {
|
|
dir[0], dir[1] = byte(w), byte(h)
|
|
}
|
|
dir[2] = 0 // colors
|
|
dir[3] = 0
|
|
binary.LittleEndian.PutUint16(dir[4:], 1) // planes
|
|
binary.LittleEndian.PutUint16(dir[6:], 32)
|
|
binary.LittleEndian.PutUint32(dir[8:], uint32(len(e.png)))
|
|
binary.LittleEndian.PutUint32(dir[12:], uint32(dataOff))
|
|
copy(buf[dataOff:], e.png)
|
|
dataOff += len(e.png)
|
|
}
|
|
if err := os.WriteFile(out, buf, 0o644); err != nil {
|
|
fatal(err)
|
|
}
|
|
fmt.Println("wrote", out)
|
|
}
|
|
|
|
func fatal(err error) {
|
|
fmt.Fprintln(os.Stderr, err)
|
|
os.Exit(1)
|
|
}
|