87 lines
3.9 KiB
Go
87 lines
3.9 KiB
Go
// Copyright 2024 Martin Riedl
|
||
//
|
||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||
// you may not use this file except in compliance with the License.
|
||
// You may obtain a copy of the License at
|
||
//
|
||
// http://www.apache.org/licenses/LICENSE-2.0
|
||
//
|
||
// Unless required by applicable law or agreed to in writing, software
|
||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||
// See the License for the specific language governing permissions and
|
||
// limitations under the License.
|
||
|
||
package gomp4
|
||
|
||
import "encoding/binary"
|
||
|
||
// FileTypeBox file type box struct
|
||
//
|
||
// 4.3 File Type Box
|
||
// Box Type: `ftyp’
|
||
// Container: File
|
||
// Mandatory: Yes
|
||
// Quantity: Exactly one (but see below)
|
||
//
|
||
// Files written to this version of this specification must contain a file‐type box. For compatibility with an
|
||
// earlier version of this specification, files may be conformant to this specification and not contain a file‐
|
||
// type box. Files with no file‐type box should be read as if they contained an FTYP box with
|
||
// Major_brand='mp41', minor_version=0, and the single compatible brand 'mp41'.
|
||
//
|
||
// A media‐file structured to this part of this specification may be compatible with more than one detailed
|
||
// specification, and it is therefore not always possible to speak of a single ‘type’ or ‘brand’ for the file. This
|
||
// means that the utility of the file name extension and Multipurpose Internet Mail Extension (MIME) type
|
||
// are somewhat reduced.
|
||
//
|
||
// This box must be placed as early as possible in the file (e.g. after any obligatory signature, but before
|
||
// any significant variable‐size boxes such as a Movie Box, Media Data Box, or Free Space). It identifies
|
||
// which specification is the ‘best use’ of the file, and a minor version of that specification; and also a set of
|
||
// other specifications to which the file complies. Readers implementing this format should attempt to
|
||
// read files that are marked as compatible with any of the specifications that the reader implements. Any
|
||
// incompatible change in a specification should therefore register a new ‘brand’ identifier to identify files
|
||
// conformant to the new specification.
|
||
//
|
||
// The minor version is informative only. It does not appear for compatible‐brands, and must not be used
|
||
// to determine the conformance of a file to a standard. It may allow more precise identification of the
|
||
// major specification, for inspection, debugging, or improved decoding.
|
||
//
|
||
// Files would normally be externally identified (e.g. with a file extension or mime type) that identifies the
|
||
// ‘best use’ (major brand), or the brand that the author believes will provide the greatest compatibility.
|
||
//
|
||
// This section of this specification does not define any brands. However, see subclause 6.3 below for brands for
|
||
// files conformant to the whole specification and not just this section. All file format brands
|
||
// defined in this specification are included in Annex E with a summary of which features they require.
|
||
type FileTypeBox struct {
|
||
*Box
|
||
// is a brand identifier
|
||
MajorBrand string
|
||
// is an informative integer for the minor version of the major brand
|
||
MinorBrand uint32
|
||
// is a list, to the end of the box, of brands
|
||
CompatibleBrands []string
|
||
}
|
||
|
||
// ParseFileTypeBox creates new file type box based on bytes
|
||
func ParseFileTypeBox(filePosition uint64, headerSize uint32, content []byte) *FileTypeBox {
|
||
// create new box
|
||
box := &FileTypeBox{
|
||
Box: &Box{filePosition, headerSize},
|
||
}
|
||
|
||
// parse major brand
|
||
majorBrandBytes := content[0:4]
|
||
box.MajorBrand = string(majorBrandBytes)
|
||
|
||
// parse minor brand
|
||
box.MinorBrand = binary.BigEndian.Uint32(content[4:8])
|
||
|
||
// parse brands
|
||
for i := 8; i < len(content); i = i + 4 {
|
||
data := content[i : i+4]
|
||
brand := string(data)
|
||
box.CompatibleBrands = append(box.CompatibleBrands, brand)
|
||
}
|
||
|
||
return box
|
||
}
|