From a3352fd899c07c30b52855306159fc56a4c92aa3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Lalinsk=C3=BD?= Date: Mon, 15 Apr 2013 10:12:02 +0200 Subject: [PATCH] Use the first instance of a MP4 atom (#126) When a file contains multiple MP4 atoms with the same name, use the first one. This is consistent with iTunes and other popular software. --- taglib/mp4/mp4tag.cpp | 33 +++++++++++++++++++++------------ taglib/mp4/mp4tag.h | 2 ++ 2 files changed, 23 insertions(+), 12 deletions(-) diff --git a/taglib/mp4/mp4tag.cpp b/taglib/mp4/mp4tag.cpp index 17ab766f..3deb84b3 100644 --- a/taglib/mp4/mp4tag.cpp +++ b/taglib/mp4/mp4tag.cpp @@ -159,7 +159,7 @@ MP4::Tag::parseInt(MP4::Atom *atom, TagLib::File *file) { ByteVectorList data = parseData(atom, file); if(data.size()) { - d->items.insert(atom->name, (int)data[0].toShort()); + addItem(atom->name, (int)data[0].toShort()); } } @@ -168,7 +168,7 @@ MP4::Tag::parseUInt(MP4::Atom *atom, TagLib::File *file) { ByteVectorList data = parseData(atom, file); if(data.size()) { - d->items.insert(atom->name, data[0].toUInt()); + addItem(atom->name, data[0].toUInt()); } } @@ -177,7 +177,7 @@ MP4::Tag::parseLongLong(MP4::Atom *atom, TagLib::File *file) { ByteVectorList data = parseData(atom, file); if(data.size()) { - d->items.insert(atom->name, data[0].toLongLong()); + addItem(atom->name, data[0].toLongLong()); } } @@ -186,7 +186,7 @@ MP4::Tag::parseByte(MP4::Atom *atom, TagLib::File *file) { ByteVectorList data = parseData(atom, file); if(data.size()) { - d->items.insert(atom->name, (uchar)data[0].at(0)); + addItem(atom->name, (uchar)data[0].at(0)); } } @@ -196,8 +196,8 @@ MP4::Tag::parseGnre(MP4::Atom *atom, TagLib::File *file) ByteVectorList data = parseData(atom, file); if(data.size()) { int idx = (int)data[0].toShort(); - if(!d->items.contains("\251gen") && idx > 0) { - d->items.insert("\251gen", StringList(ID3v1::genre(idx - 1))); + if(idx > 0) { + addItem("\251gen", StringList(ID3v1::genre(idx - 1))); } } } @@ -209,7 +209,7 @@ MP4::Tag::parseIntPair(MP4::Atom *atom, TagLib::File *file) if(data.size()) { int a = data[0].mid(2, 2).toShort(); int b = data[0].mid(4, 2).toShort(); - d->items.insert(atom->name, MP4::Item(a, b)); + addItem(atom->name, MP4::Item(a, b)); } } @@ -219,7 +219,7 @@ MP4::Tag::parseBool(MP4::Atom *atom, TagLib::File *file) ByteVectorList data = parseData(atom, file); if(data.size()) { bool value = data[0].size() ? data[0][0] != '\0' : false; - d->items.insert(atom->name, value); + addItem(atom->name, value); } } @@ -232,7 +232,7 @@ MP4::Tag::parseText(MP4::Atom *atom, TagLib::File *file, int expectedFlags) for(unsigned int i = 0; i < data.size(); i++) { value.append(String(data[i], String::UTF8)); } - d->items.insert(atom->name, value); + addItem(atom->name, value); } } @@ -256,7 +256,7 @@ MP4::Tag::parseFreeForm(MP4::Atom *atom, TagLib::File *file) } Item item(value); item.setAtomDataType(type); - d->items.insert(name, item); + addItem(name, item); } else { ByteVectorList value; @@ -265,7 +265,7 @@ MP4::Tag::parseFreeForm(MP4::Atom *atom, TagLib::File *file) } Item item(value); item.setAtomDataType(type); - d->items.insert(name, item); + addItem(name, item); } } } @@ -294,7 +294,7 @@ MP4::Tag::parseCovr(MP4::Atom *atom, TagLib::File *file) pos += length; } if(value.size() > 0) - d->items.insert(atom->name, value); + addItem(atom->name, value); } ByteVector @@ -910,3 +910,12 @@ 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 + "\""); + } +} diff --git a/taglib/mp4/mp4tag.h b/taglib/mp4/mp4tag.h index 0e1d0676..48d71fcb 100644 --- a/taglib/mp4/mp4tag.h +++ b/taglib/mp4/mp4tag.h @@ -105,6 +105,8 @@ namespace TagLib { void saveNew(TagLib::ByteVector &data); void saveExisting(TagLib::ByteVector &data, AtomList &path); + void addItem(const String &name, const Item &value); + class TagPrivate; TagPrivate *d; };