diff --git a/taglib/CMakeLists.txt b/taglib/CMakeLists.txt index ed84805b..6d8e483f 100644 --- a/taglib/CMakeLists.txt +++ b/taglib/CMakeLists.txt @@ -54,6 +54,8 @@ set(tag_HDRS toolkit/tfilestream.h toolkit/tmap.h toolkit/tmap.tcc + toolkit/tpicture.h + toolkit/tpicturemap.h toolkit/tpropertymap.h toolkit/trefcounter.h toolkit/tdebuglistener.h @@ -329,6 +331,8 @@ set(toolkit_SRCS toolkit/tfile.cpp toolkit/tfilestream.cpp toolkit/tdebug.cpp + toolkit/tpicture.cpp + toolkit/tpicturemap.cpp toolkit/tpropertymap.cpp toolkit/trefcounter.cpp toolkit/tdebuglistener.cpp diff --git a/taglib/ape/apetag.cpp b/taglib/ape/apetag.cpp index 1d0f62b3..1fe62b35 100644 --- a/taglib/ape/apetag.cpp +++ b/taglib/ape/apetag.cpp @@ -34,6 +34,7 @@ #include #include #include +#include #include #include "apetag.h" @@ -127,6 +128,11 @@ TagLib::uint APE::Tag::track() const return d->itemListMap["TRACK"].toString().toInt(); } +TagLib::PictureMap APE::Tag::pictures() const +{ + return PictureMap(); +} + void APE::Tag::setTitle(const String &s) { addValue("TITLE", s, true); @@ -168,18 +174,19 @@ void APE::Tag::setTrack(uint i) addValue("TRACK", String::number(i), true); } -namespace +void APE::Tag::setPictures(const PictureMap &l) { - // conversions of tag keys between what we use in PropertyMap and what's usual - // for APE tags - static const TagLib::uint keyConversionsSize = 5; //usual, APE - static const char *keyConversions[][2] = {{"TRACKNUMBER", "TRACK" }, - {"DATE", "YEAR" }, - {"ALBUMARTIST", "ALBUM ARTIST"}, - {"DISCNUMBER", "DISC" }, - {"REMIXER", "MIXARTIST" }}; } +// conversions of tag keys between what we use in PropertyMap and what's usual +// for APE tags +static const TagLib::uint keyConversionsSize = 5; //usual, APE +static const char *keyConversions[][2] = {{"TRACKNUMBER", "TRACK" }, + {"DATE", "YEAR" }, + {"ALBUMARTIST", "ALBUM ARTIST"}, + {"DISCNUMBER", "DISC" }, + {"REMIXER", "MIXARTIST" }}; + PropertyMap APE::Tag::properties() const { PropertyMap properties; diff --git a/taglib/ape/apetag.h b/taglib/ape/apetag.h index a39294ab..cad9a564 100644 --- a/taglib/ape/apetag.h +++ b/taglib/ape/apetag.h @@ -94,6 +94,7 @@ namespace TagLib { virtual String genre() const; virtual uint year() const; virtual uint track() const; + virtual PictureMap pictures() const; virtual void setTitle(const String &s); virtual void setArtist(const String &s); @@ -102,6 +103,7 @@ namespace TagLib { virtual void setGenre(const String &s); virtual void setYear(uint i); virtual void setTrack(uint i); + virtual void setPictures(const PictureMap &l); /*! * Implements the unified tag dictionary interface -- export function. diff --git a/taglib/asf/asftag.cpp b/taglib/asf/asftag.cpp index ea9141a3..4a3355a8 100644 --- a/taglib/asf/asftag.cpp +++ b/taglib/asf/asftag.cpp @@ -23,6 +23,7 @@ * http://www.mozilla.org/MPL/ * ***************************************************************************/ +#include #include #include "asftag.h" @@ -110,6 +111,11 @@ String ASF::Tag::genre() const return String(); } +PictureMap ASF::Tag::pictures() const +{ + return PictureMap(); +} + void ASF::Tag::setTitle(const String &value) { d->title = value; @@ -155,6 +161,10 @@ void ASF::Tag::setTrack(uint value) setAttribute("WM/TrackNumber", String::number(value)); } +void ASF::Tag::setPictures(const PictureMap &l) +{ +} + ASF::AttributeListMap& ASF::Tag::attributeListMap() { return d->attributeListMap; diff --git a/taglib/asf/asftag.h b/taglib/asf/asftag.h index 8f322b18..4fa06a22 100644 --- a/taglib/asf/asftag.h +++ b/taglib/asf/asftag.h @@ -98,6 +98,8 @@ namespace TagLib { */ virtual uint track() const; + virtual PictureMap pictures() const; + /*! * Sets the title to \a s. */ @@ -144,6 +146,8 @@ namespace TagLib { */ virtual void setTrack(uint i); + virtual void setPictures(const PictureMap &l); + /*! * Returns true if the tag does not contain any data. This should be * reimplemented in subclasses that provide more than the basic tagging diff --git a/taglib/ebml/matroska/ebmlmatroskafile.cpp b/taglib/ebml/matroska/ebmlmatroskafile.cpp index 397945fa..4a525907 100644 --- a/taglib/ebml/matroska/ebmlmatroskafile.cpp +++ b/taglib/ebml/matroska/ebmlmatroskafile.cpp @@ -26,6 +26,7 @@ #include "ebmlmatroskaconstants.h" #include "ebmlmatroskaaudio.h" +#include "tpicturemap.h" #include "tpropertymap.h" using namespace TagLib; @@ -41,25 +42,25 @@ public: Element *v = simpleTag->getChild(Constants::TagString); if(!n || !v) return false; - + name = n->getAsString(); value = v->getAsString(); return true; } - + FilePrivate(File *p_document) : tag(0), document(p_document) { // Just get the first segment, because "Typically a Matroska file is // composed of 1 segment." Element* elem = document->getDocumentRoot()->getChild(Constants::Segment); - + // We take the first tags element (there shouldn't be more), if there is // non such element, consider the file as not compatible. if(!elem || !(elem = elem->getChild(Constants::Tags))) { document->setValid(false); return; } - + // Load all Tag entries List entries = elem->getChildren(Constants::Tag); for(List::Iterator i = entries.begin(); i != entries.end(); ++i) { @@ -67,7 +68,7 @@ public: ulli ttvalue = 50; // 50 is default (see spec.) if(target && (target = target->getChild(Constants::TargetTypeValue))) ttvalue = target->getAsUnsigned(); - + // Load all SimpleTags PropertyMap tagEntries; List simpleTags = (*i)->getChildren(Constants::SimpleTag); @@ -78,11 +79,11 @@ public: continue; tagEntries.insert(name, StringList(value)); } - + tags.append(std::pair >(tagEntries, std::pair(*i, ttvalue))); } } - + // Creates Tag and AudioProperties. Late creation because both require a fully // functional FilePrivate (well AudioProperties doesn't...) void lateCreate() @@ -90,7 +91,7 @@ public: tag = new Tag(document); audio = new AudioProperties(document); } - + // Checks the EBML header and creates the FilePrivate. static FilePrivate *checkAndCreate(File *document) { @@ -103,19 +104,19 @@ public: return fp; } } - + return 0; } - + // The tags with their Element and TargetTypeValue List > > tags; - + // The tag Tag *tag; - + // The audio properties AudioProperties *audio; - + // The corresponding file. File *document; }; @@ -179,11 +180,11 @@ PropertyMap EBML::Matroska::File::setProperties(const PropertyMap &properties) if(best == d->tags.end() || best->second.second > i->second.second) best = i; } - + std::pair > replace(properties, best->second); d->tags.erase(best); d->tags.prepend(replace); - + return PropertyMap(); } @@ -196,42 +197,42 @@ bool EBML::Matroska::File::save() { if(readOnly()) return false; - + // C++11 features would be nice: for(auto &i : d->tags) { /* ... */ } // Well, here we just iterate each extracted element. for(List > >::Iterator i = d->tags.begin(); i != d->tags.end(); ++i) { - + for(PropertyMap::Iterator j = i->first.begin(); j != i->first.end(); ++j) { - + // No element? Create it! if(!i->second.first) { // Should be save, since we already checked, when creating the object. Element *container = d->document->getDocumentRoot() ->getChild(Constants::Segment)->getChild(Constants::Tags); - + // Create Targets container i->second.first = container->addElement(Constants::Tag); Element *target = i->second.first->addElement(Constants::Targets); - + if(i->second.second == Constants::MostCommonPartValue) target->addElement(Constants::TargetType, Constants::TRACK); else if(i->second.second == Constants::MostCommonGroupingValue) target->addElement(Constants::TargetType, Constants::ALBUM); - + target->addElement(Constants::TargetTypeValue, i->second.second); } - + // Find entries List simpleTags = i->second.first->getChildren(Constants::SimpleTag); StringList::Iterator str = j->second.begin(); List::Iterator k = simpleTags.begin(); for(; k != simpleTags.end(); ++k) { - + String name, value; if(!d->extractContent(*k, name, value)) continue; - + // Write entry from StringList if(name == j->first) { if(str == j->second.end()) { @@ -248,7 +249,7 @@ bool EBML::Matroska::File::save() } } } - + // If we didn't write the complete StringList, we have to write the rest. for(; str != j->second.end(); ++str) { Element *stag = i->second.first->addElement(Constants::SimpleTag); @@ -256,21 +257,21 @@ bool EBML::Matroska::File::save() stag->addElement(Constants::TagString, *str); } } - + // Finally, we have to find elements that are not in the PropertyMap and // remove them. List simpleTags = i->second.first->getChildren(Constants::SimpleTag); for(List::Iterator j = simpleTags.begin(); j != simpleTags.end(); ++j) { - + String name, value; if(!d->extractContent(*j, name, value)) continue; - + if(i->first.find(name) == i->first.end()){ i->second.first->removeChild(*j);} } } - + return true; } @@ -295,89 +296,89 @@ public: year(document->d->tags.end()), track(document->d->tags.end()) { - + for(List > >::Iterator i = document->d->tags.begin(); i != document->d->tags.end(); ++i) { - + // Just save it, if the title is more specific, or there is no title yet. if(i->first.find(Constants::TITLE) != i->first.end() && (title == document->d->tags.end() || title->second.second > i->second.second || i->second.second == Constants::MostCommonPartValue)) { - + title = i; } - + // Same goes for artist. if(i->first.find(Constants::ARTIST) != i->first.end() && (artist == document->d->tags.end() || artist->second.second > i->second.second || i->second.second == Constants::MostCommonPartValue)) { - + artist = i; } - + // Here, we also look for a title (the album title), but since we // specified the granularity, we have to search for it exactly. // Therefore it is possible, that title and album are the same (if only // the title of the album is given). if(i->first.find(Constants::TITLE) != i->first.end() && i->second.second == Constants::MostCommonGroupingValue) { - + album = i; } - + // Again the same as title and artist. if(i->first.find(Constants::COMMENT) != i->first.end() && (comment == document->d->tags.end() || comment->second.second > i->second.second || i->second.second == Constants::MostCommonPartValue)) { - + comment = i; } - + // Same goes for genre. if(i->first.find(Constants::GENRE) != i->first.end() && (genre == document->d->tags.end() || genre->second.second > i->second.second || i->second.second == Constants::MostCommonPartValue)) { - + genre = i; } - + // And year (in our case: DATE_REALEASE) if(i->first.find(Constants::DATE_RELEASE) != i->first.end() && (year == document->d->tags.end() || year->second.second > i->second.second || i->second.second == Constants::MostCommonPartValue)) { - + year = i; } - + // And track (in our case: PART_NUMBER) if(i->first.find(Constants::PART_NUMBER) != i->first.end() && (track == document->d->tags.end() || track->second.second > i->second.second || i->second.second == Constants::MostCommonPartValue)) { - + track = i; } } } - + // Searches for the Tag with given TargetTypeValue (returns the first one) List > >::Iterator find(ulli ttv) { for(List > >::Iterator i = document->d->tags.begin(); i != document->d->tags.end(); ++i) { - + if(i->second.second == ttv) return i; } return document->d->tags.end(); } - + // Updates the given information void update( List > >::Iterator t, @@ -387,19 +388,19 @@ public: { t->first.find(tagname)->second.front() = s; } - + // Inserts a tag with given information void insert(const String &tagname, const ulli ttv, const String &s) { for(List > >::Iterator i = document->d->tags.begin(); i != document->d->tags.end(); ++i) { - + if(i->second.second == ttv) { i->first.insert(tagname, StringList(s)); return; } } - + // Not found? Create new! PropertyMap pm; pm.insert(tagname, StringList(s)); @@ -409,10 +410,10 @@ public: ) ); } - + // The PropertyMap from the Matroska::File File *document; - + // Iterators to the tags. List > >::Iterator title; List > >::Iterator artist; @@ -461,6 +462,11 @@ String EBML::Matroska::File::Tag::album() const return String::null; } +PictureMap EBML::Matroska::File::Tag::pictures() const +{ + return PictureMap(); +} + String EBML::Matroska::File::Tag::comment() const { if(e->comment != e->document->d->tags.end()) @@ -517,6 +523,11 @@ void EBML::Matroska::File::Tag::setAlbum(const String &s) e->insert(Constants::TITLE, Constants::MostCommonGroupingValue, s); } +void EBML::Matroska::File::Tag::setPictures(const PictureMap& p ) +{ + (void)p; // avoid warning for unused variable +} + void EBML::Matroska::File::Tag::setComment(const String &s) { if(e->comment != e->document->d->tags.end()) diff --git a/taglib/ebml/matroska/ebmlmatroskafile.h b/taglib/ebml/matroska/ebmlmatroskafile.h index 5e57a751..09461e0f 100644 --- a/taglib/ebml/matroska/ebmlmatroskafile.h +++ b/taglib/ebml/matroska/ebmlmatroskafile.h @@ -30,12 +30,12 @@ #include "ebmlelement.h" namespace TagLib { - + namespace EBML { - + //! Implementation for reading Matroska tags. namespace Matroska { - + /*! * Implements the TagLib::File API and offers access to the tags of the * matroska file. @@ -45,22 +45,22 @@ namespace TagLib { public: //! Destroys the instance of the file. virtual ~File(); - + /*! * Constructs a Matroska File from a file name. */ File(FileName file); - + /*! * Constructs a Matroska File from a stream. */ File(IOStream *stream); - + /*! * Returns the pointer to a tag that allow access on common tags. */ virtual TagLib::Tag *tag() const; - + /*! * Exports the tags to a PropertyMap. Due to the diversity of the * Matroska format (e.g. multiple media streams in one file, each with @@ -68,26 +68,26 @@ namespace TagLib { * There are no unsupported tags. */ virtual PropertyMap properties() const; - + /*! * Sets the tags of the file to those specified in properties. The * returned PropertyMap is always empty. * Note: Only the best fitting tags are taken into account. */ virtual PropertyMap setProperties(const PropertyMap &properties); - + /*! * Returns a pointer to this file's audio properties. - * + * * I'm glad about not having a setAudioProperties method ;) */ virtual AudioProperties *audioProperties() const; - + /*! * Saves the file. Returns true on success. */ bool save(); - + /*! * Offers access to a few common tag entries. */ @@ -96,104 +96,116 @@ namespace TagLib { public: //! Destroys the tag. ~Tag(); - + /*! * Creates a new Tag for Matroska files. The given properties are gained * by the Matroska::File. */ Tag(File *document); - + /*! * Returns the track name; if no track name is present in the tag * String::null will be returned. */ virtual String title() const; - + /*! * Returns the artist name; if no artist name is present in the tag * String::null will be returned. */ virtual String artist() const; - + /*! * Returns the album name; if no album name is present in the tag * String::null will be returned. */ virtual String album() const; - + + /*! + * Returns a list of pictures; if no picture is present in the tag + * an empty PictureMap is returned + */ + virtual PictureMap pictures() const; + /*! * Returns the track comment; if no comment is present in the tag * String::null will be returned. */ virtual String comment() const; - + /*! * Returns the genre name; if no genre is present in the tag String::null * will be returned. */ virtual String genre() const; - + /*! * Returns the year; if there is no year set, this will return 0. */ virtual uint year() const; - + /*! * Returns the track number; if there is no track number set, this will * return 0. */ virtual uint track() const; - + /*! * Sets the title to s. If s is String::null then this value will be * cleared. */ virtual void setTitle(const String &s); - + /*! * Sets the artist to s. If s is String::null then this value will be * cleared. */ virtual void setArtist(const String &s); - + /*! * Sets the album to s. If s is String::null then this value will be * cleared. */ virtual void setAlbum(const String &s); - + + /*! + * Sets the picture map to p. If p is empty then this value will be + * cleared + */ + virtual void setPictures(const PictureMap& p ); + /*! * Sets the comment to s. If s is String::null then this value will be * cleared. */ virtual void setComment(const String &s); - + /*! * Sets the genre to s. If s is String::null then this value will be * cleared. */ virtual void setGenre(const String &s); - + /*! * Sets the year to i. If s is 0 then this value will be cleared. */ virtual void setYear(uint i); - + /*! * Sets the track to i. If s is 0 then this value will be cleared. */ virtual void setTrack(uint i); - + private: class TagPrivate; TagPrivate *e; }; - + private: class FilePrivate; FilePrivate *d; }; - + } } } diff --git a/taglib/mod/modtag.cpp b/taglib/mod/modtag.cpp index af98fb92..56c80ebf 100644 --- a/taglib/mod/modtag.cpp +++ b/taglib/mod/modtag.cpp @@ -22,6 +22,7 @@ #include "modtag.h" #include "tstringlist.h" #include "tpropertymap.h" +#include "tpicturemap.h" using namespace TagLib; using namespace Mod; @@ -83,6 +84,11 @@ TagLib::uint Mod::Tag::track() const return 0; } +TagLib::PictureMap Mod::Tag::pictures() const +{ + return PictureMap(); +} + String Mod::Tag::trackerName() const { return d->trackerName; @@ -118,6 +124,10 @@ void Mod::Tag::setTrack(uint) { } +void Mod::Tag::setPictures(const PictureMap &l) +{ +} + void Mod::Tag::setTrackerName(const String &trackerName) { d->trackerName = trackerName; diff --git a/taglib/mod/modtag.h b/taglib/mod/modtag.h index 5b660359..6e92082e 100644 --- a/taglib/mod/modtag.h +++ b/taglib/mod/modtag.h @@ -84,6 +84,8 @@ namespace TagLib { */ uint track() const; + PictureMap pictures() const; + /*! * Returns the name of the tracker used to create/edit the module file. * Only XM files store this tag to the file as such, for other formats @@ -147,6 +149,8 @@ namespace TagLib { */ void setTrack(uint track); + void setPictures(const PictureMap &l); + /*! * Sets the tracker name to \a trackerName. If \a trackerName is * String::null then this value will be cleared. diff --git a/taglib/mp4/mp4tag.cpp b/taglib/mp4/mp4tag.cpp index 50f1a0fb..770261c1 100644 --- a/taglib/mp4/mp4tag.cpp +++ b/taglib/mp4/mp4tag.cpp @@ -25,6 +25,7 @@ #include #include +#include #include #include "mp4atom.h" #include "mp4tag.h" @@ -737,6 +738,12 @@ MP4::Tag::track() const return 0; } +PictureMap +MP4::Tag::pictures() const +{ + return PictureMap(); +} + void MP4::Tag::setTitle(const String &value) { @@ -779,6 +786,11 @@ MP4::Tag::setTrack(uint value) d->items["trkn"] = MP4::Item(value, 0); } +void +MP4::Tag::setPictures(const PictureMap &l) +{ +} + bool MP4::Tag::isEmpty() const { return d->items.isEmpty(); diff --git a/taglib/mp4/mp4tag.h b/taglib/mp4/mp4tag.h index 596f785c..074d1b1a 100644 --- a/taglib/mp4/mp4tag.h +++ b/taglib/mp4/mp4tag.h @@ -60,6 +60,7 @@ namespace TagLib { String genre() const; uint year() const; uint track() const; + PictureMap pictures() const; void setTitle(const String &value); void setArtist(const String &value); @@ -68,6 +69,7 @@ namespace TagLib { void setGenre(const String &value); void setYear(uint value); void setTrack(uint value); + void setPictures(const PictureMap &l); virtual bool isEmpty() const; diff --git a/taglib/mpeg/id3v1/id3v1tag.cpp b/taglib/mpeg/id3v1/id3v1tag.cpp index 06b49830..f93d504b 100644 --- a/taglib/mpeg/id3v1/id3v1tag.cpp +++ b/taglib/mpeg/id3v1/id3v1tag.cpp @@ -25,6 +25,7 @@ #include #include +#include #include "id3v1tag.h" #include "id3v1genres.h" @@ -155,6 +156,11 @@ TagLib::uint ID3v1::Tag::track() const return d->track; } +TagLib::PictureMap ID3v1::Tag::pictures() const +{ + return PictureMap(); +} + void ID3v1::Tag::setTitle(const String &s) { d->title = s; @@ -190,6 +196,10 @@ void ID3v1::Tag::setTrack(TagLib::uint i) d->track = i < 256 ? i : 0; } +void ID3v1::Tag::setPictures(const PictureMap &l) +{ +} + TagLib::uint ID3v1::Tag::genreNumber() const { return d->genre; diff --git a/taglib/mpeg/id3v1/id3v1tag.h b/taglib/mpeg/id3v1/id3v1tag.h index 8ac83546..b939a731 100644 --- a/taglib/mpeg/id3v1/id3v1tag.h +++ b/taglib/mpeg/id3v1/id3v1tag.h @@ -99,6 +99,7 @@ namespace TagLib { virtual String genre() const; virtual TagLib::uint year() const; virtual TagLib::uint track() const; + virtual PictureMap pictures() const; virtual void setTitle(const String &s); virtual void setArtist(const String &s); @@ -107,6 +108,7 @@ namespace TagLib { virtual void setGenre(const String &s); virtual void setYear(TagLib::uint i); virtual void setTrack(TagLib::uint i); + virtual void setPictures(const PictureMap &l); /*! * Returns the genre in number. diff --git a/taglib/mpeg/id3v2/id3v2tag.cpp b/taglib/mpeg/id3v2/id3v2tag.cpp index dd32f2c7..cbfbe36b 100644 --- a/taglib/mpeg/id3v2/id3v2tag.cpp +++ b/taglib/mpeg/id3v2/id3v2tag.cpp @@ -32,6 +32,7 @@ #include #include #include +#include #include #include "id3v2tag.h" @@ -231,6 +232,11 @@ TagLib::uint ID3v2::Tag::track() const return 0; } +TagLib::PictureMap ID3v2::Tag::pictures() const +{ + return PictureMap(); +} + void ID3v2::Tag::setTitle(const String &s) { setTextFrame("TIT2", s); @@ -306,6 +312,10 @@ void ID3v2::Tag::setTrack(uint i) setTextFrame("TRCK", String::number(i)); } +void ID3v2::Tag::setPictures(const PictureMap &l) +{ +} + bool ID3v2::Tag::isEmpty() const { return d->frameList.isEmpty(); diff --git a/taglib/mpeg/id3v2/id3v2tag.h b/taglib/mpeg/id3v2/id3v2tag.h index 2a84bed2..321e34a0 100644 --- a/taglib/mpeg/id3v2/id3v2tag.h +++ b/taglib/mpeg/id3v2/id3v2tag.h @@ -142,6 +142,7 @@ namespace TagLib { virtual String genre() const; virtual uint year() const; virtual uint track() const; + virtual PictureMap pictures() const; virtual void setTitle(const String &s); virtual void setArtist(const String &s); @@ -150,6 +151,7 @@ namespace TagLib { virtual void setGenre(const String &s); virtual void setYear(uint i); virtual void setTrack(uint i); + virtual void setPictures( const PictureMap& l ); virtual bool isEmpty() const; diff --git a/taglib/ogg/xiphcomment.cpp b/taglib/ogg/xiphcomment.cpp index daf8181e..263b96dd 100644 --- a/taglib/ogg/xiphcomment.cpp +++ b/taglib/ogg/xiphcomment.cpp @@ -27,6 +27,7 @@ #include #include +#include #include using namespace TagLib; @@ -120,6 +121,11 @@ TagLib::uint Ogg::XiphComment::track() const return 0; } +TagLib::PictureMap Ogg::XiphComment::pictures() const +{ + return PictureMap(); +} + void Ogg::XiphComment::setTitle(const String &s) { addField("TITLE", s); @@ -170,6 +176,10 @@ void Ogg::XiphComment::setTrack(uint i) addField("TRACKNUMBER", String::number(i)); } +void Ogg::XiphComment::setPictures(const PictureMap &l) +{ +} + bool Ogg::XiphComment::isEmpty() const { FieldListMap::ConstIterator it = d->fieldListMap.begin(); diff --git a/taglib/ogg/xiphcomment.h b/taglib/ogg/xiphcomment.h index bf94b69c..ec9cbd05 100644 --- a/taglib/ogg/xiphcomment.h +++ b/taglib/ogg/xiphcomment.h @@ -86,6 +86,7 @@ namespace TagLib { virtual String genre() const; virtual uint year() const; virtual uint track() const; + virtual PictureMap pictures() const; virtual void setTitle(const String &s); virtual void setArtist(const String &s); @@ -94,6 +95,7 @@ namespace TagLib { virtual void setGenre(const String &s); virtual void setYear(uint i); virtual void setTrack(uint i); + virtual void setPictures( const PictureMap &l ); virtual bool isEmpty() const; virtual String toString() const; diff --git a/taglib/riff/wav/infotag.cpp b/taglib/riff/wav/infotag.cpp index bb9b861d..6b2ee6d2 100644 --- a/taglib/riff/wav/infotag.cpp +++ b/taglib/riff/wav/infotag.cpp @@ -25,6 +25,7 @@ #include #include +#include #include "rifffile.h" #include "infotag.h" @@ -118,6 +119,11 @@ TagLib::uint RIFF::Info::Tag::track() const return fieldText("IPRT").toInt(); } +TagLib::PictureMap RIFF::Info::Tag::pictures() const +{ + return PictureMap(); +} + void RIFF::Info::Tag::setTitle(const String &s) { setFieldText("INAM", s); @@ -159,6 +165,10 @@ void RIFF::Info::Tag::setTrack(uint i) d->fieldMap.erase("IPRT"); } +void RIFF::Info::Tag::setPictures(const PictureMap &l) +{ +} + bool RIFF::Info::Tag::isEmpty() const { return d->fieldMap.isEmpty(); diff --git a/taglib/riff/wav/infotag.h b/taglib/riff/wav/infotag.h index 8960ebc5..52f80d37 100644 --- a/taglib/riff/wav/infotag.h +++ b/taglib/riff/wav/infotag.h @@ -79,6 +79,7 @@ namespace TagLib { virtual String genre() const; virtual uint year() const; virtual uint track() const; + virtual PictureMap pictures() const; virtual void setTitle(const String &s); virtual void setArtist(const String &s); @@ -87,6 +88,7 @@ namespace TagLib { virtual void setGenre(const String &s); virtual void setYear(uint i); virtual void setTrack(uint i); + virtual void setPictures(const PictureMap &l); virtual bool isEmpty() const; diff --git a/taglib/tag.cpp b/taglib/tag.cpp index e4f5c933..aa6d15d0 100644 --- a/taglib/tag.cpp +++ b/taglib/tag.cpp @@ -25,6 +25,7 @@ #include "tag.h" #include "tstringlist.h" +#include "tpicturemap.h" #include "tpropertymap.h" using namespace TagLib; @@ -52,7 +53,8 @@ bool Tag::isEmpty() const comment().isEmpty() && genre().isEmpty() && year() == 0 && - track() == 0); + track() == 0 && + pictures().isEmpty()); } PropertyMap Tag::properties() const @@ -160,6 +162,7 @@ void Tag::duplicate(const Tag *source, Tag *target, bool overwrite) // static target->setGenre(source->genre()); target->setYear(source->year()); target->setTrack(source->track()); + target->setPictures(source->pictures()); } else { if(target->title().isEmpty()) @@ -176,6 +179,8 @@ void Tag::duplicate(const Tag *source, Tag *target, bool overwrite) // static target->setYear(source->year()); if(target->track() <= 0) target->setTrack(source->track()); + if(target->pictures().isEmpty() ) + target->setPictures(source->pictures()); } } diff --git a/taglib/tag.h b/taglib/tag.h index a8199ea7..4724e83e 100644 --- a/taglib/tag.h +++ b/taglib/tag.h @@ -27,6 +27,7 @@ #define TAGLIB_TAG_H #include "taglib_export.h" + #include "tstring.h" namespace TagLib { @@ -42,6 +43,7 @@ namespace TagLib { */ class PropertyMap; + class PictureMap; class TAGLIB_EXPORT Tag { @@ -116,6 +118,12 @@ namespace TagLib { */ virtual uint track() const = 0; + /*! + * Returns a list of pictures available; if there is no picture, the list + * will be empty + */ + virtual PictureMap pictures() const = 0; + /*! * Sets the title to \a s. If \a s is String::null then this value will be * cleared. @@ -159,6 +167,11 @@ namespace TagLib { */ virtual void setTrack(uint i) = 0; + /*! + * Sets the list of pictures + */ + virtual void setPictures( const PictureMap& l ) = 0; + /*! * Returns true if the tag does not contain any data. This should be * reimplemented in subclasses that provide more than the basic tagging diff --git a/taglib/tagunion.cpp b/taglib/tagunion.cpp index 78cc62af..d53e24f5 100644 --- a/taglib/tagunion.cpp +++ b/taglib/tagunion.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #include #define stringUnion(method) \ @@ -44,6 +45,14 @@ } \ return 0; +#define pictureMapUnion(method) \ + for(size_t j = 0; j < COUNT; ++j) { \ + PictureMap val = d->tags[j] ? d->tags[j]->method() : PictureMap(); \ + if(!val.isEmpty()) \ + return val; \ + } \ + return PictureMap(); \ + #define setUnion(method, value) \ for(size_t j = 0; j < COUNT; ++j) { \ if(d->tags[j]) \ @@ -163,6 +172,12 @@ namespace TagLib setUnion(Artist, s); } + template + TagLib::PictureMap TagUnion::pictures() const + { + pictureMapUnion(pictures); + } + template void TagUnion::setAlbum(const String &s) { @@ -193,6 +208,12 @@ namespace TagLib setUnion(Track, i); } + template + void TagUnion::setPictures(const PictureMap &l) + { + setUnion(Pictures, l); + } + template bool TagUnion::isEmpty() const { diff --git a/taglib/tagunion.h b/taglib/tagunion.h index e1a7544b..c949c15b 100644 --- a/taglib/tagunion.h +++ b/taglib/tagunion.h @@ -68,6 +68,7 @@ namespace TagLib { virtual String genre() const; virtual uint year() const; virtual uint track() const; + virtual PictureMap pictures() const; virtual void setTitle(const String &s); virtual void setArtist(const String &s); @@ -76,6 +77,8 @@ namespace TagLib { virtual void setGenre(const String &s); virtual void setYear(uint i); virtual void setTrack(uint i); + virtual void setPictures( const PictureMap& l ); + virtual bool isEmpty() const; template T *access(size_t index, bool create) diff --git a/taglib/toolkit/tpicture.cpp b/taglib/toolkit/tpicture.cpp new file mode 100644 index 00000000..84fe0370 --- /dev/null +++ b/taglib/toolkit/tpicture.cpp @@ -0,0 +1,184 @@ +/*************************************************************************** + copyright : (C) 2015 by Maxime Leblanc + email : lblnc.maxime@gmail.com + ***************************************************************************/ + +/*************************************************************************** + * This library is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License version * + * 2.1 as published by the Free Software Foundation. * + * * + * This library is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * + * 02110-1301 USA * + * * + * Alternatively, this file is available under the Mozilla Public * + * License Version 1.1. You may obtain a copy of the License at * + * http://www.mozilla.org/MPL/ * + ***************************************************************************/ + +#include "tpicture.h" + +using namespace TagLib; + +class Picture::PicturePrivate : public RefCounter +{ +public: + PicturePrivate() : RefCounter() + { + } + + String description; + String mime; + Type type; + ByteVector data; +}; + +Picture::Picture() + : d(new PicturePrivate()) +{ +} + +Picture::Picture(const ByteVector &data, + Type type, + const String &mime, + const String &description) + : d(new PicturePrivate()) +{ + d->mime = mime; + d->description = description; + d->type = type; + d->data = data; +} + +Picture::Picture(const Picture &p) + : d(p.d) +{ + d->ref(); +} + +String Picture::description() const +{ + return d->description; +} + +ByteVector Picture::data() const +{ + return d->data; +} + +String Picture::mime() const +{ + return d->mime; +} + +Picture::Type Picture::type() const +{ + return d->type; +} + +Picture::~Picture() +{ + if(d->deref()) + delete d; +} + +/* =========== OPERATORS =========== */ + +Picture &Picture::operator =(const Picture &p) +{ + if(&p == this) + return *this; + + if(d && d->deref()) + delete d; + + d = p.d; + d->ref(); + return *this; +} + +std::ostream &operator<<(std::ostream &s, const Picture &p) +{ + String type; + switch(p.type()) { + case Picture::Other: + type = "Other"; + break; + case Picture::FileIcon: + type = "FileIcon"; + break; + case Picture::OtherFileIcon: + type = "OtherFileIcon"; + break; + case Picture::FrontCover: + type = "FrontCover"; + break; + case Picture::BackCover: + type = "BackCover"; + break; + case Picture::LeafletPage: + type = "LeafletPage"; + break; + case Picture::Media: + type = "Media"; + break; + case Picture::LeadArtist: + type = "LeadArtist"; + break; + case Picture::Artist: + type = "Artist"; + break; + case Picture::Conductor: + type = "Conductor"; + break; + case Picture::Band: + type = "Band"; + break; + case Picture::Composer: + type = "Composer"; + break; + case Picture::Lyricist: + type = "Lyricist"; + break; + case Picture::RecordingLocation: + type = "RecordingLocation"; + break; + case Picture::DuringRecording: + type = "DuringRecording"; + break; + case Picture::DuringPerformance: + type = "DuringPerformance"; + break; + case Picture::MovieScreenCapture: + type = "MovieScreenCapture"; + break; + case Picture::ColouredFish: + type = "ColouredFish"; + break; + case Picture::Illustration: + type = "Illustration"; + break; + case Picture::BandLogo: + type = "BandLogo"; + break; + case Picture::PublisherLogo: + type = "PublisherLogo"; + break; + } + + ByteVector displayableData = p.data().mid(0, 20).toHex(); + s << "\nPicture:\n" + << "\ttype: " << type.to8Bit() << std::endl + << "\tdesc: " << p.description().to8Bit() << std::endl + << "\tmime: " << p.mime().to8Bit() << std::endl + << "\tdata: " << std::hex << displayableData << "..." << std::endl; + + return s; +} diff --git a/taglib/toolkit/tpicture.h b/taglib/toolkit/tpicture.h new file mode 100644 index 00000000..a3a0768e --- /dev/null +++ b/taglib/toolkit/tpicture.h @@ -0,0 +1,156 @@ +/*************************************************************************** + copyright : (C) 2015 by Maxime Leblanc + email : lblnc.maxime@gmail.com + ***************************************************************************/ + +/*************************************************************************** + * This library is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License version * + * 2.1 as published by the Free Software Foundation. * + * * + * This library is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * + * 02110-1301 USA * + * * + * Alternatively, this file is available under the Mozilla Public * + * License Version 1.1. You may obtain a copy of the License at * + * http://www.mozilla.org/MPL/ * + ***************************************************************************/ + +#ifndef TAGLIB_PICTURE_H +#define TAGLIB_PICTURE_H + +#include "taglib_export.h" +#include "tbytevector.h" +#include "tmap.h" +#include "tstring.h" + +namespace TagLib { + + class TAGLIB_EXPORT Picture + { + + class PicturePrivate; + + public: + + /*! + * The Type enum is based on types in id3v2 tags + */ + enum Type { + //! A type not enumerated below + Other = 0x00, + //! 32x32 PNG image that should be used as the file icon + FileIcon = 0x01, + //! File icon of a different size or format + OtherFileIcon = 0x02, + //! Front cover image of the album + FrontCover = 0x03, + //! Back cover image of the album + BackCover = 0x04, + //! Inside leaflet page of the album + LeafletPage = 0x05, + //! Image from the album itself + Media = 0x06, + //! Picture of the lead artist or soloist + LeadArtist = 0x07, + //! Picture of the artist or performer + Artist = 0x08, + //! Picture of the conductor + Conductor = 0x09, + //! Picture of the band or orchestra + Band = 0x0A, + //! Picture of the composer + Composer = 0x0B, + //! Picture of the lyricist or text writer + Lyricist = 0x0C, + //! Picture of the recording location or studio + RecordingLocation = 0x0D, + //! Picture of the artists during recording + DuringRecording = 0x0E, + //! Picture of the artists during performance + DuringPerformance = 0x0F, + //! Picture from a movie or video related to the track + MovieScreenCapture = 0x10, + //! Picture of a large, coloured fish + ColouredFish = 0x11, + //! Illustration related to the track + Illustration = 0x12, + //! Logo of the band or performer + BandLogo = 0x13, + //! Logo of the publisher (record company) + PublisherLogo = 0x14 + }; + + /*! + * Constructs an empty Picture. + */ + Picture(); + + /*! + * Constructs a Picture object base on an other Picture + */ + Picture(const Picture &p); + + /*! + * Constructs a Picture object based on the \a ByteVector given. + * + * \note type, mime and description are optional + */ + Picture(const ByteVector &data, + Type type = Other, + const String &mime = "image/", + const String &description = String()); + + /*! + * Destroys this Picture instance. + */ + virtual ~Picture(); + + /*! + * Returns the mime of the picture + */ + String mime() const; + + /*! + * Returns the descritpion of the picture + */ + String description() const; + + /*! + * Returns the type of the picture + */ + Type type() const; + + /*! + * Returns datas of the picture + */ + ByteVector data() const; + + /*! + * Performs a shallow, implicitly shared, copy of \a p, overwriting the + * Picture's current data. + */ + Picture &operator=(const Picture &p); + + private: + PicturePrivate *d; + }; + +} + +/*! + * \relates TagLib::Picture + * + * Send the picture to an output stream. + */ +TAGLIB_EXPORT std::ostream &operator<<(std::ostream &s, + const TagLib::Picture &picture); + +#endif // TAGLIB_PICTUREMAP_H diff --git a/taglib/toolkit/tpicturemap.cpp b/taglib/toolkit/tpicturemap.cpp new file mode 100644 index 00000000..2e6b068d --- /dev/null +++ b/taglib/toolkit/tpicturemap.cpp @@ -0,0 +1,82 @@ +/*************************************************************************** + copyright : (C) 2015 by Maxime Leblanc + email : lblnc.maxime@gmail.com + ***************************************************************************/ + +/*************************************************************************** + * This library is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License version * + * 2.1 as published by the Free Software Foundation. * + * * + * This library is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * + * 02110-1301 USA * + * * + * Alternatively, this file is available under the Mozilla Public * + * License Version 1.1. You may obtain a copy of the License at * + * http://www.mozilla.org/MPL/ * + ***************************************************************************/ + +#include "tpicturemap.h" + +using namespace TagLib; + +PictureMap::PictureMap() : Map< Picture::Type, PictureList >() +{ +} + +PictureMap::PictureMap(const PictureList &l) + : Map< Picture::Type, PictureList >() +{ + insert(l); +} + +PictureMap::PictureMap(const Picture &p) + : Map< Picture::Type, PictureList >() +{ + insert(p); +} + +void PictureMap::insert(const Picture &p) +{ + PictureList list; + if(contains(p.type())) { + list = Map::find(p.type())->second; + list.append(p); + Map::insert(p.type(), list); + } + else { + list.append(p); + Map::insert(p.type(), list); + } +} + +void PictureMap::insert(const PictureList &l) +{ + for(PictureList::ConstIterator it = l.begin(); it != l.end(); ++it) { + Picture picture = (*it); + insert(picture); + } +} + +PictureMap::~PictureMap() +{ +} + +std::ostream &operator<<(std::ostream &s, const PictureMap &map) +{ + for(PictureMap::ConstIterator it = map.begin(); it != map.end(); ++it) { + PictureList list = it->second; + for(PictureList::ConstIterator it2 = list.begin(); + it2 != list.end(); + ++it2) + s << *it2; + } + return s; +} diff --git a/taglib/toolkit/tpicturemap.h b/taglib/toolkit/tpicturemap.h new file mode 100644 index 00000000..c3f35999 --- /dev/null +++ b/taglib/toolkit/tpicturemap.h @@ -0,0 +1,86 @@ +/*************************************************************************** + copyright : (C) 2015 by Maxime Leblanc + email : lblnc.maxime@gmail.com + ***************************************************************************/ + +/*************************************************************************** + * This library is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License version * + * 2.1 as published by the Free Software Foundation. * + * * + * This library is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * + * 02110-1301 USA * + * * + * Alternatively, this file is available under the Mozilla Public * + * License Version 1.1. You may obtain a copy of the License at * + * http://www.mozilla.org/MPL/ * + ***************************************************************************/ + +#ifndef TAGLIB_PICTUREMAP_H +#define TAGLIB_PICTUREMAP_H + +#include "tlist.h" +#include "tmap.h" +#include "taglib_export.h" +#include "tpicture.h" + +namespace TagLib { + + //! A list of pictures + typedef List PictureList; + + /*! + * This is a spcialization of the List class with some members. + */ + class TAGLIB_EXPORT PictureMap : public Map< Picture::Type, PictureList > + { + public: + + /*! + * Constructs an empty PictureList. + */ + PictureMap(); + + /*! + * Constructs a PictureMap with \a Picture. + */ + PictureMap(const Picture &p); + + /*! + * Constructs a PictureMap with \a PictureList as a member. + */ + PictureMap(const PictureList &l); + + /*! + * Destroys this PictureList instance. + */ + virtual ~PictureMap(); + + /*! + * Inserts a PictureList into the picture map + */ + void insert(const PictureList &l); + + /*! + * Inserts a Picture into the picture map + */ + void insert(const Picture &p); + }; + +} + +/*! + * \relates TagLib::PictureMap + * + * Send the PictureMap to on output stream + */ +TAGLIB_EXPORT std::ostream &operator<<(std::ostream &s, const TagLib::PictureMap &map); + +#endif // TAGLIB_PICTUREMAP_H