Tag Parser  9.4.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 #include <cstdint>
7 
8 using namespace CppUtilities;
9 
10 namespace TagParser {
11 
15 enum Sig64 : std::uint64_t {
16  Ar = 0x213C617263683E0A,
17  Asf1 = 0x3026B2758E66CF11ul,
18  Asf2 = 0xA6D900AA0062CE6Cul,
19  Png = 0x89504E470D0A1A0Aul,
20  RiffAvi = 0x415649204C495354ul,
21  YUV4Mpeg2 = 0x595556344D504547ul,
22 };
23 
27 enum Sig56 : std::uint64_t {
28  Rar = 0x526172211A0700ul,
29 };
30 
34 enum Sig48 : std::uint64_t {
35  Gif87a = 0x474946383761ul,
36  Gif89a = 0x474946383961ul,
37  SevenZ = 0x377ABCAF271Cul,
38  Xz = 0xFD377A585A00ul,
39 };
40 
44 enum Sig32 : std::uint32_t {
45  Dirac = 0x42424344u,
46  Elf = 0x7F454C46u,
47  Flac = 0x664C6143u,
48  Ivf = 0x444B4946u,
49  JavaClassFile = 0xCAFEBABEu,
50  Ebml = 0x1A45DFA3u,
51  Midi = 0x4D546864u,
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 : std::uint32_t {
74  Bzip2 = 0x425A68u,
75  Flv = 0x464C56u,
76  Gzip = 0x1F8B08u,
77  Id3v2 = 0x494433u,
78  Utf8Text = 0xEFBBBFu,
79 };
80 
84 enum Sig16 : std::uint16_t {
85  Ac3 = 0x0B77u,
86  Adts = 0xFFF0u,
87  AdtsMask = 0xFFF6u,
88  Jpeg = 0xffd8u,
89  Lha = 0x1FA0u,
90  Lzw = 0x1F9Du,
91  MpegAudioFrames = 0x7FFu,
92  PortableExecutable = 0x4D5Au,
93  Utf16Text = 0xFFFEu,
94  WindowsBitmap = 0x424du,
95 };
96 
104 ContainerFormat parseSignature(const char *buffer, int bufferSize)
105 {
106  // read signature
107  std::uint64_t sig = 0;
108  if (bufferSize >= 8) {
109  sig = BE::toUInt64(buffer);
110  } else if (bufferSize >= 4) {
111  sig = BE::toUInt32(buffer);
112  sig <<= 4;
113  } else if (bufferSize >= 2) {
114  sig = BE::toUInt16(buffer);
115  sig <<= 6;
116  } else {
117  return ContainerFormat::Unknown;
118  }
119  // return corresponding container format
120  switch (sig) { // check 64-bit signatures
121  case Ar:
122  return ContainerFormat::Ar;
123  case Asf1:
124  return ContainerFormat::Asf;
125  case Asf2:
126  return ContainerFormat::Asf;
127  case Png:
128  return ContainerFormat::Png;
129  case YUV4Mpeg2:
130  if (bufferSize >= 10 && buffer[8] == 0x32 && buffer[9] == 0x20) {
132  }
133  break;
134  default:;
135  }
136  switch (sig & 0x00000000FFFFFFFF) { // check 32-bit signatures @ bit 31
137  case Mp4:
138  return ContainerFormat::Mp4;
139  case QuickTime:
141  default:;
142  }
143  switch (sig >> 8) { // check 56-bit signatures
144  case Rar:
145  return ContainerFormat::Rar;
146  default:;
147  }
148  switch (sig >> 16) { // check 48-bit signatures
149  case Gif87a:
151  case Gif89a:
153  case SevenZ:
155  case Xz:
156  return ContainerFormat::Xz;
157  default:;
158  }
159  switch (sig >> 32) { // check 32-bit signatures
160  case Dirac:
161  return ContainerFormat::Dirac;
162  case Elf:
163  return ContainerFormat::Elf;
164  case Flac:
165  return ContainerFormat::Flac;
166  case Ivf:
167  return ContainerFormat::Ivf;
168  case JavaClassFile:
170  case Ebml:
171  return ContainerFormat::Ebml;
172  case Midi:
173  return ContainerFormat::Midi;
174  case MonkeysAudio:
176  case Ogg:
177  return ContainerFormat::Ogg;
178  case PhotoshopDocument:
180  case Riff:
181  if (bufferSize >= 16 && BE::toUInt64(buffer + 8) == Sig64::RiffAvi) {
183  } else if (bufferSize >= 12 && BE::toUInt32(buffer + 8) == RiffWave) {
185  } else {
186  return ContainerFormat::Riff;
187  }
188  case TiffBigEndian:
190  case TiffLittleEndian:
192  case Utf32Text:
194  case WavPack:
196  case WindowsIcon:
198  case Lzip:
199  return ContainerFormat::Lzip;
200  case Zip1:
201  case Zip2:
202  case Zip3:
203  return ContainerFormat::Zip;
204  default:;
205  }
206  switch (sig >> 40) { // check 24-bit signatures
207  case Bzip2:
208  return ContainerFormat::Bzip2;
209  case Flv:
210  return ContainerFormat::FlashVideo;
211  case Gzip:
212  return ContainerFormat::Gzip;
213  case Id3v2:
214  return ContainerFormat::Id2v2Tag;
215  case Utf8Text:
217  }
218  switch (sig >> 48) { // check 16-bit signatures
219  case Ac3:
220  return ContainerFormat::Ac3Frames;
221  case Jpeg:
222  return ContainerFormat::Jpeg;
223  case Lha:
224  return ContainerFormat::Lha;
225  case Lzw:
226  return ContainerFormat::Lzw;
227  case PortableExecutable:
229  case Utf16Text:
231  case WindowsBitmap:
233  default:;
234  }
235  // check other signatures
236  if (((sig >> 48) & AdtsMask) == Adts) {
237  return ContainerFormat::Adts;
238  }
239  if ((sig >> 53) == MpegAudioFrames) {
241  }
242  return ContainerFormat::Unknown;
243 }
244 
251 const char *containerFormatAbbreviation(ContainerFormat containerFormat, MediaType mediaType, unsigned int version)
252 {
253  switch (containerFormat) {
254  case ContainerFormat::Ac3Frames:
255  return "ac3";
256  case ContainerFormat::Ar:
257  return "a";
258  case ContainerFormat::Asf:
259  return "asf";
261  return "drc";
263  return "elf";
265  return "flac";
266  case ContainerFormat::FlashVideo:
267  return "flv";
270  return "gif";
272  return "ivf";
274  return "class";
276  return "jpeg";
278  return "lzh";
280  return "lzw";
282  switch (mediaType) {
283  case MediaType::Audio:
284  return "m4a";
285  default:
286  return "mp4";
287  }
289  switch (mediaType) {
290  case MediaType::Video:
291  return "ogv";
292  default:
293  switch (version) {
294  case static_cast<unsigned int>(GeneralMediaFormat::Opus):
295  return "opus";
296  case static_cast<unsigned int>(GeneralMediaFormat::Speex):
297  return "spx";
298  default:
299  return "ogg";
300  }
301  }
303  return "psd";
305  return "png";
307  return "exe";
309  return "rar";
310  case ContainerFormat::Matroska:
311  switch (mediaType) {
312  case MediaType::Audio:
313  return "mka";
314  default:
315  return "mkv";
316  }
318  switch (version) {
319  case 1:
320  return "mp1";
321  case 2:
322  return "mp2";
323  default:
324  return "mp3";
325  }
327  return "riff";
329  return "wav";
331  return "avi";
332  case ContainerFormat::Tar:
333  return "tar";
336  return "tiff";
338  return "bmp";
340  return "ico";
342  return "bz";
344  return "gz";
346  return "lz";
348  return "mov";
349  case ContainerFormat::Zip:
350  return "zip";
352  return "7z";
353  case ContainerFormat::Xz:
354  return "xz";
356  return "y4m";
358  return "wv";
360  return "ape";
362  return "mid";
363  default:
364  return "";
365  }
366 }
367 
373 const char *containerFormatName(ContainerFormat containerFormat)
374 {
375  switch (containerFormat) {
376  case ContainerFormat::Ac3Frames:
377  return "raw Dolby Digital";
379  return "Audio Data Transport Stream";
380  case ContainerFormat::Ar:
381  return "Archive (GNU ar)";
382  case ContainerFormat::Asf:
383  return "Advanced Systems Format";
385  return "raw Dirac";
387  return "Executable and Linkable Format";
389  return "raw Free Lossless Audio Codec frames";
390  case ContainerFormat::FlashVideo:
391  return "Flash Video";
394  return "Graphics Interchange Format";
396  return "IVF";
398  return "Java class file";
400  return "JPEG File Interchange Format";
402  return "LHA compressed file";
404  return "LZW compressed file";
406  return "MPEG-4 Part 14";
408  return "Ogg transport bitstream";
410  return "Photoshop document";
412  return "Portable Network Graphics";
414  return "Portable Executable";
416  return "RAR Archive";
418  return "EBML";
419  case ContainerFormat::Matroska:
420  return "Matroska";
421  case ContainerFormat::Webm:
422  return "WebM";
424  return "MPEG-1 Layer 1/2/3 frames";
426  return "Resource Interchange File Format";
428  return "RIFF/WAVE";
430  return "RIFF/Audio Video Interleave";
431  case ContainerFormat::Tar:
432  return "TAR archive";
435  return "Tagged Image File Format";
437  return "UTF-16 text";
439  return "UTF-32 text";
441  return "UTF-8 text";
443  return "WavPack";
445  return "Microsoft Windows Bitmap";
447  return "Microsoft Windows Icon";
449  return "bzip2 compressed file";
451  return "gzip compressed file";
453  return "lzip compressed file";
455  return "7z archive";
457  return "Quick Time";
458  case ContainerFormat::Xz:
459  return "xz compressed file";
461  return "YUV4MPEG2";
462  case ContainerFormat::Zip:
463  return "ZIP archive";
465  return "Monkey's Audio";
467  return "MIDI";
468  default:
469  return "unknown";
470  }
471 }
472 
478 const char *containerFormatSubversion(ContainerFormat containerFormat)
479 {
480  switch (containerFormat) {
482  return "87a";
484  return "89a";
486  return "big endian";
488  return "little endian";
489  default:
490  return "";
491  }
492 }
493 
499 const char *containerMimeType(ContainerFormat containerFormat, MediaType mediaType)
500 {
501  switch (containerFormat) {
502  case ContainerFormat::Ac3Frames:
503  return "audio/ac3";
504  case ContainerFormat::Asf:
505  return "video/x-ms-asf";
507  return "audio/flac";
508  case ContainerFormat::FlashVideo:
509  return "video/x-flv";
512  return "image/gif";
514  return "image/jpeg";
516  return "image/png";
518  return "audio/mpeg";
520  switch (mediaType) {
521  case MediaType::Audio:
522  return "audio/mp4";
523  default:
524  return "video/mp4";
525  }
527  switch (mediaType) {
528  case MediaType::Audio:
529  return "audio/ogg";
530  default:
531  return "video/ogg";
532  }
533  case ContainerFormat::Matroska:
534  switch (mediaType) {
535  case MediaType::Audio:
536  return "audio/x-matroska";
537  default:
538  return "video/x-matroska";
539  }
541  return "audio/midi";
543  return "application/x-bzip";
545  return "application/gzip";
547  return "application/x-lzh-compressed";
549  return "application/x-rar-compressed";
551  return "application/x-lzip";
553  return "video/quicktime";
554  case ContainerFormat::Zip:
555  return "application/zip";
557  return "application/x-7z-compressed";
558  case ContainerFormat::Xz:
559  return "application/x-xz";
561  return "image/bmp";
563  return "image/vnd.microsoft.icon";
564  default:
565  return "";
566  }
567 }
568 
572 TagTargetLevel containerTargetLevel(ContainerFormat containerFormat, std::uint64_t targetLevelValue)
573 {
574  switch (containerFormat) {
575  case ContainerFormat::Matroska:
576  case ContainerFormat::Webm:
577  return matroskaTagTargetLevel(targetLevelValue);
578  default:
579  return TagTargetLevel::Unspecified;
580  }
581 }
582 
586 std::uint64_t containerTargetLevelValue(ContainerFormat containerFormat, TagTargetLevel targetLevel)
587 {
588  switch (containerFormat) {
589  case ContainerFormat::Matroska:
590  case ContainerFormat::Webm:
591  return matroskaTagTargetLevelValue(targetLevel);
592  default:
593  return 0;
594  }
595 }
596 
597 } // namespace TagParser
TagParser::Sig16
Sig16
Holds 16-bit signatures.
Definition: signature.cpp:84
TagParser::Utf32Text
@ Utf32Text
Definition: signature.cpp:61
TagParser::VorbisCommentIds::version
constexpr TAG_PARSER_EXPORT const char * version()
Definition: vorbiscommentids.h:34
TagParser::TiffBigEndian
@ TiffBigEndian
Definition: signature.cpp:59
TagParser::Sig48
Sig48
Holds 48-bit signatures.
Definition: signature.cpp:34
TagParser::matroskaTagTargetLevel
constexpr TAG_PARSER_EXPORT TagTargetLevel matroskaTagTargetLevel(std::uint64_t targetLevelValue)
Returns the general TagTargetLevel for the Matroska specific targetLevelValue.
Definition: matroskatagid.h:479
TagParser::parseSignature
TAG_PARSER_EXPORT ContainerFormat parseSignature(const char *buffer, int bufferSize)
Parses the signature read from the specified buffer.
Definition: signature.cpp:104
TagParser::Asf2
@ Asf2
Definition: signature.cpp:18
TagParser::Gif89a
@ Gif89a
Definition: signature.cpp:36
TagParser::Sig56
Sig56
Holds 52-bit signatures.
Definition: signature.cpp:27
TagParser::Ogg
@ Ogg
Definition: signature.cpp:54
TagParser::Zip2
@ Zip2
Definition: signature.cpp:66
TagParser::MonkeysAudio
@ MonkeysAudio
Definition: signature.cpp:52
TagParser::Gzip
@ Gzip
Definition: signature.cpp:76
TagParser::Ebml
@ Ebml
Definition: signature.cpp:50
TagParser::containerFormatName
TAG_PARSER_EXPORT const char * containerFormatName(ContainerFormat containerFormat)
Returns the name of the specified container format as C-style string.
Definition: signature.cpp:373
TagParser::Gif87a
@ Gif87a
Definition: signature.cpp:35
TagParser::Elf
@ Elf
Definition: signature.cpp:46
TagParser::TagTargetLevel
TagTargetLevel
The TagTargetLevel enum specifies tag target levels.
Definition: tagtarget.h:16
TagParser::Jpeg
@ Jpeg
Definition: signature.cpp:88
TagParser
Contains all classes and functions of the TagInfo library.
Definition: aaccodebook.h:10
TagParser::Zip1
@ Zip1
Definition: signature.cpp:65
TagParser::Utf16Text
@ Utf16Text
Definition: signature.cpp:93
TagParser::FourccIds::Opus
@ Opus
Definition: mp4ids.h:346
TagParser::AdtsMask
@ AdtsMask
Definition: signature.cpp:87
TagParser::Zip3
@ Zip3
Definition: signature.cpp:67
TagParser::containerFormatAbbreviation
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:251
TagParser::Ar
@ Ar
Definition: signature.cpp:16
signature.h
TagParser::Ac3
@ Ac3
Definition: signature.cpp:85
TagParser::Id3v2
@ Id3v2
Definition: signature.cpp:77
TagParser::Bzip2
@ Bzip2
Definition: signature.cpp:74
TagParser::containerFormatSubversion
TAG_PARSER_EXPORT const char * containerFormatSubversion(ContainerFormat containerFormat)
Returns the subversion of the container format as C-style string.
Definition: signature.cpp:478
TagParser::Lzip
@ Lzip
Definition: signature.cpp:64
TagParser::MediaType
MediaType
The MediaType enum specifies the type of media data (audio, video, text, ...).
Definition: mediaformat.h:13
TagParser::QuickTime
@ QuickTime
Definition: signature.cpp:56
TagParser::YUV4Mpeg2
@ YUV4Mpeg2
Definition: signature.cpp:21
CppUtilities
Definition: abstractcontainer.h:15
TagParser::Sig32
Sig32
Holds 32-bit signatures.
Definition: signature.cpp:44
TagParser::Ivf
@ Ivf
Definition: signature.cpp:48
TagParser::Utf8Text
@ Utf8Text
Definition: signature.cpp:78
TagParser::JavaClassFile
@ JavaClassFile
Definition: signature.cpp:49
TagParser::ContainerFormat
ContainerFormat
Specifies the container format.
Definition: signature.h:17
TagParser::containerMimeType
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:499
TagParser::Dirac
@ Dirac
Definition: signature.cpp:45
TagParser::Sig24
Sig24
Holds 24-bit signatures.
Definition: signature.cpp:73
TagParser::Adts
@ Adts
Definition: signature.cpp:86
TagParser::Lha
@ Lha
Definition: signature.cpp:89
TagParser::MpegAudioFrames
@ MpegAudioFrames
Definition: signature.cpp:91
TagParser::WindowsIcon
@ WindowsIcon
Definition: signature.cpp:63
TagParser::matroskaTagTargetLevelValue
constexpr TAG_PARSER_EXPORT std::uint64_t matroskaTagTargetLevelValue(TagTargetLevel targetLevel)
Returns the Matroska specific target level value for the specified general targetLevel.
Definition: matroskatagid.h:487
TagParser::Xz
@ Xz
Definition: signature.cpp:38
TagParser::Flac
@ Flac
Definition: signature.cpp:47
TagParser::Flv
@ Flv
Definition: signature.cpp:75
matroskatagid.h
TagParser::Midi
@ Midi
Definition: signature.cpp:51
TagParser::Asf1
@ Asf1
Definition: signature.cpp:17
TagParser::containerTargetLevel
TAG_PARSER_EXPORT TagTargetLevel containerTargetLevel(ContainerFormat containerFormat, std::uint64_t targetLevelValue)
Returns the general TagTargetLevel for the specified container format and raw targetLevelValue.
Definition: signature.cpp:572
TagParser::PhotoshopDocument
@ PhotoshopDocument
Definition: signature.cpp:55
TagParser::Lzw
@ Lzw
Definition: signature.cpp:90
TagParser::RiffWave
@ RiffWave
Definition: signature.cpp:58
TagParser::MatroskaTrackType::Video
@ Video
Definition: matroskaid.h:405
TagParser::WindowsBitmap
@ WindowsBitmap
Definition: signature.cpp:94
TagParser::Png
@ Png
Definition: signature.cpp:19
TagParser::Riff
@ Riff
Definition: signature.cpp:57
TagParser::containerTargetLevelValue
TAG_PARSER_EXPORT std::uint64_t containerTargetLevelValue(ContainerFormat containerFormat, TagTargetLevel targetLevel)
Returns the raw target level value for the specified containerFormat and general targetLevel.
Definition: signature.cpp:586
TagParser::WavPack
@ WavPack
Definition: signature.cpp:62
TagParser::RiffAvi
@ RiffAvi
Definition: signature.cpp:20
TagParser::PortableExecutable
@ PortableExecutable
Definition: signature.cpp:92
TagParser::TiffLittleEndian
@ TiffLittleEndian
Definition: signature.cpp:60
TagParser::SevenZ
@ SevenZ
Definition: signature.cpp:37
TagParser::Rar
@ Rar
Definition: signature.cpp:28
TagParser::Sig64
Sig64
Holds 64-bit signatures.
Definition: signature.cpp:15
TagParser::MatroskaTrackType::Audio
@ Audio
Definition: matroskaid.h:405
TagParser::Mp4
@ Mp4
Definition: signature.cpp:53