Compare commits

...

6 Commits

Author SHA1 Message Date
Martchus 7a8d3d5b62 Improve documentation 2021-05-09 12:25:17 +02:00
Martchus 6d72a947df Fix typo 2021-05-09 12:22:15 +02:00
Martchus 90d0c1cce1 Consider 4:3 resolutions as well in Size::abbreviation()
So e.g. 960×720 is considered 720p (and not just 1280×720).
2021-05-09 12:21:00 +02:00
Martchus 455f5bcf4c Fix handling empty ID3v2 record date fields to avoid year "0001" in this case 2021-05-09 12:20:28 +02:00
Martchus 98f6b268a5 Fix reading empty ID3v1 fields 2021-05-09 12:20:28 +02:00
Martchus db4e1a480a Bump patch version 9.4.0 -> 9.4.1 2021-05-09 12:20:28 +02:00
6 changed files with 33 additions and 15 deletions

View File

@ -10,7 +10,7 @@ set(META_APP_URL "https://github.com/${META_APP_AUTHOR}/${META_PROJECT_NAME}")
set(META_APP_DESCRIPTION "C++ library for reading and writing MP4 (iTunes), ID3, Vorbis, Opus, FLAC and Matroska tags") set(META_APP_DESCRIPTION "C++ library for reading and writing MP4 (iTunes), ID3, Vorbis, Opus, FLAC and Matroska tags")
set(META_VERSION_MAJOR 9) set(META_VERSION_MAJOR 9)
set(META_VERSION_MINOR 4) set(META_VERSION_MINOR 4)
set(META_VERSION_PATCH 0) set(META_VERSION_PATCH 1)
set(META_REQUIRED_CPP_UNIT_VERSION 1.14.0) set(META_REQUIRED_CPP_UNIT_VERSION 1.14.0)
set(META_ADD_DEFAULT_CPP_UNIT_TEST_APPLICATION ON) set(META_ADD_DEFAULT_CPP_UNIT_TEST_APPLICATION ON)

View File

@ -22,7 +22,7 @@ class WaveAudioStream;
class Mp4Track; class Mp4Track;
/*! /*!
* \brief Specifies the track type. * \brief The TrackType enum specifies the underlying file type of a track and the concrete class of the track object.
*/ */
enum class TrackType { enum class TrackType {
Unspecified, /**< The track type is not specified. */ Unspecified, /**< The track type is not specified. */

View File

@ -283,10 +283,13 @@ void Id3v1Tag::ensureTextValuesAreProperlyEncoded()
void Id3v1Tag::readValue(TagValue &value, size_t maxLength, const char *buffer) void Id3v1Tag::readValue(TagValue &value, size_t maxLength, const char *buffer)
{ {
const char *end = buffer + maxLength - 1; const char *end = buffer + maxLength - 1;
while ((*end == 0x0 || *end == ' ') && end > buffer) { while ((*end == 0x0 || *end == ' ') && end >= buffer) {
--end; --end;
--maxLength; --maxLength;
} }
if (buffer == end) {
return;
}
if (maxLength >= 3 && BE::toUInt24(buffer) == 0x00EFBBBF) { if (maxLength >= 3 && BE::toUInt24(buffer) == 0x00EFBBBF) {
value.assignData(buffer + 3, maxLength - 3, TagDataType::Text, TagTextEncoding::Utf8); value.assignData(buffer + 3, maxLength - 3, TagDataType::Text, TagTextEncoding::Utf8);
} else { } else {

View File

@ -89,7 +89,7 @@ std::vector<const TagValue *> Id3v2Tag::internallyGetValues(const IdentifierType
/*! /*!
* \brief Uses default implementation for non-text frames and applies special handling to text frames. * \brief Uses default implementation for non-text frames and applies special handling to text frames.
* *
* - Ensure text frames are unique * - Ensure text frames are unique.
* - Allow to store multiple values inside the same text frame. * - Allow to store multiple values inside the same text frame.
*/ */
bool Id3v2Tag::internallySetValues(const IdentifierType &id, const std::vector<TagValue> &values) bool Id3v2Tag::internallySetValues(const IdentifierType &id, const std::vector<TagValue> &values)
@ -369,8 +369,10 @@ void Id3v2Tag::convertOldRecordDateFields(const std::string &diagContext, Diagno
} }
// parse values of lYear/lRecordingDates/lDate/lTime/sYear/sRecordingDates/sDate/sTime fields // parse values of lYear/lRecordingDates/lDate/lTime/sYear/sRecordingDates/sDate/sTime fields
bool hasAnyValue = false;
int year = 1, month = 1, day = 1, hour = 0, minute = 0; int year = 1, month = 1, day = 1, hour = 0, minute = 0;
if (const auto &v = value(Id3v2FrameIds::lYear)) { if (const auto &v = value(Id3v2FrameIds::lYear)) {
hasAnyValue = true;
try { try {
year = v.toInteger(); year = v.toInteger();
} catch (const ConversionException &e) { } catch (const ConversionException &e) {
@ -378,6 +380,7 @@ void Id3v2Tag::convertOldRecordDateFields(const std::string &diagContext, Diagno
} }
} }
if (const auto &v = value(Id3v2FrameIds::lDate)) { if (const auto &v = value(Id3v2FrameIds::lDate)) {
hasAnyValue = true;
try { try {
auto str = v.toString(); auto str = v.toString();
if (str.size() != 4) { if (str.size() != 4) {
@ -390,6 +393,7 @@ void Id3v2Tag::convertOldRecordDateFields(const std::string &diagContext, Diagno
} }
} }
if (const auto &v = value(Id3v2FrameIds::lTime)) { if (const auto &v = value(Id3v2FrameIds::lTime)) {
hasAnyValue = true;
try { try {
auto str = v.toString(); auto str = v.toString();
if (str.size() != 4) { if (str.size() != 4) {
@ -403,6 +407,9 @@ void Id3v2Tag::convertOldRecordDateFields(const std::string &diagContext, Diagno
} }
// set the field values as DateTime // set the field values as DateTime
if (!hasAnyValue) {
return;
}
try { try {
setValue(Id3v2FrameIds::lRecordingTime, DateTime::fromDateAndTime(year, month, day, hour, minute)); setValue(Id3v2FrameIds::lRecordingTime, DateTime::fromDateAndTime(year, month, day, hour, minute));
} catch (const ConversionException &e) { } catch (const ConversionException &e) {

View File

@ -105,7 +105,7 @@ void EbmlElement::internalParse(Diagnostics &diag)
// check whether this element is actually a sibling of one of its parents rather then a child // check whether this element is actually a sibling of one of its parents rather then a child
// (might be the case if the parent's size is unknown and hence assumed to be the max file size) // (might be the case if the parent's size is unknown and hence assumed to be the max file size)
if (m_parent && m_parent->m_sizeUnknown) { if (m_parent && m_parent->m_sizeUnknown) {
// check at which level in the hierarchy the element is supposed to occour using its ID // check at which level in the hierarchy the element is supposed to occur using its ID
// (the only chance to find out whether the element belongs higher up in the hierarchy) // (the only chance to find out whether the element belongs higher up in the hierarchy)
const MatroskaElementLevel supposedLevel = matroskaIdLevel(m_id); const MatroskaElementLevel supposedLevel = matroskaIdLevel(m_id);
const std::uint8_t actualLevel = level(); const std::uint8_t actualLevel = level();

View File

@ -2,27 +2,35 @@
namespace TagParser { namespace TagParser {
/// \cond
constexpr Size fromHeightAndAspectRatio(std::uint32_t height, std::uint32_t numerator = 4, std::uint32_t denominator = 3)
{
return Size(height * numerator / denominator, height);
}
/// \endcond
/*! /*!
* \brief Returns an abbreviation for the current instance, eg. 720p for sizes greather than 1280×720 * \brief Returns an abbreviation for the current instance, eg. 720p for sizes greather than 960×720
* and 1080p for sizes greather than 1920×1080. * and 1080p for sizes greather than 1440×1080.
* \remarks The width thresolds are for 4:3 resolutions so both, 4:3 and 16:9 "720p" is considered as such.
*/ */
const char *Size::abbreviation() const const char *Size::abbreviation() const
{ {
if (*this >= Size(7680, 4320)) { if (*this >= fromHeightAndAspectRatio(4320)) {
return "8k"; return "8k";
} else if (*this >= Size(3840, 2160)) { } else if (*this >= fromHeightAndAspectRatio(2160)) {
return "4k"; return "4k";
} else if (*this >= Size(1920, 1080)) { } else if (*this >= fromHeightAndAspectRatio(1080)) {
return "1080p"; return "1080p";
} else if (*this >= Size(1280, 720)) { } else if (*this >= fromHeightAndAspectRatio(720)) {
return "720p"; return "720p";
} else if (*this >= Size(704, 576)) { } else if (*this >= fromHeightAndAspectRatio(576)) {
return "576p"; return "576p";
} else if (*this >= Size(640, 480)) { } else if (*this >= fromHeightAndAspectRatio(480)) {
return "480p"; return "480p";
} else if (*this >= Size(480, 320)) { } else if (*this >= fromHeightAndAspectRatio(320)) {
return "320p"; return "320p";
} else if (*this >= Size(320, 240)) { } else if (*this >= fromHeightAndAspectRatio(240)) {
return "240p"; return "240p";
} }
return "<240p"; return "<240p";