Tag Parser  6.4.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 Media {
9 
13 enum Sig64 : uint64
14 {
15  Ar = 0x213C617263683E0A,
16  Asf1 = 0x3026B2758E66CF11ul,
17  Asf2 = 0xA6D900AA0062CE6Cul,
18  Png = 0x89504E470D0A1A0Aul,
19  RiffAvi = 0x415649204C495354ul,
20 };
21 
25 enum Sig56 : uint64
26 {
27  Rar = 0x526172211A0700ul,
28 };
29 
33 enum Sig48 : uint64
34 {
35  Gif87a = 0x474946383761ul,
36  Gif89a = 0x474946383961ul,
37  SevenZ = 0x377ABCAF271Cul,
38  Xz = 0xFD377A585A00ul,
39 };
40 
44 enum Sig32 : uint32
45 {
46  Dirac = 0x42424344u,
47  Elf = 0x7F454C46u,
48  Flac = 0x664C6143u,
49  JavaClassFile = 0xCAFEBABEu,
50  Ebml = 0x1A45DFA3u,
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  WindowsIcon = 0x00000100u,
61  Lzip = 0x4C5A4950u,
62  Zip1 = 0x504B0304u,
63  Zip2 = 0x504B0506u,
64  Zip3 = 0x504B0708u,
65 };
66 
70 enum Sig24 : uint32
71 {
72  Bzip2 = 0x425A68u,
73  Flv = 0x464C56u,
74  Gzip = 0x1F8B08u,
75  Id3v2 = 0x494433u,
76  Utf8Text = 0xEFBBBFu,
77 };
78 
82 enum Sig16 : uint16
83 {
84  Ac3 = 0x0B77u,
85  Adts = 0xFFF0u,
86  AdtsMask = 0xFFF6u,
87  Jpeg = 0xffd8u,
88  Lha = 0x1FA0u,
89  Lzw = 0x1F9Du,
90  MpegAudioFrames = 0x7FFu,
91  PortableExecutable = 0x4D5Au,
92  Utf16Text = 0xFFFEu,
93  WindowsBitmap = 0x424du,
94 };
95 
103 ContainerFormat parseSignature(const char *buffer, int bufferSize)
104 {
105  // read signature
106  uint64 sig = 0;
107  if(bufferSize >= 8) {
108  sig = ConversionUtilities::BE::toUInt64(buffer);
109  } else if(bufferSize >= 4) {
110  sig = ConversionUtilities::BE::toUInt32(buffer);
111  sig <<= 4;
112  } else if(bufferSize >= 2) {
113  sig = ConversionUtilities::BE::toUInt16(buffer);
114  sig <<= 6;
115  } else {
116  return ContainerFormat::Unknown;
117  }
118  // return corresponding container format
119  switch(sig) { // check 64-bit signatures
120  case Ar:
121  return ContainerFormat::Ar;
122  case Asf1:
123  return ContainerFormat::Asf;
124  case Asf2:
125  return ContainerFormat::Asf;
126  case Png:
127  return ContainerFormat::Png;
128  default:
129  ;
130  }
131  switch(sig & 0x00000000FFFFFFFF) { // check 32-bit signatures @ bit 31
132  case Mp4:
133  return ContainerFormat::Mp4;
134  case QuickTime:
136  default:
137  ;
138  }
139  switch(sig >> 8) { // check 56-bit signatures
140  case Rar:
141  return ContainerFormat::Rar;
142  default:
143  ;
144  }
145  switch(sig >> 16) { // check 48-bit signatures
146  case Gif87a:
148  case Gif89a:
150  case SevenZ:
152  case Xz:
153  return ContainerFormat::Xz;
154  default:
155  ;
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 JavaClassFile:
166  case Ebml:
167  return ContainerFormat::Ebml;
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 WindowsIcon:
188  case Lzip:
189  return ContainerFormat::Lzip;
190  case Zip1:
191  case Zip2:
192  case Zip3:
193  return ContainerFormat::Zip;
194  default:
195  ;
196  }
197  switch(sig >> 40) { // check 24-bit signatures
198  case Bzip2:
199  return ContainerFormat::Bzip2;
200  case Flv:
201  return ContainerFormat::FlashVideo;
202  case Gzip:
203  return ContainerFormat::Gzip;
204  case Id3v2:
205  return ContainerFormat::Id2v2Tag;
206  case Utf8Text:
208  }
209  switch(sig >> 48) { // check 16-bit signatures
210  case Ac3:
211  return ContainerFormat::Ac3Frames;
212  case Jpeg:
213  return ContainerFormat::Jpeg;
214  case Lha:
215  return ContainerFormat::Lha;
216  case Lzw:
217  return ContainerFormat::Lzw;
218  case PortableExecutable:
220  case Utf16Text:
222  case WindowsBitmap:
224  default:
225  ;
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: return "ac3";
247  case ContainerFormat::Ar: return "a";
248  case ContainerFormat::Asf: return "asf";
249  case ContainerFormat::Dirac: return "drc";
250  case ContainerFormat::Elf: return "elf";
251  case ContainerFormat::Flac: return "flac";
252  case ContainerFormat::FlashVideo: return "flv";
254  case ContainerFormat::Gif89a: return "gif";
255  case ContainerFormat::JavaClassFile: return "class";
256  case ContainerFormat::Jpeg: return "jpeg";
257  case ContainerFormat::Lha: return "lzh";
258  case ContainerFormat::Lzw: return "lzw";
260  switch(mediaType) {
261  case MediaType::Audio:
262  return "m4a";
263  default:
264  return "mp4";
265  }
267  switch(mediaType) {
268  case MediaType::Video:
269  return "ogv";
270  default:
271  switch(version) {
272  case static_cast<unsigned int>(GeneralMediaFormat::Opus):
273  return "opus";
274  default:
275  return "ogg";
276  }
277  }
278  case ContainerFormat::PhotoshopDocument: return "psd";
279  case ContainerFormat::Png: return "png";
280  case ContainerFormat::PortableExecutable: return "exe";
281  case ContainerFormat::Rar: return "rar";
282  case ContainerFormat::Matroska:
283  switch(mediaType) {
284  case MediaType::Audio:
285  return "mka";
286  default:
287  return "mkv";
288  }
290  switch(version) {
291  case 1:
292  return "mp1";
293  case 2:
294  return "mp2";
295  default:
296  return "mp3";
297  }
298  case ContainerFormat::Riff: return "riff";
299  case ContainerFormat::RiffWave: return "wav";
300  case ContainerFormat::RiffAvi: return "avi";
301  case ContainerFormat::Tar: return "tar";
303  case ContainerFormat::TiffLittleEndian: return "tiff";
304  case ContainerFormat::WindowsBitmap: return "bmp";
305  case ContainerFormat::WindowsIcon: return "ico";
306  case ContainerFormat::Bzip2: return "bz";
307  case ContainerFormat::Gzip: return "gz";
308  case ContainerFormat::Lzip: return "lz";
309  case ContainerFormat::QuickTime: return "mov";
310  case ContainerFormat::Zip: return "zip";
311  case ContainerFormat::SevenZ: return "7z";
312  case ContainerFormat::Xz: return "xz";
313  default: return "";
314  }
315 }
316 
322 const char *containerFormatName(ContainerFormat containerFormat)
323 {
324  switch(containerFormat) {
325  case ContainerFormat::Ac3Frames:
326  return "raw Dolby Digital";
328  return "Audio Data Transport Stream";
329  case ContainerFormat::Ar:
330  return "Archive (GNU ar)";
331  case ContainerFormat::Asf:
332  return "Advanced Systems Format";
334  return "raw Dirac";
336  return "Executable and Linkable Format";
338  return "raw Free Lossless Audio Codec frames";
339  case ContainerFormat::FlashVideo:
340  return "Flash Video";
343  return "Graphics Interchange Format";
345  return "Java class file";
347  return "JPEG File Interchange Format";
349  return "LHA compressed file";
351  return "LZW compressed file";
353  return "MPEG-4 Part 14";
355  return "Ogg transport bitstream";
357  return "Photoshop document";
359  return "Portable Network Graphics";
361  return "Portable Executable";
363  return "RAR Archive";
365  return "EBML";
366  case ContainerFormat::Matroska:
367  return "Matroska";
368  case ContainerFormat::Webm:
369  return "WebM";
371  return "MPEG-1 Layer 1/2/3 frames";
373  return "Resource Interchange File Format";
375  return "RIFF/WAVE";
377  return "RIFF/Audio Video Interleave";
378  case ContainerFormat::Tar:
379  return "TAR archive";
382  return "Tagged Image File Format";
384  return "UTF-16 text";
386  return "UTF-32 text";
388  return "UTF-8 text";
390  return "Microsoft Windows Bitmap";
392  return "Microsoft Windows Icon";
394  return "bzip2 compressed file";
396  return "gzip compressed file";
398  return "lzip compressed file";
400  return "7z archive";
402  return "Quick Time";
403  case ContainerFormat::Xz:
404  return "xz compressed file";
405  case ContainerFormat::Zip:
406  return "ZIP archive";
407  default:
408  return "unknown";
409  }
410 }
411 
417 const char *containerFormatSubversion(ContainerFormat containerFormat)
418 {
419  switch(containerFormat) {
421  return "87a";
423  return "89a";
425  return "big endian";
427  return "little endian";
428  default:
429  return "";
430  }
431 }
432 
438 const char *containerMimeType(ContainerFormat containerFormat, MediaType mediaType)
439 {
440  switch(containerFormat) {
441  case ContainerFormat::Ac3Frames:
442  return "audio/ac3";
443  case ContainerFormat::Asf:
444  return "video/x-ms-asf";
446  return "audio/flac";
447  case ContainerFormat::FlashVideo:
448  return "video/x-flv";
451  return "image/gif";
453  return "image/jpeg";
455  return "image/png";
457  return "audio/mpeg";
459  switch(mediaType) {
460  case MediaType::Audio:
461  return "audio/mp4";
462  default:
463  return "video/mp4";
464  }
466  switch(mediaType) {
467  case MediaType::Audio:
468  return "audio/ogg";
469  default:
470  return "video/ogg";
471  }
472  case ContainerFormat::Matroska:
473  switch(mediaType) {
474  case MediaType::Audio:
475  return "audio/x-matroska";
476  default:
477  return "video/x-matroska";
478  }
480  return "application/x-bzip";
482  return "application/gzip";
484  return "application/x-lzh-compressed";
486  return "application/x-rar-compressed";
488  return "application/x-lzip";
490  return "video/quicktime";
491  case ContainerFormat::Zip:
492  return "application/zip";
494  return "application/x-7z-compressed";
495  case ContainerFormat::Xz:
496  return "application/x-xz";
498  return "image/bmp";
500  return "image/vnd.microsoft.icon";
501  default:
502  return "";
503  }
504 }
505 
509 TagTargetLevel containerTargetLevel(ContainerFormat containerFormat, uint64 targetLevelValue)
510 {
511  switch(containerFormat) {
512  case ContainerFormat::Matroska:
513  case ContainerFormat::Webm:
514  return matroskaTagTargetLevel(targetLevelValue);
515  default:
516  return TagTargetLevel::Unspecified;
517  }
518 }
519 
523 uint64 containerTargetLevelValue(ContainerFormat containerFormat, TagTargetLevel targetLevel)
524 {
525  switch(containerFormat) {
526  case ContainerFormat::Matroska:
527  case ContainerFormat::Webm:
528  return matroskaTagTargetLevelValue(targetLevel);
529  default:
530  return 0;
531  }
532 }
533 
534 }
Sig32
Holds 32-bit signatures.
Definition: signature.cpp:44
Sig56
Holds 52-bit signatures.
Definition: signature.cpp:25
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:243
TAG_PARSER_EXPORT const char * containerFormatSubversion(ContainerFormat containerFormat)
Returns the subversion of the container format as C-style string.
Definition: signature.cpp:417
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:523
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:322
TAG_PARSER_EXPORT ContainerFormat parseSignature(const char *buffer, int bufferSize)
Parses the signature read from the specified buffer.
Definition: signature.cpp:103
Sig16
Holds 16-bit signatures.
Definition: signature.cpp:82
TAG_PARSER_EXPORT TagTargetLevel containerTargetLevel(ContainerFormat containerFormat, uint64 targetLevelValue)
Returns the general TagTargetLevel for the specified container format and raw targetLevelValue.
Definition: signature.cpp:509
Sig24
Holds 24-bit signatures.
Definition: signature.cpp:70
Sig48
Holds 48-bit signatures.
Definition: signature.cpp:33
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:438