Tag Parser  8.0.0
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  Ivf = 0x444B4946u,
47  JavaClassFile = 0xCAFEBABEu,
48  Ebml = 0x1A45DFA3u,
49  Midi = 0x4D546864u,
50  MonkeysAudio = 0x4D414320u,
51  Mp4 = 0x66747970u,
52  Ogg = 0x4F676753u,
53  PhotoshopDocument = 0x38425053u,
54  QuickTime = 0x6D6F6F76u,
55  Riff = 0x52494646u,
56  RiffWave = 0x57415645u,
57  TiffBigEndian = 0x4D4D002Au,
58  TiffLittleEndian = 0x49492A00u,
59  Utf32Text = 0xFFFE0000u,
60  WavPack = 0x7776706Bu,
61  WindowsIcon = 0x00000100u,
62  Lzip = 0x4C5A4950u,
63  Zip1 = 0x504B0304u,
64  Zip2 = 0x504B0506u,
65  Zip3 = 0x504B0708u,
66 };
67 
71 enum Sig24 : uint32 {
72  Bzip2 = 0x425A68u,
73  Flv = 0x464C56u,
74  Gzip = 0x1F8B08u,
75  Id3v2 = 0x494433u,
76  Utf8Text = 0xEFBBBFu,
77 };
78 
82 enum Sig16 : uint16 {
83  Ac3 = 0x0B77u,
84  Adts = 0xFFF0u,
85  AdtsMask = 0xFFF6u,
86  Jpeg = 0xffd8u,
87  Lha = 0x1FA0u,
88  Lzw = 0x1F9Du,
89  MpegAudioFrames = 0x7FFu,
90  PortableExecutable = 0x4D5Au,
91  Utf16Text = 0xFFFEu,
92  WindowsBitmap = 0x424du,
93 };
94 
102 ContainerFormat parseSignature(const char *buffer, int bufferSize)
103 {
104  // read signature
105  uint64 sig = 0;
106  if (bufferSize >= 8) {
107  sig = ConversionUtilities::BE::toUInt64(buffer);
108  } else if (bufferSize >= 4) {
109  sig = ConversionUtilities::BE::toUInt32(buffer);
110  sig <<= 4;
111  } else if (bufferSize >= 2) {
112  sig = ConversionUtilities::BE::toUInt16(buffer);
113  sig <<= 6;
114  } else {
115  return ContainerFormat::Unknown;
116  }
117  // return corresponding container format
118  switch (sig) { // check 64-bit signatures
119  case Ar:
120  return ContainerFormat::Ar;
121  case Asf1:
122  return ContainerFormat::Asf;
123  case Asf2:
124  return ContainerFormat::Asf;
125  case Png:
126  return ContainerFormat::Png;
127  case YUV4Mpeg2:
128  if (bufferSize >= 10 && buffer[8] == 0x32 && buffer[9] == 0x20) {
130  }
131  break;
132  default:;
133  }
134  switch (sig & 0x00000000FFFFFFFF) { // check 32-bit signatures @ bit 31
135  case Mp4:
136  return ContainerFormat::Mp4;
137  case QuickTime:
139  default:;
140  }
141  switch (sig >> 8) { // check 56-bit signatures
142  case Rar:
143  return ContainerFormat::Rar;
144  default:;
145  }
146  switch (sig >> 16) { // check 48-bit signatures
147  case Gif87a:
149  case Gif89a:
151  case SevenZ:
153  case Xz:
154  return ContainerFormat::Xz;
155  default:;
156  }
157  switch (sig >> 32) { // check 32-bit signatures
158  case Dirac:
159  return ContainerFormat::Dirac;
160  case Elf:
161  return ContainerFormat::Elf;
162  case Flac:
163  return ContainerFormat::Flac;
164  case Ivf:
165  return ContainerFormat::Ivf;
166  case JavaClassFile:
168  case Ebml:
169  return ContainerFormat::Ebml;
170  case Midi:
171  return ContainerFormat::Midi;
172  case MonkeysAudio:
174  case Ogg:
175  return ContainerFormat::Ogg;
176  case PhotoshopDocument:
178  case Riff:
179  if (bufferSize >= 16 && ConversionUtilities::BE::toUInt64(buffer + 8) == Sig64::RiffAvi) {
181  } else if (bufferSize >= 12 && ConversionUtilities::BE::toUInt32(buffer + 8) == RiffWave) {
183  } else {
184  return ContainerFormat::Riff;
185  }
186  case TiffBigEndian:
188  case TiffLittleEndian:
190  case Utf32Text:
192  case WavPack:
194  case WindowsIcon:
196  case Lzip:
197  return ContainerFormat::Lzip;
198  case Zip1:
199  case Zip2:
200  case Zip3:
201  return ContainerFormat::Zip;
202  default:;
203  }
204  switch (sig >> 40) { // check 24-bit signatures
205  case Bzip2:
206  return ContainerFormat::Bzip2;
207  case Flv:
208  return ContainerFormat::FlashVideo;
209  case Gzip:
210  return ContainerFormat::Gzip;
211  case Id3v2:
212  return ContainerFormat::Id2v2Tag;
213  case Utf8Text:
215  }
216  switch (sig >> 48) { // check 16-bit signatures
217  case Ac3:
218  return ContainerFormat::Ac3Frames;
219  case Jpeg:
220  return ContainerFormat::Jpeg;
221  case Lha:
222  return ContainerFormat::Lha;
223  case Lzw:
224  return ContainerFormat::Lzw;
225  case PortableExecutable:
227  case Utf16Text:
229  case WindowsBitmap:
231  default:;
232  }
233  // check other signatures
234  if (((sig >> 48) & AdtsMask) == Adts) {
235  return ContainerFormat::Adts;
236  }
237  if ((sig >> 53) == MpegAudioFrames) {
239  }
240  return ContainerFormat::Unknown;
241 }
242 
249 const char *containerFormatAbbreviation(ContainerFormat containerFormat, MediaType mediaType, unsigned int version)
250 {
251  switch (containerFormat) {
252  case ContainerFormat::Ac3Frames:
253  return "ac3";
254  case ContainerFormat::Ar:
255  return "a";
256  case ContainerFormat::Asf:
257  return "asf";
259  return "drc";
261  return "elf";
263  return "flac";
264  case ContainerFormat::FlashVideo:
265  return "flv";
268  return "gif";
270  return "ivf";
272  return "class";
274  return "jpeg";
276  return "lzh";
278  return "lzw";
280  switch (mediaType) {
281  case MediaType::Audio:
282  return "m4a";
283  default:
284  return "mp4";
285  }
287  switch (mediaType) {
288  case MediaType::Video:
289  return "ogv";
290  default:
291  switch (version) {
292  case static_cast<unsigned int>(GeneralMediaFormat::Opus):
293  return "opus";
294  case static_cast<unsigned int>(GeneralMediaFormat::Speex):
295  return "spx";
296  default:
297  return "ogg";
298  }
299  }
301  return "psd";
303  return "png";
305  return "exe";
307  return "rar";
308  case ContainerFormat::Matroska:
309  switch (mediaType) {
310  case MediaType::Audio:
311  return "mka";
312  default:
313  return "mkv";
314  }
316  switch (version) {
317  case 1:
318  return "mp1";
319  case 2:
320  return "mp2";
321  default:
322  return "mp3";
323  }
325  return "riff";
327  return "wav";
329  return "avi";
330  case ContainerFormat::Tar:
331  return "tar";
334  return "tiff";
336  return "bmp";
338  return "ico";
340  return "bz";
342  return "gz";
344  return "lz";
346  return "mov";
347  case ContainerFormat::Zip:
348  return "zip";
350  return "7z";
351  case ContainerFormat::Xz:
352  return "xz";
354  return "y4m";
356  return "wv";
358  return "ape";
360  return "mid";
361  default:
362  return "";
363  }
364 }
365 
371 const char *containerFormatName(ContainerFormat containerFormat)
372 {
373  switch (containerFormat) {
374  case ContainerFormat::Ac3Frames:
375  return "raw Dolby Digital";
377  return "Audio Data Transport Stream";
378  case ContainerFormat::Ar:
379  return "Archive (GNU ar)";
380  case ContainerFormat::Asf:
381  return "Advanced Systems Format";
383  return "raw Dirac";
385  return "Executable and Linkable Format";
387  return "raw Free Lossless Audio Codec frames";
388  case ContainerFormat::FlashVideo:
389  return "Flash Video";
392  return "Graphics Interchange Format";
394  return "IVF";
396  return "Java class file";
398  return "JPEG File Interchange Format";
400  return "LHA compressed file";
402  return "LZW compressed file";
404  return "MPEG-4 Part 14";
406  return "Ogg transport bitstream";
408  return "Photoshop document";
410  return "Portable Network Graphics";
412  return "Portable Executable";
414  return "RAR Archive";
416  return "EBML";
417  case ContainerFormat::Matroska:
418  return "Matroska";
419  case ContainerFormat::Webm:
420  return "WebM";
422  return "MPEG-1 Layer 1/2/3 frames";
424  return "Resource Interchange File Format";
426  return "RIFF/WAVE";
428  return "RIFF/Audio Video Interleave";
429  case ContainerFormat::Tar:
430  return "TAR archive";
433  return "Tagged Image File Format";
435  return "UTF-16 text";
437  return "UTF-32 text";
439  return "UTF-8 text";
441  return "WavPack";
443  return "Microsoft Windows Bitmap";
445  return "Microsoft Windows Icon";
447  return "bzip2 compressed file";
449  return "gzip compressed file";
451  return "lzip compressed file";
453  return "7z archive";
455  return "Quick Time";
456  case ContainerFormat::Xz:
457  return "xz compressed file";
459  return "YUV4MPEG2";
460  case ContainerFormat::Zip:
461  return "ZIP archive";
463  return "Monkey's Audio";
465  return "MIDI";
466  default:
467  return "unknown";
468  }
469 }
470 
476 const char *containerFormatSubversion(ContainerFormat containerFormat)
477 {
478  switch (containerFormat) {
480  return "87a";
482  return "89a";
484  return "big endian";
486  return "little endian";
487  default:
488  return "";
489  }
490 }
491 
497 const char *containerMimeType(ContainerFormat containerFormat, MediaType mediaType)
498 {
499  switch (containerFormat) {
500  case ContainerFormat::Ac3Frames:
501  return "audio/ac3";
502  case ContainerFormat::Asf:
503  return "video/x-ms-asf";
505  return "audio/flac";
506  case ContainerFormat::FlashVideo:
507  return "video/x-flv";
510  return "image/gif";
512  return "image/jpeg";
514  return "image/png";
516  return "audio/mpeg";
518  switch (mediaType) {
519  case MediaType::Audio:
520  return "audio/mp4";
521  default:
522  return "video/mp4";
523  }
525  switch (mediaType) {
526  case MediaType::Audio:
527  return "audio/ogg";
528  default:
529  return "video/ogg";
530  }
531  case ContainerFormat::Matroska:
532  switch (mediaType) {
533  case MediaType::Audio:
534  return "audio/x-matroska";
535  default:
536  return "video/x-matroska";
537  }
539  return "audio/midi";
541  return "application/x-bzip";
543  return "application/gzip";
545  return "application/x-lzh-compressed";
547  return "application/x-rar-compressed";
549  return "application/x-lzip";
551  return "video/quicktime";
552  case ContainerFormat::Zip:
553  return "application/zip";
555  return "application/x-7z-compressed";
556  case ContainerFormat::Xz:
557  return "application/x-xz";
559  return "image/bmp";
561  return "image/vnd.microsoft.icon";
562  default:
563  return "";
564  }
565 }
566 
570 TagTargetLevel containerTargetLevel(ContainerFormat containerFormat, uint64 targetLevelValue)
571 {
572  switch (containerFormat) {
573  case ContainerFormat::Matroska:
574  case ContainerFormat::Webm:
575  return matroskaTagTargetLevel(targetLevelValue);
576  default:
577  return TagTargetLevel::Unspecified;
578  }
579 }
580 
584 uint64 containerTargetLevelValue(ContainerFormat containerFormat, TagTargetLevel targetLevel)
585 {
586  switch (containerFormat) {
587  case ContainerFormat::Matroska:
588  case ContainerFormat::Webm:
589  return matroskaTagTargetLevelValue(targetLevel);
590  default:
591  return 0;
592  }
593 }
594 
595 } // namespace TagParser
constexpr TAG_PARSER_EXPORT TagTargetLevel matroskaTagTargetLevel(uint64 targetLevelValue)
Returns the general TagTargetLevel for the Matroska specific targetLevelValue.
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:584
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:570
constexpr 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:497
Sig32
Holds 32-bit signatures.
Definition: signature.cpp:42
constexpr TAG_PARSER_EXPORT uint64 matroskaTagTargetLevelValue(TagTargetLevel targetLevel)
Returns the Matroska specific target level value for the specified general targetLevel.
Sig48
Holds 48-bit signatures.
Definition: signature.cpp:32
Sig16
Holds 16-bit signatures.
Definition: signature.cpp:82
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:371
Sig24
Holds 24-bit signatures.
Definition: signature.cpp:71
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:249
TAG_PARSER_EXPORT ContainerFormat parseSignature(const char *buffer, int bufferSize)
Parses the signature read from the specified buffer.
Definition: signature.cpp:102
TAG_PARSER_EXPORT const char * containerFormatSubversion(ContainerFormat containerFormat)
Returns the subversion of the container format as C-style string.
Definition: signature.cpp:476
Contains all classes and functions of the TagInfo library.
Definition: aaccodebook.h:9