package avif
import (
"encoding/binary"
"image"
"io"
)
type fourCC [4]byte
var (
boxTypeFTYP = fourCC{'f', 't', 'y', 'p'}
boxTypeMDAT = fourCC{'m', 'd', 'a', 't'}
boxTypeMETA = fourCC{'m', 'e', 't', 'a'}
boxTypeHDLR = fourCC{'h', 'd', 'l', 'r'}
boxTypePITM = fourCC{'p', 'i', 't', 'm'}
boxTypeILOC = fourCC{'i', 'l', 'o', 'c'}
boxTypeIINF = fourCC{'i', 'i', 'n', 'f'}
boxTypeINFE = fourCC{'i', 'n', 'f', 'e'}
boxTypeIPRP = fourCC{'i', 'p', 'r', 'p'}
boxTypeIPCO = fourCC{'i', 'p', 'c', 'o'}
boxTypeISPE = fourCC{'i', 's', 'p', 'e'}
boxTypePASP = fourCC{'p', 'a', 's', 'p'}
boxTypeAV1C = fourCC{'a', 'v', '1', 'C'}
boxTypePIXI = fourCC{'p', 'i', 'x', 'i'}
boxTypeIPMA = fourCC{'i', 'p', 'm', 'a'}
itemTypeMIF1 = fourCC{'m', 'i', 'f', '1'}
itemTypeAVIF = fourCC{'a', 'v', 'i', 'f'}
itemTypeMIAF = fourCC{'m', 'i', 'a', 'f'}
itemTypePICT = fourCC{'p', 'i', 'c', 't'}
itemTypeMIME = fourCC{'m', 'i', 'm', 'e'}
itemTypeURI = fourCC{'u', 'r', 'i', ' '}
itemTypeAV01 = fourCC{'a', 'v', '0', '1'}
)
func ulen(s string) uint32 {
return uint32(len(s))
}
func bflag(b bool, pos uint8) uint8 {
if b {
return 1 << (pos - 1)
} else {
return 0
}
}
func writeAll(w io.Writer, writers ...io.WriterTo) (err error) {
for _, wt := range writers {
_, err = wt.WriteTo(w)
if err != nil {
return
}
}
return
}
func writeBE(w io.Writer, chunks ...interface{}) (err error) {
for _, v := range chunks {
err = binary.Write(w, binary.BigEndian, v)
if err != nil {
return
}
}
return
}
//----------------------------------------------------------------------
type box struct {
size uint32
typ fourCC
}
func (b *box) Size() uint32 {
return 8
}
func (b *box) WriteTo(w io.Writer) (n int64, err error) {
err = writeBE(w, b.size, b.typ)
return
}
//----------------------------------------------------------------------
type fullBox struct {
box
version uint8
flags uint32
}
func (b *fullBox) Size() uint32 {
return 12
}
func (b *fullBox) WriteTo(w io.Writer) (n int64, err error) {
if _, err = b.box.WriteTo(w); err != nil {
return
}
versionAndFlags := (uint32(b.version) << 24) | (b.flags & 0xffffff)
err = writeBE(w, versionAndFlags)
return
}
//----------------------------------------------------------------------
// File Type Box
type boxFTYP struct {
box
majorBrand fourCC
minorVersion uint32
compatibleBrands []fourCC
}
func (b *boxFTYP) Size() uint32 {
return b.box.Size() +
4 /*major_brand*/ + 4 /*minor_version*/ + uint32(len(b.compatibleBrands))*4
}
func (b *boxFTYP) WriteTo(w io.Writer) (n int64, err error) {
b.size = b.Size()
b.typ = boxTypeFTYP
if _, err = b.box.WriteTo(w); err != nil {
return
}
err = writeBE(w, b.majorBrand, b.minorVersion, b.compatibleBrands)
return
}
//----------------------------------------------------------------------
// Media Data Box
type boxMDAT struct {
box
data []byte
}
func (b *boxMDAT) Size() uint32 {
return b.box.Size() + uint32(len(b.data))
}
func (b *boxMDAT) WriteTo(w io.Writer) (n int64, err error