Code refactorization
Should even work if the subatoms of "----" are out of order
This commit is contained in:
parent
be3da62488
commit
a931bf6e30
134
mp4.go
134
mp4.go
@ -6,6 +6,7 @@ package tag
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
@ -69,10 +70,62 @@ func ReadAtoms(r io.ReadSeeker) (Metadata, error) {
|
||||
return m, err
|
||||
}
|
||||
|
||||
func readCustomAtom(r io.ReadSeeker, size uint32) (string, uint32, error) {
|
||||
var datasize uint32
|
||||
var datapos int64
|
||||
var name string
|
||||
var mean string
|
||||
|
||||
for size > 8 {
|
||||
var subsize uint32
|
||||
err := binary.Read(r, binary.BigEndian, &subsize)
|
||||
if err != nil {
|
||||
return "----", size - 4, err
|
||||
}
|
||||
subname, err := readString(r, 4)
|
||||
if err != nil {
|
||||
return "----", size - 8, err
|
||||
}
|
||||
b, err := readBytes(r, int(subsize-8))
|
||||
if err != nil {
|
||||
return "----", size - subsize, err
|
||||
}
|
||||
// Remove the size of the mean atom from the size counter
|
||||
size -= subsize
|
||||
|
||||
switch string(subname) {
|
||||
case "mean":
|
||||
mean = string(b[4:])
|
||||
case "name":
|
||||
name = string(b[4:])
|
||||
case "data":
|
||||
datapos, err = r.Seek(0, os.SEEK_CUR)
|
||||
if err != nil {
|
||||
return "----", size, err
|
||||
}
|
||||
datasize = subsize
|
||||
datapos -= int64(subsize)
|
||||
}
|
||||
}
|
||||
// there should remain only the header size
|
||||
if size != 8 {
|
||||
return "----", size, errors.New("---- atom out of bound")
|
||||
}
|
||||
if mean == "com.apple.iTunes" && datasize != 0 && name != "" {
|
||||
// we jump just before the data subatom
|
||||
_, err := r.Seek(datapos, os.SEEK_SET)
|
||||
if err != nil {
|
||||
return "----", size, err
|
||||
}
|
||||
return name, datasize + 8, nil
|
||||
}
|
||||
return "----", size, nil
|
||||
}
|
||||
|
||||
func (m metadataMP4) readAtoms(r io.ReadSeeker) error {
|
||||
for {
|
||||
var size uint32
|
||||
var subname string
|
||||
ok := false
|
||||
err := binary.Read(r, binary.BigEndian, &size)
|
||||
if err != nil {
|
||||
if err == io.EOF {
|
||||
@ -109,69 +162,20 @@ func (m metadataMP4) readAtoms(r io.ReadSeeker) error {
|
||||
}
|
||||
continue
|
||||
case "----":
|
||||
/* Generic atom.
|
||||
Should have 3 sub atoms : mean, name and data.
|
||||
We check that mean=="com.apple.iTunes" and we use the subname as
|
||||
the name, and move to the data atom if anything goes wrong, we jump
|
||||
at the end of the "----" atom. */
|
||||
|
||||
// let's read the mean atom
|
||||
var subsize uint32
|
||||
err := binary.Read(r, binary.BigEndian, &subsize)
|
||||
// Generic atom.
|
||||
// Should have 3 sub atoms : mean, name and data.
|
||||
// We check that mean=="com.apple.iTunes" and we use the subname as
|
||||
// the name, and move to the data atom if anything goes wrong,
|
||||
// we jump at the end of the "----" atom.
|
||||
name, size, err = readCustomAtom(r, size)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
sub, err := readString(r, 4)
|
||||
if err != nil {
|
||||
return err
|
||||
if name != "----" {
|
||||
ok = true
|
||||
}
|
||||
|
||||
if sub != "mean" {
|
||||
// Something's wrong. Remove 8 read bytes from the size counter
|
||||
// since "----" is not a known atom name, the whole data will
|
||||
// be skipped
|
||||
size -= 8
|
||||
break
|
||||
}
|
||||
|
||||
mean, err := readBytes(r, int(subsize-8))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Remove the size of the mean atom from the size counter
|
||||
size -= subsize
|
||||
|
||||
if string(mean[4:]) != "com.apple.iTunes" {
|
||||
// Something's wrong, skip this atom
|
||||
break
|
||||
}
|
||||
|
||||
// Let's read the name atom
|
||||
err = binary.Read(r, binary.BigEndian, &subsize)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
sub, err = readString(r, 4)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if sub != "name" {
|
||||
// Something's wrong
|
||||
size -= 8
|
||||
break
|
||||
}
|
||||
|
||||
b, err := readBytes(r, int(subsize-8))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
/* Remove the size of the name atom from the size counter.
|
||||
We should now be at the start of the data subatom and size should
|
||||
be equal to the size of the data atom and its header */
|
||||
size -= subsize
|
||||
|
||||
subname = string(b[4:])
|
||||
default:
|
||||
_, ok = atoms[name]
|
||||
}
|
||||
|
||||
b, err := readBytes(r, int(size-8))
|
||||
@ -179,14 +183,8 @@ func (m metadataMP4) readAtoms(r io.ReadSeeker) error {
|
||||
return err
|
||||
}
|
||||
|
||||
// Allow all known atoms and the valid "----" atoms
|
||||
_, ok := atoms[name]
|
||||
switch {
|
||||
case name == "----" && subname == "":
|
||||
continue
|
||||
case name == "----":
|
||||
name = subname
|
||||
case !ok:
|
||||
// At this point, we allow all known atoms and the valid "----" atoms
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user