Files
TrollSSH/src/frameformat.go
T

92 lines
2.1 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package main
import (
"bufio"
"encoding/binary"
"fmt"
"math"
"os"
)
// .tsf container, little-endian: "TSFR" | version uint16 | fps float64 |
// count uint32 | count × (colorLen uint32, color JPEG).
const (
tsfMagic = "TSFR"
tsfVersion = 1
)
func writeTSF(output string, data *FramesContainer) error {
f, err := os.Create(output)
if err != nil {
return err
}
defer f.Close()
w := bufio.NewWriterSize(f, 1<<20)
if _, err := w.WriteString(tsfMagic); err != nil {
return err
}
var hdr [14]byte
binary.LittleEndian.PutUint16(hdr[0:], tsfVersion)
binary.LittleEndian.PutUint64(hdr[2:], math.Float64bits(data.FPS))
binary.LittleEndian.PutUint32(hdr[10:], uint32(len(data.ColorFrames)))
if _, err := w.Write(hdr[:]); err != nil {
return err
}
var lenBuf [4]byte
for _, frame := range data.ColorFrames {
binary.LittleEndian.PutUint32(lenBuf[:], uint32(len(frame)))
if _, err := w.Write(lenBuf[:]); err != nil {
return err
}
if _, err := w.Write(frame); err != nil {
return err
}
}
return w.Flush()
}
func loadTSF(filename string) (*FramesContainer, error) {
raw, err := os.ReadFile(filename)
if err != nil {
return nil, err
}
invalid := func() error {
return fmt.Errorf("invalid frames file %q: corrupt .tsf container", filename)
}
if len(raw) < 18 || string(raw[:4]) != tsfMagic {
return nil, invalid()
}
version := binary.LittleEndian.Uint16(raw[4:])
if version != tsfVersion {
return nil, fmt.Errorf("unsupported .tsf version %d in %q", version, filename)
}
fps := math.Float64frombits(binary.LittleEndian.Uint64(raw[6:]))
count := binary.LittleEndian.Uint32(raw[14:])
colorFrames := make([][]byte, 0, count)
off := 18
for range count {
if off+4 > len(raw) {
return nil, invalid()
}
n := int(binary.LittleEndian.Uint32(raw[off:]))
off += 4
if off+n > len(raw) {
return nil, invalid()
}
colorFrames = append(colorFrames, raw[off:off+n])
off += n
}
if len(colorFrames) == 0 || fps <= 0 {
return nil, fmt.Errorf(
"invalid frames file %q: expected non-empty frames and a positive fps",
filename,
)
}
return &FramesContainer{ColorFrames: colorFrames, FPS: fps}, nil
}