recognize ar and tar archives by magic number
This commit is contained in:
parent
73ff80c46a
commit
fa129cf487
|
@ -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,
|
||||
|
|
|
@ -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<Mp4Container>(*this, m_containerOffset);
|
||||
NotificationList notifications;
|
||||
try {
|
||||
static_cast<Mp4Container *>(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<MatroskaContainer>(*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<OggContainer>(*this, m_containerOffset);
|
||||
static_cast<OggContainer *>(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);
|
||||
}
|
||||
|
|
|
@ -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";
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Reference in New Issue