1
1
mirror of https://github.com/wader/fq.git synced 2024-12-25 22:34:14 +03:00
fq/format/webp/webp.go

76 lines
1.6 KiB
Go
Raw Normal View History

2020-06-08 03:29:51 +03:00
package webp
// https://developers.google.com/speed/webp/docs/riff_container
import (
"bytes"
"github.com/wader/fq/format"
"github.com/wader/fq/pkg/decode"
"github.com/wader/fq/pkg/interp"
"github.com/wader/fq/pkg/scalar"
2020-06-08 03:29:51 +03:00
)
var vp8Frame decode.Group
2020-06-08 03:29:51 +03:00
func init() {
interp.RegisterFormat(decode.Format{
2020-06-08 03:29:51 +03:00
Name: format.WEBP,
Description: "WebP image",
Groups: []string{format.PROBE, format.IMAGE},
DecodeFn: webpDecode,
Dependencies: []decode.Dependency{
{Names: []string{format.VP8_FRAME}, Group: &vp8Frame},
2020-06-08 03:29:51 +03:00
},
})
}
func decodeChunk(d *decode.D, expectedChunkID string, fn func(d *decode.D)) bool {
trimChunkID := d.FieldUTF8("id", 4, scalar.ActualTrimSpace)
2020-06-08 03:29:51 +03:00
if expectedChunkID != "" && trimChunkID != expectedChunkID {
return false
}
2021-12-04 21:15:54 +03:00
chunkLen := int64(d.FieldU32("size"))
2020-06-08 03:29:51 +03:00
if fn != nil {
d.FramedFn(chunkLen*8, fn)
2020-06-08 03:29:51 +03:00
} else {
d.FieldRawLen("data", chunkLen*8)
2020-06-08 03:29:51 +03:00
}
return true
}
func webpDecode(d *decode.D, in any) any {
2021-12-04 21:15:54 +03:00
d.Endian = decode.LittleEndian
d.FieldUTF8("riff_id", 4, d.AssertStr("RIFF"))
2021-12-04 21:15:54 +03:00
riffLength := d.FieldU32("riff_length")
d.FieldUTF8("webp_id", 4, d.AssertStr("WEBP"))
2020-06-08 03:29:51 +03:00
d.FramedFn(int64(riffLength-4)*8, func(d *decode.D) {
2020-06-08 03:29:51 +03:00
p := d.PeekBytes(4)
// TODO: VP8X
switch {
case bytes.Equal(p, []byte("VP8 ")):
d.FieldStruct("image", func(d *decode.D) {
2020-06-08 03:29:51 +03:00
decodeChunk(d, "VP8", func(d *decode.D) {
d.Format(vp8Frame, nil)
2020-06-08 03:29:51 +03:00
})
})
case bytes.Equal(p, []byte("VP8L")):
d.FieldStruct("image", func(d *decode.D) {
2020-06-08 03:29:51 +03:00
decodeChunk(d, "VP8L", func(d *decode.D) {
// TODO
})
})
default:
d.Fatalf("could not find VP8 or VP8L chunk")
2020-06-08 03:29:51 +03:00
}
})
return nil
}