mirror of
				https://github.com/superseriousbusiness/gotosocial.git
				synced 2025-10-29 19:52:24 -05:00 
			
		
		
		
	Bumps [github.com/abema/go-mp4](https://github.com/abema/go-mp4) from 0.10.0 to 0.10.1. - [Release notes](https://github.com/abema/go-mp4/releases) - [Commits](https://github.com/abema/go-mp4/compare/v0.10.0...v0.10.1) --- updated-dependencies: - dependency-name: github.com/abema/go-mp4 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
		
			
				
	
	
		
			182 lines
		
	
	
	
		
			4.5 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			182 lines
		
	
	
	
		
			4.5 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package mp4
 | |
| 
 | |
| import (
 | |
| 	"errors"
 | |
| 	"fmt"
 | |
| 	"io"
 | |
| )
 | |
| 
 | |
| type BoxPath []BoxType
 | |
| 
 | |
| func (lhs BoxPath) compareWith(rhs BoxPath) (forwardMatch bool, match bool) {
 | |
| 	if len(lhs) > len(rhs) {
 | |
| 		return false, false
 | |
| 	}
 | |
| 	for i := 0; i < len(lhs); i++ {
 | |
| 		if !lhs[i].MatchWith(rhs[i]) {
 | |
| 			return false, false
 | |
| 		}
 | |
| 	}
 | |
| 	if len(lhs) < len(rhs) {
 | |
| 		return true, false
 | |
| 	}
 | |
| 	return false, true
 | |
| }
 | |
| 
 | |
| type ReadHandle struct {
 | |
| 	Params      []interface{}
 | |
| 	BoxInfo     BoxInfo
 | |
| 	Path        BoxPath
 | |
| 	ReadPayload func() (box IBox, n uint64, err error)
 | |
| 	ReadData    func(io.Writer) (n uint64, err error)
 | |
| 	Expand      func(params ...interface{}) (vals []interface{}, err error)
 | |
| }
 | |
| 
 | |
| type ReadHandler func(handle *ReadHandle) (val interface{}, err error)
 | |
| 
 | |
| func ReadBoxStructure(r io.ReadSeeker, handler ReadHandler, params ...interface{}) ([]interface{}, error) {
 | |
| 	if _, err := r.Seek(0, io.SeekStart); err != nil {
 | |
| 		return nil, err
 | |
| 	}
 | |
| 	return readBoxStructure(r, 0, true, nil, Context{}, handler, params)
 | |
| }
 | |
| 
 | |
| func ReadBoxStructureFromInternal(r io.ReadSeeker, bi *BoxInfo, handler ReadHandler, params ...interface{}) (interface{}, error) {
 | |
| 	return readBoxStructureFromInternal(r, bi, nil, handler, params)
 | |
| }
 | |
| 
 | |
| func readBoxStructureFromInternal(r io.ReadSeeker, bi *BoxInfo, path BoxPath, handler ReadHandler, params []interface{}) (interface{}, error) {
 | |
| 	if _, err := bi.SeekToPayload(r); err != nil {
 | |
| 		return nil, err
 | |
| 	}
 | |
| 
 | |
| 	// check comatible-brands
 | |
| 	if len(path) == 0 && bi.Type == BoxTypeFtyp() {
 | |
| 		var ftyp Ftyp
 | |
| 		if _, err := Unmarshal(r, bi.Size-bi.HeaderSize, &ftyp, bi.Context); err != nil {
 | |
| 			return nil, err
 | |
| 		}
 | |
| 		if ftyp.HasCompatibleBrand(BrandQT()) {
 | |
| 			bi.IsQuickTimeCompatible = true
 | |
| 		}
 | |
| 		if _, err := bi.SeekToPayload(r); err != nil {
 | |
| 			return nil, err
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	ctx := bi.Context
 | |
| 	if bi.Type == BoxTypeWave() {
 | |
| 		ctx.UnderWave = true
 | |
| 	} else if bi.Type == BoxTypeIlst() {
 | |
| 		ctx.UnderIlst = true
 | |
| 	} else if bi.UnderIlst && !bi.UnderIlstMeta && IsIlstMetaBoxType(bi.Type) {
 | |
| 		ctx.UnderIlstMeta = true
 | |
| 		if bi.Type == StrToBoxType("----") {
 | |
| 			ctx.UnderIlstFreeMeta = true
 | |
| 		}
 | |
| 	} else if bi.Type == BoxTypeUdta() {
 | |
| 		ctx.UnderUdta = true
 | |
| 	}
 | |
| 
 | |
| 	newPath := make(BoxPath, len(path)+1)
 | |
| 	copy(newPath, path)
 | |
| 	newPath[len(path)] = bi.Type
 | |
| 
 | |
| 	h := &ReadHandle{
 | |
| 		Params:  params,
 | |
| 		BoxInfo: *bi,
 | |
| 		Path:    newPath,
 | |
| 	}
 | |
| 
 | |
| 	var childrenOffset uint64
 | |
| 
 | |
| 	h.ReadPayload = func() (IBox, uint64, error) {
 | |
| 		if _, err := bi.SeekToPayload(r); err != nil {
 | |
| 			return nil, 0, err
 | |
| 		}
 | |
| 
 | |
| 		box, n, err := UnmarshalAny(r, bi.Type, bi.Size-bi.HeaderSize, bi.Context)
 | |
| 		if err != nil {
 | |
| 			return nil, 0, err
 | |
| 		}
 | |
| 		childrenOffset = bi.Offset + bi.HeaderSize + n
 | |
| 		return box, n, nil
 | |
| 	}
 | |
| 
 | |
| 	h.ReadData = func(w io.Writer) (uint64, error) {
 | |
| 		if _, err := bi.SeekToPayload(r); err != nil {
 | |
| 			return 0, err
 | |
| 		}
 | |
| 
 | |
| 		size := bi.Size - bi.HeaderSize
 | |
| 		if _, err := io.CopyN(w, r, int64(size)); err != nil {
 | |
| 			return 0, err
 | |
| 		}
 | |
| 		return size, nil
 | |
| 	}
 | |
| 
 | |
| 	h.Expand = func(params ...interface{}) ([]interface{}, error) {
 | |
| 		if childrenOffset == 0 {
 | |
| 			if _, err := bi.SeekToPayload(r); err != nil {
 | |
| 				return nil, err
 | |
| 			}
 | |
| 
 | |
| 			_, n, err := UnmarshalAny(r, bi.Type, bi.Size-bi.HeaderSize, bi.Context)
 | |
| 			if err != nil {
 | |
| 				return nil, err
 | |
| 			}
 | |
| 			childrenOffset = bi.Offset + bi.HeaderSize + n
 | |
| 		} else {
 | |
| 			if _, err := r.Seek(int64(childrenOffset), io.SeekStart); err != nil {
 | |
| 				return nil, err
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		childrenSize := bi.Offset + bi.Size - childrenOffset
 | |
| 		return readBoxStructure(r, childrenSize, false, newPath, ctx, handler, params)
 | |
| 	}
 | |
| 
 | |
| 	if val, err := handler(h); err != nil {
 | |
| 		return nil, err
 | |
| 	} else if _, err := bi.SeekToEnd(r); err != nil {
 | |
| 		return nil, err
 | |
| 	} else {
 | |
| 		return val, nil
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func readBoxStructure(r io.ReadSeeker, totalSize uint64, isRoot bool, path BoxPath, ctx Context, handler ReadHandler, params []interface{}) ([]interface{}, error) {
 | |
| 	vals := make([]interface{}, 0, 8)
 | |
| 
 | |
| 	for isRoot || totalSize >= SmallHeaderSize {
 | |
| 		bi, err := ReadBoxInfo(r)
 | |
| 		if isRoot && err == io.EOF {
 | |
| 			return vals, nil
 | |
| 		} else if err != nil {
 | |
| 			return nil, err
 | |
| 		}
 | |
| 
 | |
| 		if !isRoot && bi.Size > totalSize {
 | |
| 			return nil, fmt.Errorf("too large box size: type=%s, size=%d, actualBufSize=%d", bi.Type.String(), bi.Size, totalSize)
 | |
| 		}
 | |
| 		totalSize -= bi.Size
 | |
| 
 | |
| 		bi.Context = ctx
 | |
| 
 | |
| 		val, err := readBoxStructureFromInternal(r, bi, path, handler, params)
 | |
| 		if err != nil {
 | |
| 			return nil, err
 | |
| 		}
 | |
| 		vals = append(vals, val)
 | |
| 
 | |
| 		if bi.IsQuickTimeCompatible {
 | |
| 			ctx.IsQuickTimeCompatible = true
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	if totalSize != 0 && !ctx.IsQuickTimeCompatible {
 | |
| 		return nil, errors.New("Unexpected EOF")
 | |
| 	}
 | |
| 
 | |
| 	return vals, nil
 | |
| }
 |