// 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 } // BoxTypeFileType File Type Box const BoxTypeFileType = "ftyp" func init() { BoxDefinitions = append(BoxDefinitions, BoxDefinition{ Type: BoxTypeFileType, ParentTypes: []string{boxTypeParentFile}, Parser: ParseFileTypeBox, }) } // ParseFileTypeBox creates new file type box based on bytes func ParseFileTypeBox(parser *Parser, filePosition uint64, headerSize uint32, content []byte) (any, error) { // 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, nil }