Added Sum support for FLAC
This commit is contained in:
parent
549eab9b75
commit
554fadb2b4
55
sum.go
55
sum.go
@ -3,6 +3,7 @@ package tag
|
||||
import (
|
||||
"crypto/sha1"
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"fmt"
|
||||
"hash"
|
||||
"io"
|
||||
@ -22,6 +23,10 @@ func Sum(r io.ReadSeeker) (string, error) {
|
||||
return "", fmt.Errorf("could not seek back to original position: %v", err)
|
||||
}
|
||||
|
||||
if string(b[0:4]) == "fLaC" {
|
||||
return SumFLAC(r)
|
||||
}
|
||||
|
||||
if string(b[4:11]) == "ftypM4A" {
|
||||
return SumAtoms(r)
|
||||
}
|
||||
@ -161,6 +166,56 @@ func SumID3v2(r io.ReadSeeker) (string, error) {
|
||||
return hashSum(h), nil
|
||||
}
|
||||
|
||||
// SumFLAC costructs a checksum of the FLAC audio file data provided by the io.ReadSeeker (ignores
|
||||
// metadata fields).
|
||||
func SumFLAC(r io.ReadSeeker) (string, error) {
|
||||
flac, err := readString(r, 4)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if flac != "fLaC" {
|
||||
return "", errors.New("expected 'fLaC'")
|
||||
}
|
||||
|
||||
for {
|
||||
last, err := skipFLACMetadataBlock(r)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if last {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
h := sha1.New()
|
||||
_, err = io.Copy(h, r)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("error reading data bytes from FLAC: %v", err)
|
||||
}
|
||||
return hashSum(h), nil
|
||||
}
|
||||
|
||||
func skipFLACMetadataBlock(r io.ReadSeeker) (last bool, err error) {
|
||||
blockHeader, err := readBytes(r, 1)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if getBit(blockHeader[0], 7) {
|
||||
blockHeader[0] ^= (1 << 7)
|
||||
last = true
|
||||
}
|
||||
|
||||
blockLen, err := readInt(r, 3)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
_, err = r.Seek(int64(blockLen), os.SEEK_CUR)
|
||||
return
|
||||
}
|
||||
|
||||
func hashSum(h hash.Hash) string {
|
||||
return fmt.Sprintf("%x", h.Sum([]byte{}))
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user