Tag Parser  6.2.2
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 };
39 
43 enum Sig32 : uint32
44 {
45  Dirac = 0x42424344u,
46  Elf = 0x7F454C46u,
47  Flac = 0x664C6143u,
48  JavaClassFile = 0xCAFEBABEu,
49  Ebml = 0x1A45DFA3u,
50  Mp4 = 0x66747970u,
51  Ogg = 0x4F676753u,
52  PhotoshopDocument = 0x38425053u,
53  QuickTime = 0x6D6F6F76u,
54  Riff = 0x52494646u,
55  RiffWave =0x57415645u,
56  TiffBigEndian = 0x4D4D002Au,
57  TiffLittleEndian = 0x49492A00u,
58  Utf32Text = 0xFFFE0000u,
59  WindowsIcon = 0x00000100u,
60  Lzip = 0x4C5A4950u,
61  Zip1 = 0x504B0304u,
62  Zip2 = 0x504B0506u,
63  Zip3 = 0x504B0708u,
64 };
65 
69 enum Sig24 : uint32
70 {
71  Bzip2 = 0x425A68u,
72  Flv = 0x464C56u,
73  Gzip = 0x1F8B08u,
74  Id3v2 = 0x494433u,
75  Utf8Text = 0xEFBBBFu,
76 };
77 
81 enum Sig16 : uint16
82 {
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  default:
128  ;
129  }
130  switch(sig & 0x00000000FFFFFFFF) { // check 32-bit signatures @ bit 31
131  case Mp4:
132  return ContainerFormat::Mp4;
133  case QuickTime:
135  default:
136  ;
137  }
138  switch(sig >> 8) { // check 56-bit signatures
139  case Rar:
140  return ContainerFormat::Rar;
141  default:
142  ;
143  }
144  switch(sig >> 16) { // check 48-bit signatures
145  case Gif87a:
147  case Gif89a:
149  case SevenZ:
151  default:
152  ;
153  }
154  switch(sig >> 32) { // check 32-bit signatures
155  case Dirac:
156  return ContainerFormat::Dirac;
157  case Elf:
158  return ContainerFormat::Elf;
159  case Flac:
160  return ContainerFormat::Flac;
161  case JavaClassFile:
163  case Ebml:
164  return ContainerFormat::Ebml;
165  case Ogg:
166  return ContainerFormat::Ogg;
167  case PhotoshopDocument:
169  case Riff:
170  if(bufferSize >= 16 && ConversionUtilities::BE::toUInt64(buffer + 8) == Sig64::RiffAvi) {
172  } else if (bufferSize >= 12 && ConversionUtilities::BE::toUInt32(buffer + 8) == RiffWave) {
174  } else {
175  return ContainerFormat::Riff;
176  }
177  case TiffBigEndian:
179  case TiffLittleEndian:
181  case Utf32Text:
183  case WindowsIcon:
185  case Lzip:
186  return ContainerFormat::Lzip;
187  case Zip1:
188  case Zip2:
189  case Zip3:
190  return ContainerFormat::Zip;
191  default:
192  ;
193  }
194  switch(sig >> 40) { // check 24-bit signatures
195  case Bzip2:
196  return ContainerFormat::Bzip2;
197  case Flv:
198  return ContainerFormat::FlashVideo;
199  case Gzip:
200  return ContainerFormat::Gzip;
201  case Id3v2:
202  return ContainerFormat::Id2v2Tag;
203  case Utf8Text:
205  }
206  switch(sig >> 48) { // check 16-bit signatures
207  case Ac3:
208  return ContainerFormat::Ac3Frames;
209  case Jpeg:
210  return ContainerFormat::Jpeg;
211  case Lha:
212  return ContainerFormat::Lha;
213  case Lzw:
214  return ContainerFormat::Lzw;
215  case PortableExecutable:
217  case Utf16Text:
219  case WindowsBitmap:
221  default:
222  ;
223  }
224  // check other signatures
225  if(((sig >> 48) & AdtsMask) == Adts) {
226  return ContainerFormat::Adts;
227  }
228  if((sig >> 53) == MpegAudioFrames) {
230  }
231  return ContainerFormat::Unknown;
232 }
233 
240 const char *containerFormatAbbreviation(ContainerFormat containerFormat, MediaType mediaType, unsigned int version)
241 {
242  switch(containerFormat) {
243  case ContainerFormat::Ac3Frames: return "ac3";
244  case ContainerFormat::Ar: return "a";
245  case ContainerFormat::Asf: return "asf";
246  case ContainerFormat::Dirac: return "drc";
247  case ContainerFormat::Elf: return "elf";
248  case ContainerFormat::Flac: return "flac";
249  case ContainerFormat::FlashVideo: return "flv";
251  case ContainerFormat::Gif89a: return "gif";
252  case ContainerFormat::JavaClassFile: return "class";
253  case ContainerFormat::Jpeg: return "jpeg";
254  case ContainerFormat::Lha: return "lzh";
255  case ContainerFormat::Lzw: return "lzw";
257  switch(mediaType) {
258  case MediaType::Audio:
259  return "m4a";
260  default:
261  return "mp4";
262  }
264  switch(mediaType) {
265  case MediaType::Video:
266  return "ogv";
267  default:
268  switch(version) {
269  case static_cast<unsigned int>(GeneralMediaFormat::Opus):
270  return "opus";
271  default:
272  return "ogg";
273  }
274  }
275  case ContainerFormat::PhotoshopDocument: return "psd";
276  case ContainerFormat::Png: return "png";
277  case ContainerFormat::PortableExecutable: return "exe";
278  case ContainerFormat::Rar: return "rar";
279  case ContainerFormat::Matroska:
280  switch(mediaType) {
281  case MediaType::Audio:
282  return "mka";
283  default:
284  return "mkv";
285  }
287  switch(version) {
288  case 1:
289  return "mp1";
290  case 2:
291  return "mp2";
292  default:
293  return "mp3";
294  }
295  case ContainerFormat::Riff: return "riff";
296  case ContainerFormat::RiffWave: return "wav";
297  case ContainerFormat::RiffAvi: return "avi";
298  case ContainerFormat::Tar: return "tar";
300  case ContainerFormat::TiffLittleEndian: return "tiff";
301  case ContainerFormat::WindowsBitmap: return "bmp";
302  case ContainerFormat::WindowsIcon: return "ico";
303  case ContainerFormat::Bzip2: return "bz";
304  case ContainerFormat::Gzip: return "gz";
305  case ContainerFormat::Lzip: return "lz";
306  case ContainerFormat::QuickTime: return "mov";
307  case ContainerFormat::Zip: return "zip";
308  case ContainerFormat::SevenZ: return "7z";
309  default: return "";
310  }
311 }
312 
318 const char *containerFormatName(ContainerFormat containerFormat)
319 {
320  switch(containerFormat) {
321  case ContainerFormat::Ac3Frames:
322  return "raw Dolby Digital";
324  return "Audio Data Transport Stream";
325  case ContainerFormat::Ar:
326  return "Archive (GNU ar)";
327  case ContainerFormat::Asf:
328  return "Advanced Systems Format";
330  return "raw Dirac";
332  return "Executable and Linkable Format";
334  return "raw Free Lossless Audio Codec frames";
335  case ContainerFormat::FlashVideo:
336  return "Flash Video";
339  return "Graphics Interchange Format";
341  return "Java class file";
343  return "JPEG File Interchange Format";
345  return "LHA compressed file";
347  return "LZW compressed file";
349  return "MPEG-4 Part 14";
351  return "Ogg transport bitstream";
353  return "Photoshop document";
355  return "Portable Network Graphics";
357  return "Portable Executable";
359  return "RAR Archive";
361  return "EBML";
362  case ContainerFormat::Matroska:
363  return "Matroska";
364  case ContainerFormat::Webm:
365  return "WebM";
367  return "MPEG-1 Layer 1/2/3 frames";
369  return "Resource Interchange File Format";
371  return "RIFF/WAVE";
373  return "RIFF/Audio Video Interleave";
374  case ContainerFormat::Tar:
375  return "TAR archive";
378  return "Tagged Image File Format";
380  return "UTF-16 text";
382  return "UTF-32 text";
384  return "UTF-8 text";
386  return "Microsoft Windows Bitmap";
388  return "Microsoft Windows Icon";
390  return "bzip2 compressed file";
392  return "gzip compressed file";
394  return "lzip compressed file";
396  return "7z archive";
398  return "Quick Time";
399  case ContainerFormat::Zip:
400  return "ZIP archive";
401  default:
402  return "unknown";
403  }
404 }
405 
411 const char *containerFormatSubversion(ContainerFormat containerFormat)
412 {
413  switch(containerFormat) {
415  return "87a";
417  return "89a";
419  return "big endian";
421  return "little endian";
422  default:
423  return "";
424  }
425 }
426 
432 const char *containerMimeType(ContainerFormat containerFormat, MediaType mediaType)
433 {
434  switch(containerFormat) {
435  case ContainerFormat::Ac3Frames:
436  return "audio/ac3";
437  case ContainerFormat::Asf:
438  return "video/x-ms-asf";
440  return "audio/flac";
441  case ContainerFormat::FlashVideo:
442  return "video/x-flv";
445  return "image/gif";
447  return "image/jpeg";
449  return "image/png";
451  return "audio/mpeg";
453  switch(mediaType) {
454  case MediaType::Audio:
455  return "audio/mp4";
456  default:
457  return "video/mp4";
458  }
460  switch(mediaType) {
461  case MediaType::Audio:
462  return "audio/ogg";
463  default:
464  return "video/ogg";
465  }
466  case ContainerFormat::Matroska:
467  switch(mediaType) {
468  case MediaType::Audio:
469  return "audio/x-matroska";
470  default:
471  return "video/x-matroska";
472  }
474  return "application/x-bzip";
476  return "application/gzip";
478  return "application/x-lzh-compressed";
480  return "application/x-rar-compressed";
482  return "application/x-lzip";
484  return "video/quicktime";
485  case ContainerFormat::Zip:
486  return "application/zip";
488  return "application/x-7z-compressed";
490  return "image/bmp";
492  return "image/vnd.microsoft.icon";
493  default:
494  return "";
495  }
496 }
497 
501 TagTargetLevel containerTargetLevel(ContainerFormat containerFormat, uint64 targetLevelValue)
502 {
503  switch(containerFormat) {
504  case ContainerFormat::Matroska:
505  case ContainerFormat::Webm:
506  return matroskaTagTargetLevel(targetLevelValue);
507  default:
508  return TagTargetLevel::Unspecified;
509  }
510 }
511 
515 uint64 containerTargetLevelValue(ContainerFormat containerFormat, TagTargetLevel targetLevel)
516 {
517  switch(containerFormat) {
518  case ContainerFormat::Matroska:
519  case ContainerFormat::Webm:
520  return matroskaTagTargetLevelValue(targetLevel);
521  default:
522  return 0;
523  }
524 }
525 
526 }
Sig32
Holds 32-bit signatures.
Definition: signature.cpp:43
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:240
TAG_PARSER_EXPORT const char * containerFormatSubversion(ContainerFormat containerFormat)
Returns the subversion of the container format as C-style string.
Definition: signature.cpp:411
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:515
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:318
TAG_PARSER_EXPORT ContainerFormat parseSignature(const char *buffer, int bufferSize)
Parses the signature read from the specified buffer.
Definition: signature.cpp:102
Sig16
Holds 16-bit signatures.
Definition: signature.cpp:81
TAG_PARSER_EXPORT TagTargetLevel containerTargetLevel(ContainerFormat containerFormat, uint64 targetLevelValue)
Returns the general TagTargetLevel for the specified container format and raw targetLevelValue.
Definition: signature.cpp:501
Sig24
Holds 24-bit signatures.
Definition: signature.cpp:69
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:432