|
7 | 7 | * Copyright(c) 2020 Google Inc. |
8 | 8 | */ |
9 | 9 |
|
10 | | -// A selection from https://en.wikipedia.org/wiki/List_of_file_signatures. |
| 10 | +// There are basically two major "container" families for modern audio-visual formats: |
| 11 | +// 1) the ISO-BMFF family (MP4, HEVC, AVIF, etc) |
| 12 | +// 2) the Matroska family (MKV, WebM, WebP) |
| 13 | + |
| 14 | +// The ISO-BMFF container needs special processing because of its "compatible brands" array :( |
| 15 | +// The Matroska container needs special processing because the sub-type can appear anywhere :( |
| 16 | + |
| 17 | +// NOTE: Because the ICO format also starts with a couple zero bytes, this tree will rely on the |
| 18 | +// File Type box never going beyond 255 bytes in length which, seems unlikely according to |
| 19 | +// https://dev.to/alfg/a-quick-dive-into-mp4-57fo. |
| 20 | +// 'ISO-BMFF': [[0x00, 0x00, 0x00, '??', 0x66, 0x74, 0x79, 0x70]], // box_length, then 'ftyp' |
| 21 | +// 'MATROSKA': [[0x1A, 0x45, 0xDF, 0xA3]] |
| 22 | + |
| 23 | +// A subset of "modern" formats from https://en.wikipedia.org/wiki/List_of_file_signatures. |
11 | 24 | // Mapping of MIME type to magic numbers. Each file type can have multiple signatures. |
12 | 25 | // '??' is used as a placeholder value. |
13 | 26 | const fileSignatures = { |
14 | 27 | // Document formats. |
15 | | - 'application/pdf': [[0x25, 0x50, 0x44, 0x46, 0x2d]], |
| 28 | + 'application/pdf': [[0x25, 0x50, 0x44, 0x46, 0x2d]], // '%PDF-' |
16 | 29 |
|
17 | 30 | // Archive formats: |
18 | | - 'application/x-tar': [ |
| 31 | + 'application/x-tar': [ // 'ustar' |
19 | 32 | [0x75, 0x73, 0x74, 0x61, 0x72, 0x00, 0x30, 0x30], |
20 | 33 | [0x75, 0x73, 0x74, 0x61, 0x72, 0x20, 0x20, 0x00], |
21 | 34 | ], |
22 | | - 'application/x-7z-compressed': [[0x37, 0x7A, 0xBC, 0xAF, 0x27, 0x1C]], |
23 | | - 'application/x-bzip2': [[0x42, 0x5A, 0x68]], |
24 | | - 'application/x-rar-compressed': [[0x52, 0x61, 0x72, 0x21, 0x1A, 0x07]], |
25 | | - 'application/zip': [[0x50, 0x4B, 0x03, 0x04], [0x50, 0x4B, 0x05, 0x06], [0x50, 0x4B, 0x07, 0x08]], |
| 35 | + 'application/x-7z-compressed': [[0x37, 0x7A, 0xBC, 0xAF, 0x27, 0x1C]], // '7z' |
| 36 | + 'application/x-bzip2': [[0x42, 0x5A, 0x68]], // 'BZh' |
| 37 | + 'application/x-rar-compressed': [[0x52, 0x61, 0x72, 0x21, 0x1A, 0x07]], // 'Rar!' |
| 38 | + 'application/zip': [ // 'PK' |
| 39 | + [0x50, 0x4B, 0x03, 0x04], |
| 40 | + [0x50, 0x4B, 0x05, 0x06], |
| 41 | + [0x50, 0x4B, 0x07, 0x08], |
| 42 | + ], |
26 | 43 |
|
27 | 44 | // Image formats. |
28 | | - 'image/bmp': [[0x42, 0x4D]], |
29 | | - 'image/gif': [[0x47, 0x49, 0x46, 0x38]], |
| 45 | + 'image/bmp': [[0x42, 0x4D]], // 'BM' |
| 46 | + 'image/gif': [[0x47, 0x49, 0x46, 0x38]], // 'GIF8' |
30 | 47 | 'image/jpeg': [[0xFF, 0xD8, 0xFF]], |
31 | 48 | 'image/png': [[0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A]], |
32 | | - 'image/webp': [[0x52, 0x49, 0x46, 0x46, '??', '??', '??', '??', 0x57, 0x45, 0x42, 0x50]], |
| 49 | + 'image/webp': [[0x52, 0x49, 0x46, 0x46, '??', '??', '??', '??', 0x57, 0x45, 0x42, 0x50]], // 'RIFF....WEBP' |
33 | 50 | 'image/x-icon': [[0x00, 0x00, 0x01, 0x00]], |
34 | 51 |
|
35 | 52 | // Audio/Video formats. |
36 | | - 'application/ogg': [[0x4F, 0x67, 0x67, 0x53]], |
37 | | - 'audio/flac': [[0x66, 0x4C, 0x61, 0x43]], |
38 | | - 'audio/mpeg': [[0xFF, 0xFB], [0xFF, 0xF3], [0xFF, 0xF2], [0x49, 0x44, 0x33]], |
| 53 | + 'application/ogg': [[0x4F, 0x67, 0x67, 0x53]], // 'OggS' |
| 54 | + 'audio/flac': [[0x66, 0x4C, 0x61, 0x43]], // 'fLaC' |
| 55 | + 'audio/mpeg': [ |
| 56 | + [0xFF, 0xFB], |
| 57 | + [0xFF, 0xF3], |
| 58 | + [0xFF, 0xF2], |
| 59 | + [0x49, 0x44, 0x33], // 'ID3' |
| 60 | + ], |
39 | 61 | }; |
40 | 62 |
|
41 | 63 | // TODO: Eventually add support for various container formats so that: |
|
0 commit comments