Tag Parser  6.5.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 Media {
9 
13 enum Sig64 : uint64
14 {
15  Ar = 0x213C617263683E0A,
16  Asf1 = 0x3026B2758E66CF11ul,
17  Asf2 = 0xA6D900AA0062CE6Cul,
18  Png = 0x89504E470D0A1A0Aul,
19  RiffAvi = 0x415649204C495354ul,
20  YUV4Mpeg2 = 0x595556344D504547ul,
21 };
22 
26 enum Sig56 : uint64
27 {
28  Rar = 0x526172211A0700ul,
29 };
30 
34 enum Sig48 : uint64
35 {
36  Gif87a = 0x474946383761ul,
37  Gif89a = 0x474946383961ul,
38  SevenZ = 0x377ABCAF271Cul,
39  Xz = 0xFD377A585A00ul,
40 };
41 
45 enum Sig32 : uint32
46 {
47  Dirac = 0x42424344u,
48  Elf = 0x7F454C46u,
49  Flac = 0x664C6143u,
50  JavaClassFile = 0xCAFEBABEu,
51  Ebml = 0x1A45DFA3u,
52  MonkeysAudio = 0x4D414320u,
53  Mp4 = 0x66747970u,
54  Ogg = 0x4F676753u,
55  PhotoshopDocument = 0x38425053u,
56  QuickTime = 0x6D6F6F76u,
57  Riff = 0x52494646u,
58  RiffWave =0x57415645u,
59  TiffBigEndian = 0x4D4D002Au,
60  TiffLittleEndian = 0x49492A00u,
61  Utf32Text = 0xFFFE0000u,
62  WavPack = 0x7776706Bu,
63  WindowsIcon = 0x00000100u,
64  Lzip = 0x4C5A4950u,
65  Zip1 = 0x504B0304u,
66  Zip2 = 0x504B0506u,
67  Zip3 = 0x504B0708u,
68 };
69 
73 enum Sig24 : uint32
74 {
75  Bzip2 = 0x425A68u,
76  Flv = 0x464C56u,
77  Gzip = 0x1F8B08u,
78  Id3v2 = 0x494433u,
79  Utf8Text = 0xEFBBBFu,
80 };
81 
85 enum Sig16 : uint16
86 {
87  Ac3 = 0x0B77u,
88  Adts = 0xFFF0u,
89  AdtsMask = 0xFFF6u,
90  Jpeg = 0xffd8u,
91  Lha = 0x1FA0u,
92  Lzw = 0x1F9Du,
93  MpegAudioFrames = 0x7FFu,
94  PortableExecutable = 0x4D5Au,
95  Utf16Text = 0xFFFEu,
96  WindowsBitmap = 0x424du,
97 };
98 
106 ContainerFormat parseSignature(const char *buffer, int bufferSize)
107 {
108  // read signature
109  uint64 sig = 0;
110  if(bufferSize >= 8) {
111  sig = ConversionUtilities::BE::toUInt64(buffer);
112  } else if(bufferSize >= 4) {
113  sig = ConversionUtilities::BE::toUInt32(buffer);
114  sig <<= 4;
115  } else if(bufferSize >= 2) {
116  sig = ConversionUtilities::BE::toUInt16(buffer);
117  sig <<= 6;
118  } else {
119  return ContainerFormat::Unknown;
120  }
121  // return corresponding container format
122  switch(sig) { // check 64-bit signatures
123  case Ar:
124  return ContainerFormat::Ar;
125  case Asf1:
126  return ContainerFormat::Asf;
127  case Asf2:
128  return ContainerFormat::Asf;
129  case Png:
130  return ContainerFormat::Png;
131  case YUV4Mpeg2:
132  if(bufferSize >= 10 && buffer[8] == 0x32 && buffer[9] == 0x20) {
134  }
135  break;
136  default:
137  ;
138  }
139  switch(sig & 0x00000000FFFFFFFF) { // check 32-bit signatures @ bit 31
140  case Mp4:
141  return ContainerFormat::Mp4;
142  case QuickTime:
144  default:
145  ;
146  }
147  switch(sig >> 8) { // check 56-bit signatures
148  case Rar:
149  return ContainerFormat::Rar;
150  default:
151  ;
152  }
153  switch(sig >> 16) { // check 48-bit signatures
154  case Gif87a:
156  case Gif89a:
158  case SevenZ:
160  case Xz:
161  return ContainerFormat::Xz;
162  default:
163  ;
164  }
165  switch(sig >> 32) { // check 32-bit signatures
166  case Dirac:
167  return ContainerFormat::Dirac;
168  case Elf:
169  return ContainerFormat::Elf;
170  case Flac:
171  return ContainerFormat::Flac;
172  case JavaClassFile:
174  case Ebml:
175  return ContainerFormat::Ebml;
176  case MonkeysAudio:
178  case Ogg:
179  return ContainerFormat::Ogg;
180  case PhotoshopDocument:
182  case Riff:
183  if(bufferSize >= 16 && ConversionUtilities::BE::toUInt64(buffer + 8) == Sig64::RiffAvi) {
185  } else if (bufferSize >= 12 && ConversionUtilities::BE::toUInt32(buffer + 8) == RiffWave) {
187  } else {
188  return ContainerFormat::Riff;
189  }
190  case TiffBigEndian:
192  case TiffLittleEndian:
194  case Utf32Text:
196  case WavPack:
198  case WindowsIcon:
200  case Lzip:
201  return ContainerFormat::Lzip;
202  case Zip1:
203  case Zip2:
204  case Zip3:
205  return ContainerFormat::Zip;
206  default:
207  ;
208  }
209  switch(sig >> 40) { // check 24-bit signatures
210  case Bzip2:
211  return ContainerFormat::Bzip2;
212  case Flv:
213  return ContainerFormat::FlashVideo;
214  case Gzip:
215  return ContainerFormat::Gzip;
216  case Id3v2:
217  return ContainerFormat::Id2v2Tag;
218  case Utf8Text:
220  }
221  switch(sig >> 48) { // check 16-bit signatures
222  case Ac3:
223  return ContainerFormat::Ac3Frames;
224  case Jpeg:
225  return ContainerFormat::Jpeg;
226  case Lha:
227  return ContainerFormat::Lha;
228  case Lzw:
229  return ContainerFormat::Lzw;
230  case PortableExecutable:
232  case Utf16Text:
234  case WindowsBitmap:
236  default:
237  ;
238  }
239  // check other signatures
240  if(((sig >> 48) & AdtsMask) == Adts) {
241  return ContainerFormat::Adts;
242  }
243  if((sig >> 53) == MpegAudioFrames) {
245  }
246  return ContainerFormat::Unknown;
247 }
248 
255 const char *containerFormatAbbreviation(ContainerFormat containerFormat, MediaType mediaType, unsigned int version)
256 {
257  switch(containerFormat) {
258  case ContainerFormat::Ac3Frames: return "ac3";
259  case ContainerFormat::Ar: return "a";
260  case ContainerFormat::Asf: return "asf";
261  case ContainerFormat::Dirac: return "drc";
262  case ContainerFormat::Elf: return "elf";
263  case ContainerFormat::Flac: return "flac";
264  case ContainerFormat::FlashVideo: return "flv";
266  case ContainerFormat::Gif89a: return "gif";
267  case ContainerFormat::JavaClassFile: return "class";
268  case ContainerFormat::Jpeg: return "jpeg";
269  case ContainerFormat::Lha: return "lzh";
270  case ContainerFormat::Lzw: 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  }
292  case ContainerFormat::PhotoshopDocument: return "psd";
293  case ContainerFormat::Png: return "png";
294  case ContainerFormat::PortableExecutable: return "exe";
295  case ContainerFormat::Rar: return "rar";
296  case ContainerFormat::Matroska:
297  switch(mediaType) {
298  case MediaType::Audio:
299  return "mka";
300  default:
301  return "mkv";
302  }
304  switch(version) {
305  case 1:
306  return "mp1";
307  case 2:
308  return "mp2";
309  default:
310  return "mp3";
311  }
312  case ContainerFormat::Riff: return "riff";
313  case ContainerFormat::RiffWave: return "wav";
314  case ContainerFormat::RiffAvi: return "avi";
315  case ContainerFormat::Tar: return "tar";
317  case ContainerFormat::TiffLittleEndian: return "tiff";
318  case ContainerFormat::WindowsBitmap: return "bmp";
319  case ContainerFormat::WindowsIcon: return "ico";
320  case ContainerFormat::Bzip2: return "bz";
321  case ContainerFormat::Gzip: return "gz";
322  case ContainerFormat::Lzip: return "lz";
323  case ContainerFormat::QuickTime: return "mov";
324  case ContainerFormat::Zip: return "zip";
325  case ContainerFormat::SevenZ: return "7z";
326  case ContainerFormat::Xz: return "xz";
327  case ContainerFormat::YUV4Mpeg2: return "y4m";
328  case ContainerFormat::WavPack: return "wv";
329  case ContainerFormat::MonkeysAudio: return "ape";
330  default: return "";
331  }
332 }
333 
339 const char *containerFormatName(ContainerFormat containerFormat)
340 {
341  switch(containerFormat) {
342  case ContainerFormat::Ac3Frames:
343  return "raw Dolby Digital";
345  return "Audio Data Transport Stream";
346  case ContainerFormat::Ar:
347  return "Archive (GNU ar)";
348  case ContainerFormat::Asf:
349  return "Advanced Systems Format";
351  return "raw Dirac";
353  return "Executable and Linkable Format";
355  return "raw Free Lossless Audio Codec frames";
356  case ContainerFormat::FlashVideo:
357  return "Flash Video";
360  return "Graphics Interchange Format";
362  return "Java class file";
364  return "JPEG File Interchange Format";
366  return "LHA compressed file";
368  return "LZW compressed file";
370  return "MPEG-4 Part 14";
372  return "Ogg transport bitstream";
374  return "Photoshop document";
376  return "Portable Network Graphics";
378  return "Portable Executable";
380  return "RAR Archive";
382  return "EBML";
383  case ContainerFormat::Matroska:
384  return "Matroska";
385  case ContainerFormat::Webm:
386  return "WebM";
388  return "MPEG-1 Layer 1/2/3 frames";
390  return "Resource Interchange File Format";
392  return "RIFF/WAVE";
394  return "RIFF/Audio Video Interleave";
395  case ContainerFormat::Tar:
396  return "TAR archive";
399  return "Tagged Image File Format";
401  return "UTF-16 text";
403  return "UTF-32 text";
405  return "UTF-8 text";
407  return "WavPack";
409  return "Microsoft Windows Bitmap";
411  return "Microsoft Windows Icon";
413  return "bzip2 compressed file";
415  return "gzip compressed file";
417  return "lzip compressed file";
419  return "7z archive";
421  return "Quick Time";
422  case ContainerFormat::Xz:
423  return "xz compressed file";
425  return "YUV4MPEG2";
426  case ContainerFormat::Zip:
427  return "ZIP archive";
429  return "Monkey's Audio";
430  default:
431  return "unknown";
432  }
433 }
434 
440 const char *containerFormatSubversion(ContainerFormat containerFormat)
441 {
442  switch(containerFormat) {
444  return "87a";
446  return "89a";
448  return "big endian";
450  return "little endian";
451  default:
452  return "";
453  }
454 }
455 
461 const char *containerMimeType(ContainerFormat containerFormat, MediaType mediaType)
462 {
463  switch(containerFormat) {
464  case ContainerFormat::Ac3Frames:
465  return "audio/ac3";
466  case ContainerFormat::Asf:
467  return "video/x-ms-asf";
469  return "audio/flac";
470  case ContainerFormat::FlashVideo:
471  return "video/x-flv";
474  return "image/gif";
476  return "image/jpeg";
478  return "image/png";
480  return "audio/mpeg";
482  switch(mediaType) {
483  case MediaType::Audio:
484  return "audio/mp4";
485  default:
486  return "video/mp4";
487  }
489  switch(mediaType) {
490  case MediaType::Audio:
491  return "audio/ogg";
492  default:
493  return "video/ogg";
494  }
495  case ContainerFormat::Matroska:
496  switch(mediaType) {
497  case MediaType::Audio:
498  return "audio/x-matroska";
499  default:
500  return "video/x-matroska";
501  }
503  return "application/x-bzip";
505  return "application/gzip";
507  return "application/x-lzh-compressed";
509  return "application/x-rar-compressed";
511  return "application/x-lzip";
513  return "video/quicktime";
514  case ContainerFormat::Zip:
515  return "application/zip";
517  return "application/x-7z-compressed";
518  case ContainerFormat::Xz:
519  return "application/x-xz";
521  return "image/bmp";
523  return "image/vnd.microsoft.icon";
524  default:
525  return "";
526  }
527 }
528 
532 TagTargetLevel containerTargetLevel(ContainerFormat containerFormat, uint64 targetLevelValue)
533 {
534  switch(containerFormat) {
535  case ContainerFormat::Matroska:
536  case ContainerFormat::Webm:
537  return matroskaTagTargetLevel(targetLevelValue);
538  default:
539  return TagTargetLevel::Unspecified;
540  }
541 }
542 
546 uint64 containerTargetLevelValue(ContainerFormat containerFormat, TagTargetLevel targetLevel)
547 {
548  switch(containerFormat) {
549  case ContainerFormat::Matroska:
550  case ContainerFormat::Webm:
551  return matroskaTagTargetLevelValue(targetLevel);
552  default:
553  return 0;
554  }
555 }
556 
557 }
Sig32
Holds 32-bit signatures.
Definition: signature.cpp:45
Sig56
Holds 52-bit signatures.
Definition: signature.cpp:26
MediaType
The MediaType enum specifies the type of media data (audio, video, text, ...).
Definition: mediaformat.h:13
ContainerFormat
Specifies the container format.
Definition: signature.h:17
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 uint64 matroskaTagTargetLevelValue(TagTargetLevel targetLevel)
Returns the Matroska specific target level value for the specified general targetLevel.
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:255
TAG_PARSER_EXPORT const char * containerFormatSubversion(ContainerFormat containerFormat)
Returns the subversion of the container format as C-style string.
Definition: signature.cpp:440
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:546
TagTargetLevel
The TagTargetLevel enum specifies tag target levels.
Definition: tagtarget.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:339
TAG_PARSER_EXPORT ContainerFormat parseSignature(const char *buffer, int bufferSize)
Parses the signature read from the specified buffer.
Definition: signature.cpp:106
Sig16
Holds 16-bit signatures.
Definition: signature.cpp:85
TAG_PARSER_EXPORT TagTargetLevel containerTargetLevel(ContainerFormat containerFormat, uint64 targetLevelValue)
Returns the general TagTargetLevel for the specified container format and raw targetLevelValue.
Definition: signature.cpp:532
Sig24
Holds 24-bit signatures.
Definition: signature.cpp:73
Sig48
Holds 48-bit signatures.
Definition: signature.cpp:34
Contains all classes and functions of the TagInfo library.
Definition: exceptions.h:9
TAG_PARSER_EXPORT const char * version()
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:461