diff --git a/README.md b/README.md index 65376ef..c777f24 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ or appending the tag. Usage of padding can be configured: However, it is also possible to force rewriting the entire file. -Taking advantage of padding is currently not supported when dealing with Ogg stream. +Taking advantage of padding is currently not supported when dealing with Ogg streams. ## Additional features The library can also display technical information such as the ID, format, language, bitrate, diff --git a/mediafileinfo.cpp b/mediafileinfo.cpp index 18b424d..b2b4264 100644 --- a/mediafileinfo.cpp +++ b/mediafileinfo.cpp @@ -181,7 +181,7 @@ startParsingSignature: goto startParsingSignature; } if(m_paddingSize) { - addNotification(NotificationType::Warning, ConversionUtilities::numberToString(m_paddingSize) + " zero-bytes skipped at the beginning of the file.", context); + addNotification(NotificationType::Warning, numberToString(m_paddingSize) + " zero-bytes skipped at the beginning of the file.", context); } // parse signature @@ -198,7 +198,7 @@ startParsingSignature: stream().read(buff, 5); // set the container offset to skip ID3v2 header - m_containerOffset += ConversionUtilities::toNormalInt(ConversionUtilities::BE::toUInt32(buff + 1)) + 10; + m_containerOffset += toNormalInt(BE::toUInt32(buff + 1)) + 10; if((*buff) & 0x10) { // footer present m_containerOffset += 10; @@ -208,17 +208,19 @@ startParsingSignature: goto startParsingSignature; case ContainerFormat::Mp4: { + // EBML/Matroska is handled using Mp4Container instance m_container = make_unique(*this, m_containerOffset); NotificationList notifications; try { static_cast(m_container.get())->validateElementStructure(notifications, &m_paddingSize); - } catch (Failure &) { + } catch(const Failure &) { m_containerParsingStatus = ParsingStatus::CriticalFailure; } addNotifications(notifications); break; } case ContainerFormat::Ebml: { + // EBML/Matroska is handled using MatroskaContainer instance auto container = make_unique(*this, m_containerOffset); NotificationList notifications; try { @@ -234,16 +236,28 @@ startParsingSignature: container->validateElementStructure(notifications, &m_paddingSize); container->validateIndex(); } - } catch(Failure &) { + } catch(const Failure &) { m_containerParsingStatus = ParsingStatus::CriticalFailure; } m_container = move(container); addNotifications(notifications); break; } case ContainerFormat::Ogg: + // Ogg is handled using OggContainer instance m_container = make_unique(*this, m_containerOffset); static_cast(m_container.get())->setChecksumValidationEnabled(m_forceFullParse); break; + case ContainerFormat::Unknown: + // container format is still unknown -> check for magic numbers at odd offsets + // -> check for tar (magic number at offset 0x101) + if(size() > 0x107) { + stream().seekg(0x101); + stream().read(buff, 6); + if(buff[0] == 0x75 && buff[1] == 0x73 && buff[2] == 0x74 && buff[3] == 0x61 && buff[4] == 0x72 && buff[5] == 0x00) { + m_containerFormat = ContainerFormat::Tar; + break; + } + } default: ; } @@ -306,10 +320,10 @@ void MediaFileInfo::parseTracks() m_singleTrack->parseHeader(); } m_tracksParsingStatus = ParsingStatus::Ok; - } catch (NotImplementedException &) { + } catch(const NotImplementedException &) { addNotification(NotificationType::Information, "Parsing tracks is not implemented for the container format of the file.", context); m_tracksParsingStatus = ParsingStatus::NotSupported; - } catch (Failure &) { + } catch(const Failure &) { addNotification(NotificationType::Critical, "Unable to parse tracks.", context); m_tracksParsingStatus = ParsingStatus::CriticalFailure; } @@ -349,9 +363,9 @@ void MediaFileInfo::parseTags() try { m_id3v1Tag->parse(stream(), true); m_actualExistingId3v1Tag = true; - } catch(NoDataFoundException &) { + } catch(const NoDataFoundException &) { m_id3v1Tag.reset(); // no ID3v1 tag found - } catch(Failure &) { + } catch(const Failure &) { m_tagsParsingStatus = ParsingStatus::CriticalFailure; addNotification(NotificationType::Critical, "Unable to parse ID3v1 tag.", context); } @@ -364,9 +378,9 @@ void MediaFileInfo::parseTags() try { id3v2Tag->parse(stream(), size() - offset); m_paddingSize += id3v2Tag->paddingSize(); - } catch(NoDataFoundException &) { + } catch(const NoDataFoundException &) { continue; - } catch(Failure &) { + } catch(const Failure &) { m_tagsParsingStatus = ParsingStatus::CriticalFailure; addNotification(NotificationType::Critical, "Unable to parse ID3v2 tag.", context); } @@ -375,13 +389,13 @@ void MediaFileInfo::parseTags() if(m_container) { try { m_container->parseTags(); - } catch (NotImplementedException &) { + } catch(const NotImplementedException &) { if(m_tagsParsingStatus == ParsingStatus::NotParsedYet) { // do not override parsing status from ID3 tags here m_tagsParsingStatus = ParsingStatus::NotSupported; } addNotification(NotificationType::Information, "Parsing tags is not implemented for the container format of the file.", context); - } catch (Failure &) { + } catch(const Failure &) { m_tagsParsingStatus = ParsingStatus::CriticalFailure; addNotification(NotificationType::Critical, "Unable to parse tag.", context); } diff --git a/signature.cpp b/signature.cpp index 579b932..7859d22 100644 --- a/signature.cpp +++ b/signature.cpp @@ -11,6 +11,7 @@ namespace Media { */ enum Sig64 : uint64 { + Ar = 0x213C617263683E0A, Asf1 = 0x3026B2758E66CF11ul, Asf2 = 0xA6D900AA0062CE6Cul, Png = 0x89504E470D0A1A0Aul, @@ -109,6 +110,8 @@ ContainerFormat parseSignature(const char *buffer, int bufferSize) } // return corresponding container format switch(sig) { // check 64-bit signatures + case Ar: + return ContainerFormat::Ar; case Asf1: return ContainerFormat::Asf; case Asf2: @@ -223,6 +226,7 @@ ContainerFormat parseSignature(const char *buffer, int bufferSize) const char *containerFormatAbbreviation(ContainerFormat containerFormat, MediaType mediaType, unsigned int version) { switch(containerFormat) { + case ContainerFormat::Ar: return "a"; case ContainerFormat::Asf: return "asf"; case ContainerFormat::Elf: return "elf"; case ContainerFormat::Gif87a: @@ -273,6 +277,7 @@ const char *containerFormatAbbreviation(ContainerFormat containerFormat, MediaTy case ContainerFormat::Riff: return "riff"; case ContainerFormat::RiffWave: return "wav"; case ContainerFormat::RiffAvi: return "avi"; + case ContainerFormat::Tar: return "tar"; case ContainerFormat::TiffBigEndian: case ContainerFormat::TiffLittleEndian: return "tiff"; case ContainerFormat::WindowsBitmap: return "bmp"; @@ -296,6 +301,8 @@ const char *containerFormatName(ContainerFormat containerFormat) switch(containerFormat) { case ContainerFormat::Adts: return "Audio Data Transport Stream"; + case ContainerFormat::Ar: + return "Archive (GNU ar)"; case ContainerFormat::Asf: return "Advanced Systems Format"; case ContainerFormat::Elf: @@ -337,6 +344,8 @@ const char *containerFormatName(ContainerFormat containerFormat) return "RIFF/WAVE"; case ContainerFormat::RiffAvi: return "RIFF/Audio Video Interleave"; + case ContainerFormat::Tar: + return "TAR archive"; case ContainerFormat::TiffBigEndian: case ContainerFormat::TiffLittleEndian: return "Tagged Image File Format"; @@ -356,10 +365,10 @@ const char *containerFormatName(ContainerFormat containerFormat) return "gzip compressed file"; case ContainerFormat::Lzip: return "lzip compressed file"; - case ContainerFormat::Zip: - return "ZIP archive"; case ContainerFormat::SevenZ: return "7z archive"; + case ContainerFormat::Zip: + return "ZIP archive"; default: return "unknown"; } diff --git a/signature.h b/signature.h index a7a5f10..1cb3e51 100644 --- a/signature.h +++ b/signature.h @@ -15,6 +15,7 @@ enum class ContainerFormat { Unknown, /**< unknown container format */ Adts, /** < Audio Data Transport Stream */ + Ar, /** < "GNU ar" archive */ Asf, /**< Advanced Systems Format */ Bzip2, /** bzip2 compressed file */ Elf, /**< Executable and Linkable Format */ @@ -39,6 +40,7 @@ enum class ContainerFormat Riff, /**< Resource Interchange File Format */ RiffWave, /**< WAVE (subset of RIFF) */ RiffAvi, /**< Audio Video Interleave (subset of RIFF) */ + Tar, /** < Tar archive */ TiffBigEndian, /**< Tagged Image File Format (big endian) */ TiffLittleEndian, /**< Tagged Image File Format (little endian) */ Utf16Text, /**< UTF-16 text */