Tag Parser  7.0.1
C++ library for reading and writing MP4 (iTunes), ID3, Vorbis, Opus, FLAC and Matroska tags
signature.cpp
Go to the documentation of this file.
1 #include "./signature.h"
3 
4 #include <c++utilities/conversion/binaryconversion.h>
5 
6 using namespace ConversionUtilities;
7 
8 namespace TagParser {
9 
13 enum Sig64 : uint64 {
14  Ar = 0x213C617263683E0A,
15  Asf1 = 0x3026B2758E66CF11ul,
16  Asf2 = 0xA6D900AA0062CE6Cul,
17  Png = 0x89504E470D0A1A0Aul,
18  RiffAvi = 0x415649204C495354ul,
19  YUV4Mpeg2 = 0x595556344D504547ul,
20 };
21 
25 enum Sig56 : uint64 {
26  Rar = 0x526172211A0700ul,
27 };
28 
32 enum Sig48 : uint64 {
33  Gif87a = 0x474946383761ul,
34  Gif89a = 0x474946383961ul,
35  SevenZ = 0x377ABCAF271Cul,
36  Xz = 0xFD377A585A00ul,
37 };
38 
42 enum Sig32 : uint32 {
43  Dirac = 0x42424344u,
44  Elf = 0x7F454C46u,
45  Flac = 0x664C6143u,
46  JavaClassFile = 0xCAFEBABEu,
47  Ebml = 0x1A45DFA3u,
48  MonkeysAudio = 0x4D414320u,
49  Mp4 = 0x66747970u,
50  Ogg = 0x4F676753u,
51  PhotoshopDocument = 0x38425053u,
52  QuickTime = 0x6D6F6F76u,
53  Riff = 0x52494646u,
54  RiffWave = 0x57415645u,
55  TiffBigEndian = 0x4D4D002Au,
56  TiffLittleEndian = 0x49492A00u,
57  Utf32Text = 0xFFFE0000u,
58  WavPack = 0x7776706Bu,
59  WindowsIcon = 0x00000100u,
60  Lzip = 0x4C5A4950u,
61  Zip1 = 0x504B0304u,
62  Zip2 = 0x504B0506u,
63  Zip3 = 0x504B0708u,
64 };
65 
69 enum Sig24 : uint32 {
70  Bzip2 = 0x425A68u,
71  Flv = 0x464C56u,
72  Gzip = 0x1F8B08u,
73  Id3v2 = 0x494433u,
74  Utf8Text = 0xEFBBBFu,
75 };
76 
80 enum Sig16 : uint16 {
81  Ac3 = 0x0B77u,
82  Adts = 0xFFF0u,
83  AdtsMask = 0xFFF6u,
84  Jpeg = 0xffd8u,
85  Lha = 0x1FA0u,
86  Lzw = 0x1F9Du,
87  MpegAudioFrames = 0x7FFu,
88  PortableExecutable = 0x4D5Au,
89  Utf16Text = 0xFFFEu,
90  WindowsBitmap = 0x424du,
91 };
92 
100 ContainerFormat parseSignature(const char *buffer, int bufferSize)
101 {
102  // read signature
103  uint64 sig = 0;
104  if (bufferSize >= 8) {
105  sig = ConversionUtilities::BE::toUInt64(buffer);
106  } else if (bufferSize >= 4) {
107  sig = ConversionUtilities::BE::toUInt32(buffer);
108  sig <<= 4;
109  } else if (bufferSize >= 2) {
110  sig = ConversionUtilities::BE::toUInt16(buffer);
111  sig <<= 6;
112  } else {
113  return ContainerFormat::Unknown;
114  }
115  // return corresponding container format
116  switch (sig) { // check 64-bit signatures
117  case Ar:
118  return ContainerFormat::Ar;
119  case Asf1:
120  return ContainerFormat::Asf;
121  case Asf2:
122  return ContainerFormat::Asf;
123  case Png:
124  return ContainerFormat::Png;
125  case YUV4Mpeg2:
126  if (bufferSize >= 10 && buffer[8] == 0x32 && buffer[9] == 0x20) {
128  }
129  break;
130  default:;
131  }
132  switch (sig & 0x00000000FFFFFFFF) { // check 32-bit signatures @ bit 31
133  case Mp4:
134  return ContainerFormat::Mp4;
135  case QuickTime:
137  default:;
138  }
139  switch (sig >> 8) { // check 56-bit signatures
140  case Rar:
141  return ContainerFormat::Rar;
142  default:;
143  }
144  switch (sig >> 16) { // check 48-bit signatures
145  case Gif87a:
147  case Gif89a:
149  case SevenZ:
151  case Xz:
152  return ContainerFormat::Xz;
153  default:;
154  }
155  switch (sig >> 32) { // check 32-bit signatures
156  case Dirac:
157  return ContainerFormat::Dirac;
158  case Elf:
159  return ContainerFormat::Elf;
160  case Flac:
161  return ContainerFormat::Flac;
162  case JavaClassFile:
164  case Ebml:
165  return ContainerFormat::Ebml;
166  case MonkeysAudio:
168  case Ogg:
169  return ContainerFormat::Ogg;
170  case PhotoshopDocument:
172  case Riff:
173  if (bufferSize >= 16 && ConversionUtilities::BE::toUInt64(buffer + 8) == Sig64::RiffAvi) {
175  } else if (bufferSize >= 12 && ConversionUtilities::BE::toUInt32(buffer + 8) == RiffWave) {
177  } else {
178  return ContainerFormat::Riff;
179  }
180  case TiffBigEndian:
182  case TiffLittleEndian:
184  case Utf32Text:
186  case WavPack:
188  case WindowsIcon:
190  case Lzip:
191  return ContainerFormat::Lzip;
192  case Zip1:
193  case Zip2:
194  case Zip3:
195  return ContainerFormat::Zip;
196  default:;
197  }
198  switch (sig >> 40) { // check 24-bit signatures
199  case Bzip2:
200  return ContainerFormat::Bzip2;
201  case Flv:
202  return ContainerFormat::FlashVideo;
203  case Gzip:
204  return ContainerFormat::Gzip;
205  case Id3v2:
206  return ContainerFormat::Id2v2Tag;
207  case Utf8Text:
209  }
210  switch (sig >> 48) { // check 16-bit signatures
211  case Ac3:
212  return ContainerFormat::Ac3Frames;
213  case Jpeg:
214  return ContainerFormat::Jpeg;
215  case Lha:
216  return ContainerFormat::Lha;
217  case Lzw:
218  return ContainerFormat::Lzw;
219  case PortableExecutable:
221  case Utf16Text:
223  case WindowsBitmap:
225  default:;
226  }
227  // check other signatures
228  if (((sig >> 48) & AdtsMask) == Adts) {
229  return ContainerFormat::Adts;
230  }
231  if ((sig >> 53) == MpegAudioFrames) {
233  }
234  return ContainerFormat::Unknown;
235 }
236 
243 const char *containerFormatAbbreviation(ContainerFormat containerFormat, MediaType mediaType, unsigned int version)
244 {
245  switch (containerFormat) {
246  case ContainerFormat::Ac3Frames:
247  return "ac3";
248  case ContainerFormat::Ar:
249  return "a";
250  case ContainerFormat::Asf:
251  return "asf";
253  return "drc";
255  return "elf";
257  return "flac";
258  case ContainerFormat::FlashVideo:
259  return "flv";
262  return "gif";
264  return "class";
266  return "jpeg";
268  return "lzh";
270  return "lzw";
272  switch (mediaType) {
273  case MediaType::Audio:
274  return "m4a";
275  default:
276  return "mp4";
277  }
279  switch (mediaType) {
280  case MediaType::Video:
281  return "ogv";
282  default:
283  switch (version) {
284  case static_cast<unsigned int>(GeneralMediaFormat::Opus):
285  return "opus";
286  case static_cast<unsigned int>(GeneralMediaFormat::Speex):
287  return "spx";
288  default:
289  return "ogg";
290  }
291  }
293  return "psd";
295  return "png";
297  return "exe";
299  return "rar";
300  case ContainerFormat::Matroska:
301  switch (mediaType) {
302  case MediaType::Audio:
303  return "mka";
304  default:
305  return "mkv";
306  }
308  switch (version) {
309  case 1:
310  return "mp1";
311  case 2:
312  return "mp2";
313  default:
314  return "mp3";
315  }
317  return "riff";
319  return "wav";
321  return "avi";
322  case ContainerFormat::Tar:
323  return "tar";
326  return "tiff";
328  return "bmp";
330  return "ico";
332  return "bz";
334  return "gz";
336  return "lz";
338  return "mov";
339  case ContainerFormat::Zip:
340  return "zip";
342  return "7z";
343  case ContainerFormat::Xz:
344  return "xz";
346  return "y4m";
348  return "wv";
350  return "ape";
351  default:
352  return "";
353  }
354 }
355 
361 const char *containerFormatName(ContainerFormat containerFormat)
362 {
363  switch (containerFormat) {
364  case ContainerFormat::Ac3Frames:
365  return "raw Dolby Digital";
367  return "Audio Data Transport Stream";
368  case ContainerFormat::Ar:
369  return "Archive (GNU ar)";
370  case ContainerFormat::Asf:
371  return "Advanced Systems Format";
373  return "raw Dirac";
375  return "Executable and Linkable Format";
377  return "raw Free Lossless Audio Codec frames";
378  case ContainerFormat::FlashVideo:
379  return "Flash Video";
382  return "Graphics Interchange Format";
384  return "Java class file";
386  return "JPEG File Interchange Format";
388  return "LHA compressed file";
390  return "LZW compressed file";
392  return "MPEG-4 Part 14";
394  return "Ogg transport bitstream";
396  return "Photoshop document";
398  return "Portable Network Graphics";
400  return "Portable Executable";
402  return "RAR Archive";
404  return "EBML";
405  case ContainerFormat::Matroska:
406  return "Matroska";
407  case ContainerFormat::Webm:
408  return "WebM";
410  return "MPEG-1 Layer 1/2/3 frames";
412  return "Resource Interchange File Format";
414  return "RIFF/WAVE";
416  return "RIFF/Audio Video Interleave";
417  case ContainerFormat::Tar:
418  return "TAR archive";
421  return "Tagged Image File Format";
423  return "UTF-16 text";
425  return "UTF-32 text";
427  return "UTF-8 text";
429  return "WavPack";
431  return "Microsoft Windows Bitmap";
433  return "Microsoft Windows Icon";
435  return "bzip2 compressed file";
437  return "gzip compressed file";
439  return "lzip compressed file";
441  return "7z archive";
443  return "Quick Time";
444  case ContainerFormat::Xz:
445  return "xz compressed file";
447  return "YUV4MPEG2";
448  case ContainerFormat::Zip:
449  return "ZIP archive";
451  return "Monkey's Audio";
452  default:
453  return "unknown";
454  }
455 }
456 
462 const char *containerFormatSubversion(ContainerFormat containerFormat)
463 {
464  switch (containerFormat) {
466  return "87a";
468  return "89a";
470  return "big endian";
472  return "little endian";
473  default:
474  return "";
475  }
476 }
477 
483 const char *containerMimeType(ContainerFormat containerFormat, MediaType mediaType)
484 {
485  switch (containerFormat) {
486  case ContainerFormat::Ac3Frames:
487  return "audio/ac3";
488  case ContainerFormat::Asf:
489  return "video/x-ms-asf";
491  return "audio/flac";
492  case ContainerFormat::FlashVideo:
493  return "video/x-flv";
496  return "image/gif";
498  return "image/jpeg";
500  return "image/png";
502  return "audio/mpeg";
504  switch (mediaType) {
505  case MediaType::Audio:
506  return "audio/mp4";
507  default:
508  return "video/mp4";
509  }
511  switch (mediaType) {
512  case MediaType::Audio:
513  return "audio/ogg";
514  default:
515  return "video/ogg";
516  }
517  case ContainerFormat::Matroska:
518  switch (mediaType) {
519  case MediaType::Audio:
520  return "audio/x-matroska";
521  default:
522  return "video/x-matroska";
523  }
525  return "application/x-bzip";
527  return "application/gzip";
529  return "application/x-lzh-compressed";
531  return "application/x-rar-compressed";
533  return "application/x-lzip";
535  return "video/quicktime";
536  case ContainerFormat::Zip:
537  return "application/zip";
539  return "application/x-7z-compressed";
540  case ContainerFormat::Xz:
541  return "application/x-xz";
543  return "image/bmp";
545  return "image/vnd.microsoft.icon";
546  default:
547  return "";
548  }
549 }
550 
554 TagTargetLevel containerTargetLevel(ContainerFormat containerFormat, uint64 targetLevelValue)
555 {
556  switch (containerFormat) {
557  case ContainerFormat::Matroska:
558  case ContainerFormat::Webm:
559  return matroskaTagTargetLevel(targetLevelValue);
560  default:
561  return TagTargetLevel::Unspecified;
562  }
563 }
564 
568 uint64 containerTargetLevelValue(ContainerFormat containerFormat, TagTargetLevel targetLevel)
569 {
570  switch (containerFormat) {
571  case ContainerFormat::Matroska:
572  case ContainerFormat::Webm:
573  return matroskaTagTargetLevelValue(targetLevel);
574  default:
575  return 0;
576  }
577 }
578 
579 } // namespace TagParser
TAG_PARSER_EXPORT uint64 containerTargetLevelValue(ContainerFormat containerFormat, TagTargetLevel targetLevel)
Returns the raw target level value for the specified containerFormat and general targetLevel.
Definition: signature.cpp:568
TagTargetLevel
The TagTargetLevel enum specifies tag target levels.
Definition: tagtarget.h:17
Sig56
Holds 52-bit signatures.
Definition: signature.cpp:25
TAG_PARSER_EXPORT TagTargetLevel containerTargetLevel(ContainerFormat containerFormat, uint64 targetLevelValue)
Returns the general TagTargetLevel for the specified container format and raw targetLevelValue.
Definition: signature.cpp:554
TAG_PARSER_EXPORT const char * version()
MediaType
The MediaType enum specifies the type of media data (audio, video, text, ...).
Definition: mediaformat.h:13
TAG_PARSER_EXPORT const char * containerMimeType(ContainerFormat containerFormat, MediaType mediaType=MediaType::Unknown)
Returns the MIME-type of the container format as C-style string.
Definition: signature.cpp:483
Sig32
Holds 32-bit signatures.
Definition: signature.cpp:42
Sig48
Holds 48-bit signatures.
Definition: signature.cpp:32
TAG_PARSER_EXPORT uint64 matroskaTagTargetLevelValue(TagTargetLevel targetLevel)
Returns the Matroska specific target level value for the specified general targetLevel.
Sig16
Holds 16-bit signatures.
Definition: signature.cpp:80
ContainerFormat
Specifies the container format.
Definition: signature.h:17
TAG_PARSER_EXPORT const char * containerFormatName(ContainerFormat containerFormat)
Returns the name of the specified container format as C-style string.
Definition: signature.cpp:361
Sig24
Holds 24-bit signatures.
Definition: signature.cpp:69
TAG_PARSER_EXPORT TagTargetLevel matroskaTagTargetLevel(uint64 targetLevelValue)
Returns the general TagTargetLevel for the Matroska specific targetLevelValue.
Sig64
Holds 64-bit signatures.
Definition: signature.cpp:13
TAG_PARSER_EXPORT const char * containerFormatAbbreviation(ContainerFormat containerFormat, MediaType mediaType=MediaType::Unknown, unsigned int version=0)
Returns the abbreviation of the container format as C-style string considering the specified media ty...
Definition: signature.cpp:243
TAG_PARSER_EXPORT ContainerFormat parseSignature(const char *buffer, int bufferSize)
Parses the signature read from the specified buffer.
Definition: signature.cpp:100
TAG_PARSER_EXPORT const char * containerFormatSubversion(ContainerFormat containerFormat)
Returns the subversion of the container format as C-style string.
Definition: signature.cpp:462