Merge branch 'pictures' of https://github.com/MaxLeb/taglib into MaxLeb-pictures

# Conflicts:
#	taglib/mpeg/id3v2/id3v2tag.cpp
#	taglib/tagunion.cpp
This commit is contained in:
Tsuda Kageyu 2015-11-22 15:46:22 +09:00
commit b3014f0878
27 changed files with 768 additions and 92 deletions

View File

@ -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

View File

@ -34,6 +34,7 @@
#include <tfile.h>
#include <tstring.h>
#include <tmap.h>
#include <tpicturemap.h>
#include <tpropertymap.h>
#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;

View File

@ -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.

View File

@ -23,6 +23,7 @@
* http://www.mozilla.org/MPL/ *
***************************************************************************/
#include <tpicturemap.h>
#include <tpropertymap.h>
#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;

View File

@ -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

View File

@ -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<Element *> entries = elem->getChildren(Constants::Tag);
for(List<Element *>::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<Element *> simpleTags = (*i)->getChildren(Constants::SimpleTag);
@ -78,11 +79,11 @@ public:
continue;
tagEntries.insert(name, StringList(value));
}
tags.append(std::pair<PropertyMap, std::pair<Element *, ulli> >(tagEntries, std::pair<Element *, ulli>(*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<std::pair<PropertyMap, std::pair<Element *, ulli> > > 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<PropertyMap, std::pair<Element *, ulli> > 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<std::pair<PropertyMap, std::pair<Element *, ulli> > >::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<Element *> simpleTags = i->second.first->getChildren(Constants::SimpleTag);
StringList::Iterator str = j->second.begin();
List<Element *>::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<Element *> simpleTags = i->second.first->getChildren(Constants::SimpleTag);
for(List<Element *>::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<std::pair<PropertyMap, std::pair<Element *, ulli> > >::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<std::pair<PropertyMap, std::pair<Element *, ulli> > >::Iterator
find(ulli ttv)
{
for(List<std::pair<PropertyMap, std::pair<Element *, ulli> > >::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<std::pair<PropertyMap, std::pair<Element *, ulli> > >::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<std::pair<PropertyMap, std::pair<Element *, ulli> > >::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<std::pair<PropertyMap, std::pair<Element *, ulli> > >::Iterator title;
List<std::pair<PropertyMap, std::pair<Element *, ulli> > >::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())

View File

@ -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;
};
}
}
}

View File

@ -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;

View File

@ -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.

View File

@ -25,6 +25,7 @@
#include <tdebug.h>
#include <tstring.h>
#include <tpicturemap.h>
#include <tpropertymap.h>
#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();

View File

@ -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;

View File

@ -25,6 +25,7 @@
#include <tdebug.h>
#include <tfile.h>
#include <tpicturemap.h>
#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;

View File

@ -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.

View File

@ -32,6 +32,7 @@
#include <tfile.h>
#include <tbytevector.h>
#include <tpropertymap.h>
#include <tpicturemap.h>
#include <tdebug.h>
#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();

View File

@ -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;

View File

@ -27,6 +27,7 @@
#include <tdebug.h>
#include <xiphcomment.h>
#include <tpicturemap.h>
#include <tpropertymap.h>
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();

View File

@ -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;

View File

@ -25,6 +25,7 @@
#include <tdebug.h>
#include <tfile.h>
#include <tpicturemap.h>
#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();

View File

@ -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;

View File

@ -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());
}
}

View File

@ -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

View File

@ -26,6 +26,7 @@
#include <tagunion.h>
#include <tstringlist.h>
#include <tpropertymap.h>
#include <tpicturemap.h>
#include <tsmartptr.h>
#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 <size_t COUNT>
TagLib::PictureMap TagUnion<COUNT>::pictures() const
{
pictureMapUnion(pictures);
}
template <size_t COUNT>
void TagUnion<COUNT>::setAlbum(const String &s)
{
@ -193,6 +208,12 @@ namespace TagLib
setUnion(Track, i);
}
template <size_t COUNT>
void TagUnion<COUNT>::setPictures(const PictureMap &l)
{
setUnion(Pictures, l);
}
template <size_t COUNT>
bool TagUnion<COUNT>::isEmpty() const
{

View File

@ -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 <class T> T *access(size_t index, bool create)

184
taglib/toolkit/tpicture.cpp Normal file
View File

@ -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;
}

156
taglib/toolkit/tpicture.h Normal file
View File

@ -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

View File

@ -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<Picture::Type, PictureList>::find(p.type())->second;
list.append(p);
Map<Picture::Type, PictureList>::insert(p.type(), list);
}
else {
list.append(p);
Map<Picture::Type, PictureList>::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;
}

View File

@ -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<Picture> 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