Additional manual formatting to taglib sources

This commit is contained in:
Jonas Kvinge
2020-06-14 17:01:05 +02:00
parent 577b7d8ec8
commit ef34dce4dc
217 changed files with 7367 additions and 8204 deletions

View File

@@ -31,13 +31,10 @@
using namespace Strawberry_TagLib::TagLib;
const char *MP4::Atom::containers[11] = {
"moov", "udta", "mdia", "meta", "ilst",
"stbl", "minf", "moof", "traf", "trak",
"stsd"
};
const char *MP4::Atom::containers[11] = { "moov", "udta", "mdia", "meta", "ilst", "stbl", "minf", "moof", "traf", "trak", "stsd" };
MP4::Atom::Atom(File *file) {
children.setAutoDelete(true);
offset = file->tell();
@@ -100,14 +97,14 @@ MP4::Atom::Atom(File *file) {
}
file->seek(offset + length);
}
MP4::Atom::~Atom() {
}
MP4::Atom::~Atom() {}
MP4::Atom *
MP4::Atom::find(const char *name1, const char *name2, const char *name3, const char *name4) {
if (name1 == 0) {
MP4::Atom *MP4::Atom::find(const char *name1, const char *name2, const char *name3, const char *name4) {
if (!name1) {
return this;
}
for (AtomList::ConstIterator it = children.begin(); it != children.end(); ++it) {
@@ -116,10 +113,11 @@ MP4::Atom::find(const char *name1, const char *name2, const char *name3, const c
}
}
return nullptr;
}
MP4::AtomList
MP4::Atom::findall(const char *_name, bool recursive) {
MP4::AtomList MP4::Atom::findall(const char *_name, bool recursive) {
MP4::AtomList result;
for (AtomList::ConstIterator it = children.begin(); it != children.end(); ++it) {
if ((*it)->name == _name) {
@@ -130,11 +128,13 @@ MP4::Atom::findall(const char *_name, bool recursive) {
}
}
return result;
}
bool MP4::Atom::path(MP4::AtomList &path, const char *name1, const char *name2, const char *name3) {
path.append(this);
if (name1 == 0) {
if (!name1) {
return true;
}
for (AtomList::ConstIterator it = children.begin(); it != children.end(); ++it) {
@@ -143,9 +143,11 @@ bool MP4::Atom::path(MP4::AtomList &path, const char *name1, const char *name2,
}
}
return false;
}
MP4::Atoms::Atoms(File *file) {
atoms.setAutoDelete(true);
file->seek(0, File::End);
@@ -157,23 +159,24 @@ MP4::Atoms::Atoms(File *file) {
if (atom->length == 0)
break;
}
}
MP4::Atoms::~Atoms() {
}
MP4::Atoms::~Atoms() {}
MP4::Atom *MP4::Atoms::find(const char *name1, const char *name2, const char *name3, const char *name4) {
MP4::Atom *
MP4::Atoms::find(const char *name1, const char *name2, const char *name3, const char *name4) {
for (AtomList::ConstIterator it = atoms.begin(); it != atoms.end(); ++it) {
if ((*it)->name == name1) {
return (*it)->find(name2, name3, name4);
}
}
return nullptr;
}
MP4::AtomList
MP4::Atoms::path(const char *name1, const char *name2, const char *name3, const char *name4) {
MP4::AtomList MP4::Atoms::path(const char *name1, const char *name2, const char *name3, const char *name4) {
MP4::AtomList path;
for (AtomList::ConstIterator it = atoms.begin(); it != atoms.end(); ++it) {
if ((*it)->name == name1) {
@@ -184,4 +187,5 @@ MP4::Atoms::path(const char *name1, const char *name2, const char *name3, const
}
}
return path;
}

View File

@@ -35,7 +35,6 @@
namespace Strawberry_TagLib {
namespace TagLib {
namespace MP4 {
class Atom;
@@ -78,6 +77,7 @@ class Atom {
public:
Atom(File *file);
~Atom();
Atom *find(const char *name1, const char *name2 = 0, const char *name3 = 0, const char *name4 = 0);
bool path(AtomList &path, const char *name1, const char *name2 = 0, const char *name3 = 0);
AtomList findall(const char *name, bool recursive = false);
@@ -96,13 +96,13 @@ class Atoms {
public:
Atoms(File *file);
~Atoms();
Atom *find(const char *name1, const char *name2 = 0, const char *name3 = 0, const char *name4 = 0);
AtomList path(const char *name1, const char *name2 = 0, const char *name3 = 0, const char *name4 = 0);
AtomList atoms;
};
} // namespace MP4
} // namespace TagLib
} // namespace Strawberry_TagLib

View File

@@ -32,8 +32,7 @@ using namespace Strawberry_TagLib::TagLib;
class MP4::CoverArt::CoverArtPrivate : public RefCounter {
public:
CoverArtPrivate() : RefCounter(),
format(MP4::CoverArt::JPEG) {}
CoverArtPrivate() : RefCounter(), format(MP4::CoverArt::JPEG) {}
Format format;
ByteVector data;

View File

@@ -33,14 +33,13 @@
namespace Strawberry_TagLib {
namespace TagLib {
namespace MP4 {
class TAGLIB_EXPORT CoverArt {
public:
/*!
* This describes the image type.
*/
* This describes the image type.
*/
enum Format {
JPEG = TypeJPEG,
PNG = TypePNG,
@@ -55,13 +54,13 @@ class TAGLIB_EXPORT CoverArt {
CoverArt(const CoverArt &item);
/*!
* Copies the contents of \a item into this CoverArt.
*/
* Copies the contents of \a item into this CoverArt.
*/
CoverArt &operator=(const CoverArt &item);
/*!
* Exchanges the content of the CoverArt by the content of \a item.
*/
* Exchanges the content of the CoverArt by the content of \a item.
*/
void swap(CoverArt &item);
//! Format of the image
@@ -78,7 +77,6 @@ class TAGLIB_EXPORT CoverArt {
typedef List<CoverArt> CoverArtList;
} // namespace MP4
} // namespace TagLib
} // namespace Strawberry_TagLib

View File

@@ -36,6 +36,7 @@ using namespace Strawberry_TagLib::TagLib;
namespace {
bool checkValid(const MP4::AtomList &list) {
for (MP4::AtomList::ConstIterator it = list.begin(); it != list.end(); ++it) {
if ((*it)->length == 0)
@@ -46,14 +47,13 @@ bool checkValid(const MP4::AtomList &list) {
}
return true;
}
} // namespace
class MP4::File::FilePrivate {
public:
FilePrivate() : tag(0),
atoms(0),
properties(0) {}
FilePrivate() : tag(nullptr), atoms(nullptr), properties(nullptr) {}
~FilePrivate() {
delete atoms;
@@ -71,26 +71,30 @@ class MP4::File::FilePrivate {
////////////////////////////////////////////////////////////////////////////////
bool MP4::File::isSupported(IOStream *stream) {
// An MP4 file has to have an "ftyp" box first.
const ByteVector id = Utils::readHeader(stream, 8, false);
return id.containsAt("ftyp", 4);
}
////////////////////////////////////////////////////////////////////////////////
// public members
////////////////////////////////////////////////////////////////////////////////
MP4::File::File(FileName file, bool readProperties, AudioProperties::ReadStyle) : Strawberry_TagLib::TagLib::File(file),
d(new FilePrivate()) {
MP4::File::File(FileName file, bool readProperties, AudioProperties::ReadStyle) : Strawberry_TagLib::TagLib::File(file), d(new FilePrivate()) {
if (isOpen())
read(readProperties);
}
MP4::File::File(IOStream *stream, bool readProperties, AudioProperties::ReadStyle) : Strawberry_TagLib::TagLib::File(stream),
d(new FilePrivate()) {
MP4::File::File(IOStream *stream, bool readProperties, AudioProperties::ReadStyle) : Strawberry_TagLib::TagLib::File(stream), d(new FilePrivate()) {
if (isOpen())
read(readProperties);
}
MP4::File::~File() {
@@ -120,6 +124,7 @@ MP4::File::audioProperties() const {
}
void MP4::File::read(bool readProperties) {
if (!isValid())
return;
@@ -139,9 +144,11 @@ void MP4::File::read(bool readProperties) {
if (readProperties) {
d->properties = new Properties(this, d->atoms);
}
}
bool MP4::File::save() {
if (readOnly()) {
debug("MP4::File::save() -- File is read only.");
return false;
@@ -153,8 +160,9 @@ bool MP4::File::save() {
}
return d->tag->save();
}
bool MP4::File::hasMP4Tag() const {
return (d->atoms->find("moov", "udta", "meta", "ilst") != 0);
return (d->atoms->find("moov", "udta", "meta", "ilst") != nullptr);
}

View File

@@ -41,92 +41,85 @@ namespace MP4 {
class Atoms;
/*!
* This implements and provides an interface for MP4 files to the
* TagLib::Tag and TagLib::AudioProperties interfaces by way of implementing
* the abstract TagLib::File API as well as providing some additional
* information specific to MP4 files.
*/
* This implements and provides an interface for MP4 files to the
* TagLib::Tag and TagLib::AudioProperties interfaces by way of implementing
* the abstract TagLib::File API as well as providing some additional
* information specific to MP4 files.
*/
class TAGLIB_EXPORT File : public Strawberry_TagLib::TagLib::File {
public:
/*!
* Constructs an MP4 file from \a file. If \a readProperties is true the
* file's audio properties will also be read.
*
* \note In the current implementation, \a propertiesStyle is ignored.
*/
File(FileName file, bool readProperties = true,
Properties::ReadStyle audioPropertiesStyle = Properties::Average);
* Constructs an MP4 file from \a file.
* If \a readProperties is true the file's audio properties will also be read.
*
* \note In the current implementation, \a propertiesStyle is ignored.
*/
File(FileName file, bool readProperties = true, Properties::ReadStyle audioPropertiesStyle = Properties::Average);
/*!
* Constructs an MP4 file from \a stream. If \a readProperties is true the
* file's audio properties will also be read.
*
* \note TagLib will *not* take ownership of the stream, the caller is
* responsible for deleting it after the File object.
*
* \note In the current implementation, \a propertiesStyle is ignored.
*/
* Constructs an MP4 file from \a stream.
* If \a readProperties is true the file's audio properties will also be read.
*
* \note TagLib will *not* take ownership of the stream, the caller is
* responsible for deleting it after the File object.
*
* \note In the current implementation, \a propertiesStyle is ignored.
*/
File(IOStream *stream, bool readProperties = true,
Properties::ReadStyle audioPropertiesStyle = Properties::Average);
/*!
* Destroys this instance of the File.
*/
* Destroys this instance of the File.
*/
virtual ~File();
/*!
* Returns a pointer to the MP4 tag of the file.
*
* MP4::Tag implements the tag interface, so this serves as the
* reimplementation of TagLib::File::tag().
*
* \note The Tag <b>is still</b> owned by the MP4::File and should not be
* deleted by the user. It will be deleted when the file (object) is
* destroyed.
*/
* Returns a pointer to the MP4 tag of the file.
*
* MP4::Tag implements the tag interface, so this serves as the reimplementation of TagLib::File::tag().
*
* \note The Tag <b>is still</b> owned by the MP4::File and should not be deleted by the user.
* It will be deleted when the file (object) is destroyed.
*/
Tag *tag() const;
/*!
* Implements the unified property interface -- export function.
*/
* Implements the unified property interface -- export function.
*/
PropertyMap properties() const;
/*!
* Removes unsupported properties. Forwards to the actual Tag's
* removeUnsupportedProperties() function.
*/
* Removes unsupported properties. Forwards to the actual Tag's removeUnsupportedProperties() function.
*/
void removeUnsupportedProperties(const StringList &properties);
/*!
* Implements the unified property interface -- import function.
*/
* Implements the unified property interface -- import function.
*/
PropertyMap setProperties(const PropertyMap &);
/*!
* Returns the MP4 audio properties for this file.
*/
* Returns the MP4 audio properties for this file.
*/
Properties *audioProperties() const;
/*!
* Save the file.
*
* This returns true if the save was successful.
*/
* Save the file.
*
* This returns true if the save was successful.
*/
bool save();
/*!
* Returns whether or not the file on disk actually has an MP4 tag, or the
* file has a Metadata Item List (ilst) atom.
*/
* Returns whether or not the file on disk actually has an MP4 tag, or the file has a Metadata Item List (ilst) atom.
*/
bool hasMP4Tag() const;
/*!
* Returns whether or not the given \a stream can be opened as an ASF
* file.
*
* \note This method is designed to do a quick check. The result may
* not necessarily be correct.
*/
* Returns whether or not the given \a stream can be opened as an ASF file.
*
* \note This method is designed to do a quick check. The result may not necessarily be correct.
*/
static bool isSupported(IOStream *stream);
private:
@@ -137,7 +130,6 @@ class TAGLIB_EXPORT File : public Strawberry_TagLib::TagLib::File {
};
} // namespace MP4
} // namespace TagLib
} // namespace Strawberry_TagLib

View File

@@ -32,9 +32,7 @@ using namespace Strawberry_TagLib::TagLib;
class MP4::Item::ItemPrivate : public RefCounter {
public:
ItemPrivate() : RefCounter(),
valid(true),
atomDataType(TypeUndefined) {}
ItemPrivate() : RefCounter(), valid(true), atomDataType(TypeUndefined) {}
bool valid;
AtomDataType atomDataType;
@@ -59,8 +57,7 @@ MP4::Item::Item(const Item &item) : d(item.d) {
d->ref();
}
MP4::Item &
MP4::Item::operator=(const Item &item) {
MP4::Item &MP4::Item::operator=(const Item &item) {
Item(item).swap(*this);
return *this;
}
@@ -129,38 +126,31 @@ int MP4::Item::toInt() const {
return d->m_int;
}
unsigned char
MP4::Item::toByte() const {
unsigned char MP4::Item::toByte() const {
return d->m_byte;
}
unsigned int
MP4::Item::toUInt() const {
unsigned int MP4::Item::toUInt() const {
return d->m_uint;
}
long long
MP4::Item::toLongLong() const {
long long MP4::Item::toLongLong() const {
return d->m_longlong;
}
MP4::Item::IntPair
MP4::Item::toIntPair() const {
MP4::Item::IntPair MP4::Item::toIntPair() const {
return d->m_intPair;
}
StringList
MP4::Item::toStringList() const {
StringList MP4::Item::toStringList() const {
return d->m_stringList;
}
ByteVectorList
MP4::Item::toByteVectorList() const {
ByteVectorList MP4::Item::toByteVectorList() const {
return d->m_byteVectorList;
}
MP4::CoverArtList
MP4::Item::toCoverArtList() const {
MP4::CoverArtList MP4::Item::toCoverArtList() const {
return d->m_coverArtList;
}

View File

@@ -32,7 +32,6 @@
namespace Strawberry_TagLib {
namespace TagLib {
namespace MP4 {
class TAGLIB_EXPORT Item {
@@ -45,13 +44,13 @@ class TAGLIB_EXPORT Item {
Item(const Item &item);
/*!
* Copies the contents of \a item into this Item.
*/
* Copies the contents of \a item into this Item.
*/
Item &operator=(const Item &item);
/*!
* Exchanges the content of the Item by the content of \a item.
*/
* Exchanges the content of the Item by the content of \a item.
*/
void swap(Item &item);
~Item();
@@ -87,7 +86,6 @@ class TAGLIB_EXPORT Item {
};
} // namespace MP4
} // namespace TagLib
} // namespace Strawberry_TagLib

View File

@@ -54,8 +54,7 @@ class MP4::Properties::PropertiesPrivate {
// public members
////////////////////////////////////////////////////////////////////////////////
MP4::Properties::Properties(File *file, MP4::Atoms *atoms, ReadStyle style) : AudioProperties(style),
d(new PropertiesPrivate()) {
MP4::Properties::Properties(File *file, MP4::Atoms *atoms, ReadStyle style) : AudioProperties(style), d(new PropertiesPrivate()) {
read(file, atoms);
}
@@ -71,10 +70,6 @@ int MP4::Properties::sampleRate() const {
return d->sampleRate;
}
int MP4::Properties::length() const {
return lengthInSeconds();
}
int MP4::Properties::lengthInSeconds() const {
return d->length / 1000;
}
@@ -105,13 +100,14 @@ MP4::Properties::codec() const {
////////////////////////////////////////////////////////////////////////////////
void MP4::Properties::read(File *file, Atoms *atoms) {
MP4::Atom *moov = atoms->find("moov");
if (!moov) {
debug("MP4: Atom 'moov' not found");
return;
}
MP4::Atom *trak = 0;
MP4::Atom *trak = nullptr;
ByteVector data;
const MP4::AtomList trakList = moov->findall("trak");
@@ -127,7 +123,7 @@ void MP4::Properties::read(File *file, Atoms *atoms) {
if (data.containsAt("soun", 16)) {
break;
}
trak = 0;
trak = nullptr;
}
if (!trak) {
debug("MP4: No audio tracks");
@@ -207,4 +203,5 @@ void MP4::Properties::read(File *file, Atoms *atoms) {
if (drms) {
d->encrypted = true;
}
}

View File

@@ -31,7 +31,6 @@
namespace Strawberry_TagLib {
namespace TagLib {
namespace MP4 {
class Atoms;
@@ -50,60 +49,49 @@ class TAGLIB_EXPORT Properties : public AudioProperties {
virtual ~Properties();
/*!
* Returns the length of the file in seconds. The length is rounded down to
* the nearest whole second.
*
* \note This method is just an alias of lengthInSeconds().
*
* \deprecated
*/
TAGLIB_DEPRECATED virtual int length() const;
/*!
* Returns the length of the file in seconds. The length is rounded down to
* the nearest whole second.
*
* \see lengthInMilliseconds()
*/
* Returns the length of the file in seconds. The length is rounded down to the nearest whole second.
*
* \see lengthInMilliseconds()
*/
// BIC: make virtual
int lengthInSeconds() const;
/*!
* Returns the length of the file in milliseconds.
*
* \see lengthInSeconds()
*/
* Returns the length of the file in milliseconds.
*
* \see lengthInSeconds()
*/
// BIC: make virtual
int lengthInMilliseconds() const;
/*!
* Returns the average bit rate of the file in kb/s.
*/
* Returns the average bit rate of the file in kb/s.
*/
virtual int bitrate() const;
/*!
* Returns the sample rate in Hz.
*/
* Returns the sample rate in Hz.
*/
virtual int sampleRate() const;
/*!
* Returns the number of audio channels.
*/
* Returns the number of audio channels.
*/
virtual int channels() const;
/*!
* Returns the number of bits per audio sample.
*/
* Returns the number of bits per audio sample.
*/
virtual int bitsPerSample() const;
/*!
* Returns whether or not the file is encrypted.
*/
* Returns whether or not the file is encrypted.
*/
bool isEncrypted() const;
/*!
* Returns the codec used in the file.
*/
* Returns the codec used in the file.
*/
Codec codec() const;
private:
@@ -114,7 +102,6 @@ class TAGLIB_EXPORT Properties : public AudioProperties {
};
} // namespace MP4
} // namespace TagLib
} // namespace Strawberry_TagLib

View File

@@ -34,18 +34,17 @@ using namespace Strawberry_TagLib::TagLib;
class MP4::Tag::TagPrivate {
public:
TagPrivate() : file(0),
atoms(0) {}
TagPrivate() : file(nullptr), atoms(nullptr) {}
Strawberry_TagLib::TagLib::File *file;
Atoms *atoms;
ItemMap items;
};
MP4::Tag::Tag() : d(new TagPrivate()) {
}
MP4::Tag::Tag() : d(new TagPrivate()) {}
MP4::Tag::Tag(Strawberry_TagLib::TagLib::File *file, MP4::Atoms *atoms) : d(new TagPrivate()) {
d->file = file;
d->atoms = atoms;
@@ -113,8 +112,8 @@ MP4::Tag::~Tag() {
delete d;
}
MP4::AtomDataList
MP4::Tag::parseData2(const MP4::Atom *atom, int expectedFlags, bool freeForm) {
MP4::AtomDataList MP4::Tag::parseData2(const MP4::Atom *atom, int expectedFlags, bool freeForm) {
AtomDataList result;
ByteVector data = d->file->readBlock(atom->length - 8);
int i = 0;
@@ -152,47 +151,58 @@ MP4::Tag::parseData2(const MP4::Atom *atom, int expectedFlags, bool freeForm) {
i++;
}
return result;
}
ByteVectorList
MP4::Tag::parseData(const MP4::Atom *atom, int expectedFlags, bool freeForm) {
ByteVectorList MP4::Tag::parseData(const MP4::Atom *atom, int expectedFlags, bool freeForm) {
AtomDataList data = parseData2(atom, expectedFlags, freeForm);
ByteVectorList result;
for (AtomDataList::ConstIterator it = data.begin(); it != data.end(); ++it) {
result.append(it->data);
}
return result;
}
void MP4::Tag::parseInt(const MP4::Atom *atom) {
ByteVectorList data = parseData(atom);
if (!data.isEmpty()) {
addItem(atom->name, (int)data[0].toShort());
}
}
void MP4::Tag::parseUInt(const MP4::Atom *atom) {
ByteVectorList data = parseData(atom);
if (!data.isEmpty()) {
addItem(atom->name, data[0].toUInt());
}
}
void MP4::Tag::parseLongLong(const MP4::Atom *atom) {
ByteVectorList data = parseData(atom);
if (!data.isEmpty()) {
addItem(atom->name, data[0].toLongLong());
}
}
void MP4::Tag::parseByte(const MP4::Atom *atom) {
ByteVectorList data = parseData(atom);
if (!data.isEmpty()) {
addItem(atom->name, static_cast<unsigned char>(data[0].at(0)));
}
}
void MP4::Tag::parseGnre(const MP4::Atom *atom) {
ByteVectorList data = parseData(atom);
if (!data.isEmpty()) {
int idx = (int)data[0].toShort();
@@ -200,26 +210,32 @@ void MP4::Tag::parseGnre(const MP4::Atom *atom) {
addItem("\251gen", StringList(ID3v1::genre(idx - 1)));
}
}
}
void MP4::Tag::parseIntPair(const MP4::Atom *atom) {
ByteVectorList data = parseData(atom);
if (!data.isEmpty()) {
const int a = data[0].toShort(2U);
const int b = data[0].toShort(4U);
addItem(atom->name, MP4::Item(a, b));
}
}
void MP4::Tag::parseBool(const MP4::Atom *atom) {
ByteVectorList data = parseData(atom);
if (!data.isEmpty()) {
bool value = data[0].size() ? data[0][0] != '\0' : false;
addItem(atom->name, value);
}
}
void MP4::Tag::parseText(const MP4::Atom *atom, int expectedFlags) {
ByteVectorList data = parseData(atom, expectedFlags);
if (!data.isEmpty()) {
StringList value;
@@ -228,9 +244,11 @@ void MP4::Tag::parseText(const MP4::Atom *atom, int expectedFlags) {
}
addItem(atom->name, value);
}
}
void MP4::Tag::parseFreeForm(const MP4::Atom *atom) {
AtomDataList data = parseData2(atom, -1, true);
if (data.size() > 2) {
AtomDataList::ConstIterator itBegin = data.begin();
@@ -267,9 +285,11 @@ void MP4::Tag::parseFreeForm(const MP4::Atom *atom) {
addItem(name, item);
}
}
}
void MP4::Tag::parseCovr(const MP4::Atom *atom) {
MP4::CoverArtList value;
ByteVector data = d->file->readBlock(atom->length - 8);
unsigned int pos = 0;
@@ -299,106 +319,117 @@ void MP4::Tag::parseCovr(const MP4::Atom *atom) {
}
if (!value.isEmpty())
addItem(atom->name, value);
}
ByteVector
MP4::Tag::padIlst(const ByteVector &data, int length) const {
ByteVector MP4::Tag::padIlst(const ByteVector &data, int length) const {
if (length == -1) {
length = ((data.size() + 1023) & ~1023) - data.size();
}
return renderAtom("free", ByteVector(length, '\1'));
}
ByteVector
MP4::Tag::renderAtom(const ByteVector &name, const ByteVector &data) const {
ByteVector MP4::Tag::renderAtom(const ByteVector &name, const ByteVector &data) const {
return ByteVector::fromUInt(data.size() + 8) + name + data;
}
ByteVector
MP4::Tag::renderData(const ByteVector &name, int flags, const ByteVectorList &data) const {
ByteVector MP4::Tag::renderData(const ByteVector &name, int flags, const ByteVectorList &data) const {
ByteVector result;
for (ByteVectorList::ConstIterator it = data.begin(); it != data.end(); ++it) {
result.append(renderAtom("data", ByteVector::fromUInt(flags) + ByteVector(4, '\0') + *it));
}
return renderAtom(name, result);
}
ByteVector
MP4::Tag::renderBool(const ByteVector &name, const MP4::Item &item) const {
ByteVector MP4::Tag::renderBool(const ByteVector &name, const MP4::Item &item) const {
ByteVectorList data;
data.append(ByteVector(1, item.toBool() ? '\1' : '\0'));
return renderData(name, TypeInteger, data);
}
ByteVector
MP4::Tag::renderInt(const ByteVector &name, const MP4::Item &item) const {
ByteVector MP4::Tag::renderInt(const ByteVector &name, const MP4::Item &item) const {
ByteVectorList data;
data.append(ByteVector::fromShort(item.toInt()));
return renderData(name, TypeInteger, data);
}
ByteVector
MP4::Tag::renderUInt(const ByteVector &name, const MP4::Item &item) const {
ByteVector MP4::Tag::renderUInt(const ByteVector &name, const MP4::Item &item) const {
ByteVectorList data;
data.append(ByteVector::fromUInt(item.toUInt()));
return renderData(name, TypeInteger, data);
}
ByteVector
MP4::Tag::renderLongLong(const ByteVector &name, const MP4::Item &item) const {
ByteVector MP4::Tag::renderLongLong(const ByteVector &name, const MP4::Item &item) const {
ByteVectorList data;
data.append(ByteVector::fromLongLong(item.toLongLong()));
return renderData(name, TypeInteger, data);
}
ByteVector
MP4::Tag::renderByte(const ByteVector &name, const MP4::Item &item) const {
ByteVector MP4::Tag::renderByte(const ByteVector &name, const MP4::Item &item) const {
ByteVectorList data;
data.append(ByteVector(1, item.toByte()));
return renderData(name, TypeInteger, data);
}
ByteVector
MP4::Tag::renderIntPair(const ByteVector &name, const MP4::Item &item) const {
ByteVector MP4::Tag::renderIntPair(const ByteVector &name, const MP4::Item &item) const {
ByteVectorList data;
data.append(ByteVector(2, '\0') +
ByteVector::fromShort(item.toIntPair().first) +
ByteVector::fromShort(item.toIntPair().second) +
ByteVector(2, '\0'));
return renderData(name, TypeImplicit, data);
}
ByteVector
MP4::Tag::renderIntPairNoTrailing(const ByteVector &name, const MP4::Item &item) const {
ByteVector MP4::Tag::renderIntPairNoTrailing(const ByteVector &name, const MP4::Item &item) const {
ByteVectorList data;
data.append(ByteVector(2, '\0') +
ByteVector::fromShort(item.toIntPair().first) +
ByteVector::fromShort(item.toIntPair().second));
return renderData(name, TypeImplicit, data);
}
ByteVector
MP4::Tag::renderText(const ByteVector &name, const MP4::Item &item, int flags) const {
ByteVector MP4::Tag::renderText(const ByteVector &name, const MP4::Item &item, int flags) const {
ByteVectorList data;
StringList value = item.toStringList();
for (StringList::ConstIterator it = value.begin(); it != value.end(); ++it) {
data.append(it->data(String::UTF8));
}
return renderData(name, flags, data);
}
ByteVector
MP4::Tag::renderCovr(const ByteVector &name, const MP4::Item &item) const {
ByteVector MP4::Tag::renderCovr(const ByteVector &name, const MP4::Item &item) const {
ByteVector data;
MP4::CoverArtList value = item.toCoverArtList();
for (MP4::CoverArtList::ConstIterator it = value.begin(); it != value.end(); ++it) {
data.append(renderAtom("data", ByteVector::fromUInt(it->format()) + ByteVector(4, '\0') + it->data()));
}
return renderAtom(name, data);
}
ByteVector
MP4::Tag::renderFreeForm(const String &name, const MP4::Item &item) const {
ByteVector MP4::Tag::renderFreeForm(const String &name, const MP4::Item &item) const {
StringList header = StringList::split(name, ":");
if (header.size() != 3) {
debug("MP4: Invalid free-form item name \"" + name + "\"");
@@ -429,9 +460,11 @@ MP4::Tag::renderFreeForm(const String &name, const MP4::Item &item) const {
}
}
return renderAtom("----", data);
}
bool MP4::Tag::save() {
ByteVector data;
for (MP4::ItemMap::ConstIterator it = d->items.begin(); it != d->items.end(); ++it) {
const String name = it->first;
@@ -496,9 +529,11 @@ bool MP4::Tag::save() {
}
return true;
}
void MP4::Tag::updateParents(const AtomList &path, long delta, int ignore) {
if (static_cast<int>(path.size()) <= ignore)
return;
@@ -525,6 +560,7 @@ void MP4::Tag::updateParents(const AtomList &path, long delta, int ignore) {
}
void MP4::Tag::updateOffsets(long delta, long offset) {
MP4::Atom *moov = d->atoms->find("moov");
if (moov) {
MP4::AtomList stco = moov->findall("stco", true);
@@ -591,9 +627,11 @@ void MP4::Tag::updateOffsets(long delta, long offset) {
}
}
}
}
void MP4::Tag::saveNew(ByteVector data) {
data = renderAtom("meta", ByteVector(4, '\0') + renderAtom("hdlr", ByteVector(8, '\0') + ByteVector("mdirappl") + ByteVector(9, '\0')) + data + padIlst(data));
AtomList path = d->atoms->path("moov", "udta");
@@ -612,9 +650,11 @@ void MP4::Tag::saveNew(ByteVector data) {
d->file->seek(offset);
path.back()->children.prepend(new Atom(d->file));
}
void MP4::Tag::saveExisting(ByteVector data, const AtomList &path) {
AtomList::ConstIterator it = path.end();
MP4::Atom *ilst = *(--it);
@@ -660,52 +700,46 @@ void MP4::Tag::saveExisting(ByteVector data, const AtomList &path) {
updateParents(path, delta, 1);
updateOffsets(delta, offset);
}
}
String
MP4::Tag::title() const {
String MP4::Tag::title() const {
if (d->items.contains("\251nam"))
return d->items["\251nam"].toStringList().toString(", ");
return String();
}
String
MP4::Tag::artist() const {
String MP4::Tag::artist() const {
if (d->items.contains("\251ART"))
return d->items["\251ART"].toStringList().toString(", ");
return String();
}
String
MP4::Tag::album() const {
String MP4::Tag::album() const {
if (d->items.contains("\251alb"))
return d->items["\251alb"].toStringList().toString(", ");
return String();
}
String
MP4::Tag::comment() const {
String MP4::Tag::comment() const {
if (d->items.contains("\251cmt"))
return d->items["\251cmt"].toStringList().toString(", ");
return String();
}
String
MP4::Tag::genre() const {
String MP4::Tag::genre() const {
if (d->items.contains("\251gen"))
return d->items["\251gen"].toStringList().toString(", ");
return String();
}
unsigned int
MP4::Tag::year() const {
unsigned int MP4::Tag::year() const {
if (d->items.contains("\251day"))
return d->items["\251day"].toStringList().toString().toInt();
return 0;
}
unsigned int
MP4::Tag::track() const {
unsigned int MP4::Tag::track() const {
if (d->items.contains("trkn"))
return d->items["trkn"].toIntPair().first;
return 0;
@@ -732,31 +766,31 @@ void MP4::Tag::setGenre(const String &value) {
}
void MP4::Tag::setYear(unsigned int value) {
if (value == 0) {
d->items.erase("\251day");
}
else {
d->items["\251day"] = StringList(String::number(value));
}
}
void MP4::Tag::setTrack(unsigned int value) {
if (value == 0) {
d->items.erase("trkn");
}
else {
d->items["trkn"] = MP4::Item(value, 0);
}
}
bool MP4::Tag::isEmpty() const {
return d->items.isEmpty();
}
MP4::ItemMap &MP4::Tag::itemListMap() {
return d->items;
}
const MP4::ItemMap &MP4::Tag::itemMap() const {
return d->items;
}
@@ -835,16 +869,19 @@ const char *keyTranslation[][2] = {
const size_t keyTranslationSize = sizeof(keyTranslation) / sizeof(keyTranslation[0]);
String translateKey(const String &key) {
for (size_t i = 0; i < keyTranslationSize; ++i) {
if (key == keyTranslation[i][0])
return keyTranslation[i][1];
}
return String();
}
} // namespace
PropertyMap MP4::Tag::properties() const {
PropertyMap props;
for (MP4::ItemMap::ConstIterator it = d->items.begin(); it != d->items.end(); ++it) {
const String key = translateKey(it->first);
@@ -872,14 +909,18 @@ PropertyMap MP4::Tag::properties() const {
}
}
return props;
}
void MP4::Tag::removeUnsupportedProperties(const StringList &props) {
for (StringList::ConstIterator it = props.begin(); it != props.end(); ++it)
d->items.erase(*it);
}
PropertyMap MP4::Tag::setProperties(const PropertyMap &props) {
static Map<String, String> reverseKeyMap;
if (reverseKeyMap.isEmpty()) {
int numKeys = sizeof(keyTranslation) / sizeof(keyTranslation[0]);
@@ -928,13 +969,16 @@ PropertyMap MP4::Tag::setProperties(const PropertyMap &props) {
}
return ignoredProps;
}
void MP4::Tag::addItem(const String &name, const Item &value) {
if (!d->items.contains(name)) {
d->items.insert(name, value);
}
else {
debug("MP4: Ignoring duplicate atom \"" + name + "\"");
}
}

View File

@@ -37,13 +37,8 @@
namespace Strawberry_TagLib {
namespace TagLib {
namespace MP4 {
/*!
* \deprecated
*/
TAGLIB_DEPRECATED typedef Strawberry_TagLib::TagLib::Map<String, Item> ItemListMap;
typedef Strawberry_TagLib::TagLib::Map<String, Item> ItemMap;
class TAGLIB_EXPORT Tag : public Strawberry_TagLib::TagLib::Tag {
@@ -70,36 +65,29 @@ class TAGLIB_EXPORT Tag : public Strawberry_TagLib::TagLib::Tag {
virtual void setTrack(unsigned int value);
virtual bool isEmpty() const;
/*!
* \deprecated Use the item() and setItem() API instead
*/
TAGLIB_DEPRECATED ItemMap &itemListMap();
/*!
* Returns a string-keyed map of the MP4::Items for this tag.
*/
* Returns a string-keyed map of the MP4::Items for this tag.
*/
const ItemMap &itemMap() const;
/*!
* \return The item, if any, corresponding to \a key.
*/
* \return The item, if any, corresponding to \a key.
*/
Item item(const String &key) const;
/*!
* Sets the value of \a key to \a value, overwriting any previous value.
*/
* Sets the value of \a key to \a value, overwriting any previous value.
*/
void setItem(const String &key, const Item &value);
/*!
* Removes the entry with \a key from the tag, or does nothing if it does
* not exist.
*/
* Removes the entry with \a key from the tag, or does nothing if it does not exist.
*/
void removeItem(const String &key);
/*!
* \return True if the tag contains an entry for \a key.
*/
* \return True if the tag contains an entry for \a key.
*/
bool contains(const String &key) const;
PropertyMap properties() const;
@@ -107,10 +95,8 @@ class TAGLIB_EXPORT Tag : public Strawberry_TagLib::TagLib::Tag {
PropertyMap setProperties(const PropertyMap &properties);
private:
AtomDataList parseData2(const Atom *atom, int expectedFlags = -1,
bool freeForm = false);
ByteVectorList parseData(const Atom *atom, int expectedFlags = -1,
bool freeForm = false);
AtomDataList parseData2(const Atom *atom, int expectedFlags = -1, bool freeForm = false);
ByteVectorList parseData(const Atom *atom, int expectedFlags = -1, bool freeForm = false);
void parseText(const Atom *atom, int expectedFlags = 1);
void parseFreeForm(const Atom *atom);
void parseInt(const Atom *atom);
@@ -124,10 +110,8 @@ class TAGLIB_EXPORT Tag : public Strawberry_TagLib::TagLib::Tag {
ByteVector padIlst(const ByteVector &data, int length = -1) const;
ByteVector renderAtom(const ByteVector &name, const ByteVector &data) const;
ByteVector renderData(const ByteVector &name, int flags,
const ByteVectorList &data) const;
ByteVector renderText(const ByteVector &name, const Item &item,
int flags = TypeUTF8) const;
ByteVector renderData(const ByteVector &name, int flags, const ByteVectorList &data) const;
ByteVector renderText(const ByteVector &name, const Item &item, int flags = TypeUTF8) const;
ByteVector renderFreeForm(const String &name, const Item &item) const;
ByteVector renderBool(const ByteVector &name, const Item &item) const;
ByteVector renderInt(const ByteVector &name, const Item &item) const;
@@ -151,7 +135,6 @@ class TAGLIB_EXPORT Tag : public Strawberry_TagLib::TagLib::Tag {
};
} // namespace MP4
} // namespace TagLib
} // namespace Strawberry_TagLib