summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xplugins/soundsource/libsoundsourcem4a.sobin0 -> 1300576 bytes
-rw-r--r--plugins/soundsourcem4a/soundsourcem4a.cpp6
-rw-r--r--plugins/soundsourcem4a/soundsourcem4a.h1
-rw-r--r--plugins/soundsourcemediafoundation/soundsourcemediafoundation.cpp5
-rw-r--r--plugins/soundsourcemediafoundation/soundsourcemediafoundation.h1
-rw-r--r--plugins/soundsourcewv/soundsourcewv.cpp7
-rw-r--r--plugins/soundsourcewv/soundsourcewv.h1
-rw-r--r--src/library/coverartcache.cpp7
-rw-r--r--src/soundsource.cpp134
-rw-r--r--src/soundsource.h11
-rw-r--r--src/soundsourcecoreaudio.cpp16
-rw-r--r--src/soundsourcecoreaudio.h1
-rw-r--r--src/soundsourceffmpeg.h1
-rw-r--r--src/soundsourceflac.cpp22
-rw-r--r--src/soundsourceflac.h1
-rw-r--r--src/soundsourcemodplug.h1
-rw-r--r--src/soundsourcemp3.cpp11
-rw-r--r--src/soundsourcemp3.h1
-rw-r--r--src/soundsourceoggvorbis.cpp6
-rw-r--r--src/soundsourceoggvorbis.h1
-rw-r--r--src/soundsourceopus.h1
-rw-r--r--src/soundsourceproxy.cpp4
-rw-r--r--src/soundsourceproxy.h1
-rw-r--r--src/soundsourcesndfile.cpp32
-rw-r--r--src/soundsourcesndfile.h1
-rw-r--r--src/test/coverartcache_test.cpp8
26 files changed, 203 insertions, 78 deletions
diff --git a/plugins/soundsource/libsoundsourcem4a.so b/plugins/soundsource/libsoundsourcem4a.so
new file mode 100755
index 0000000000..527047e91b
--- /dev/null
+++ b/plugins/soundsource/libsoundsourcem4a.so
Binary files differ
diff --git a/plugins/soundsourcem4a/soundsourcem4a.cpp b/plugins/soundsourcem4a/soundsourcem4a.cpp
index 9e3717ddde..eb0a552bad 100644
--- a/plugins/soundsourcem4a/soundsourcem4a.cpp
+++ b/plugins/soundsourcem4a/soundsourcem4a.cpp
@@ -192,6 +192,12 @@ Result SoundSourceM4A::parseHeader(){
return ERR;
}
+QImage SoundSourceM4A::parseCoverArt() {
+ setType("m4a");
+ TagLib::MP4::File f(getFilename().toLocal8Bit().constData());
+ return getCoverInMP4Tag(f.tag());
+}
+
QList<QString> SoundSourceM4A::supportedFileExtensions()
{
QList<QString> list;
diff --git a/plugins/soundsourcem4a/soundsourcem4a.h b/plugins/soundsourcem4a/soundsourcem4a.h
index f039c5f25f..e6a141489e 100644
--- a/plugins/soundsourcem4a/soundsourcem4a.h
+++ b/plugins/soundsourcem4a/soundsourcem4a.h
@@ -49,6 +49,7 @@ class SoundSourceM4A : public SoundSource {
unsigned read(unsigned long size, const SAMPLE*);
unsigned long length();
Result parseHeader();
+ QImage parseCoverArt();
static QList<QString> supportedFileExtensions();
private:
int trackId;
diff --git a/plugins/soundsourcemediafoundation/soundsourcemediafoundation.cpp b/plugins/soundsourcemediafoundation/soundsourcemediafoundation.cpp
index 4e10c6e300..e3c4aac68e 100644
--- a/plugins/soundsourcemediafoundation/soundsourcemediafoundation.cpp
+++ b/plugins/soundsourcemediafoundation/soundsourcemediafoundation.cpp
@@ -391,6 +391,11 @@ Result SoundSourceMediaFoundation::parseHeader()
return ERR;
}
+QImage SoundSourceMediaFoundation::parseCoverArt() {
+ setType("m4a");
+ TagLib::MP4::File f(getFilename().toLocal8Bit().constData());
+ return getCoverInMP4Tag(f.tag());
+}
// static
QList<QString> SoundSourceMediaFoundation::supportedFileExtensions()
diff --git a/plugins/soundsourcemediafoundation/soundsourcemediafoundation.h b/plugins/soundsourcemediafoundation/soundsourcemediafoundation.h
index 016f6901c2..79875551e2 100644
--- a/plugins/soundsourcemediafoundation/soundsourcemediafoundation.h
+++ b/plugins/soundsourcemediafoundation/soundsourcemediafoundation.h
@@ -46,6 +46,7 @@ class SoundSourceMediaFoundation : public Mixxx::SoundSource {
unsigned read(unsigned long size, const SAMPLE *buffer);
inline long unsigned length();
Result parseHeader();
+ QImage parseCoverArt();
static QList<QString> supportedFileExtensions();
private:
diff --git a/plugins/soundsourcewv/soundsourcewv.cpp b/plugins/soundsourcewv/soundsourcewv.cpp
index c247ac3dbb..3c3ad1640f 100644
--- a/plugins/soundsourcewv/soundsourcewv.cpp
+++ b/plugins/soundsourcewv/soundsourcewv.cpp
@@ -139,6 +139,13 @@ Result SoundSourceWV::parseHeader() {
return ERR;
}
+QImage SoundSourceWV::parseCoverArt() {
+ setType("wv");
+ TagLib::WavPack::File f(m_qFilename.toLocal8Bit().constData());
+ TagLib::APE::Tag *ape = f.APETag();
+ return getCoverInAPETag(ape);
+}
+
void SoundSourceWV::format_samples(int Bps, char *dst, int32_t *src, uint32_t count)
{
//this handles converting the fixed 32bit per sample produced by UnpackSamples
diff --git a/plugins/soundsourcewv/soundsourcewv.h b/plugins/soundsourcewv/soundsourcewv.h
index e7235da39a..ee65ecccda 100644
--- a/plugins/soundsourcewv/soundsourcewv.h
+++ b/plugins/soundsourcewv/soundsourcewv.h
@@ -32,6 +32,7 @@ class SoundSourceWV : public SoundSource {
unsigned read(unsigned long size, const SAMPLE*);
inline long unsigned length();
Result parseHeader();
+ QImage parseCoverArt();
static QList<QString> supportedFileExtensions();
private:
int Bps;
diff --git a/src/library/coverartcache.cpp b/src/library/coverartcache.cpp
index 482ec68cf3..1a402200e7 100644
--- a/src/library/coverartcache.cpp
+++ b/src/library/coverartcache.cpp
@@ -311,15 +311,14 @@ QImage CoverArtCache::extractEmbeddedCover(QString trackLocation) {
if (trackLocation.isEmpty()) {
return QImage();
}
-
SecurityTokenPointer securityToken = Sandbox::openSecurityToken(
QDir(trackLocation), true);
SoundSourceProxy proxy(trackLocation, securityToken);
Mixxx::SoundSource* pProxiedSoundSource = proxy.getProxiedSoundSource();
- if (pProxiedSoundSource != NULL && proxy.parseHeader() == OK) {
- return pProxiedSoundSource->getCoverArt();
+ if (pProxiedSoundSource == NULL) {
+ return QImage();
}
- return QImage();
+ return proxy.parseCoverArt();
}
// watcher
diff --git a/src/soundsource.cpp b/src/soundsource.cpp
index 1b7b457d16..19741158f3 100644
--- a/src/soundsource.cpp
+++ b/src/soundsource.cpp
@@ -149,10 +149,6 @@ int SoundSource::getChannels()
{
return m_iChannels;
}
-QImage SoundSource::getCoverArt()
-{
- return m_coverArt;
-}
void SoundSource::setArtist(QString artist)
{
@@ -222,10 +218,6 @@ void SoundSource::setChannels(int channels)
{
m_iChannels = channels;
}
-void SoundSource::setCoverArt(QImage picture)
-{
- m_coverArt = picture;
-}
QString SoundSource::getKey(){
return m_sKey;
}
@@ -390,18 +382,6 @@ bool SoundSource::processID3v2Tag(TagLib::ID3v2::Tag* id3v2) {
setGrouping(sGrouping);
}
- // Get Cover Art
- TagLib::ID3v2::FrameList covertArtFrame = id3v2->frameListMap()["APIC"];
- if (!covertArtFrame.isEmpty()) {
- TagLib::ID3v2::AttachedPictureFrame* picframe = static_cast
- <TagLib::ID3v2::AttachedPictureFrame*>(covertArtFrame.front());
- TagLib::ByteVector data = picframe->picture();
- QImage picture = QImage::fromData(reinterpret_cast<const uchar *>(
- data.data()),
- data.size());
- setCoverArt(picture);
- }
-
return true;
}
@@ -413,21 +393,6 @@ bool SoundSource::processAPETag(TagLib::APE::Tag* ape) {
}
}
- // Get Cover Art
- if (ape->itemListMap().contains("COVER ART (FRONT)"))
- {
- const TagLib::ByteVector nullStringTerminator(1, 0);
- TagLib::ByteVector item = ape->itemListMap()["COVER ART (FRONT)"].value();
- int pos = item.find(nullStringTerminator); // skip the filename
- if (++pos > 0) {
- const TagLib::ByteVector& data = item.mid(pos);
- QImage picture = QImage::fromData(reinterpret_cast<const uchar *>(
- data.data()),
- data.size());
- setCoverArt(picture);
- }
- }
-
if (ape->itemListMap().contains("BPM")) {
QString sBpm = toQString(ape->itemListMap()["BPM"].toString());
processBpmString("APE", sBpm);
@@ -467,20 +432,6 @@ bool SoundSource::processXiphComment(TagLib::Ogg::XiphComment* xiph) {
}
}
- // Get Cover Art
- if (xiph->fieldListMap().contains("METADATA_BLOCK_PICTURE")) {
- QByteArray data(QByteArray::fromBase64(
- xiph->fieldListMap()["METADATA_BLOCK_PICTURE"].front().toCString()));
- TagLib::ByteVector tdata(data.data(), data.size());
- TagLib::FLAC::Picture p(tdata);
- data = QByteArray(p.data().data(), p.data().size());
- setCoverArt(QImage::fromData(data));
- } else if (xiph->fieldListMap().contains("COVERART")) {
- QByteArray data(QByteArray::fromBase64(
- xiph->fieldListMap()["COVERART"].toString().toCString()));
- setCoverArt(QImage::fromData(data));
- }
-
// Some tags use "BPM" so check for that.
if (xiph->fieldListMap().contains("BPM")) {
TagLib::StringList bpmString = xiph->fieldListMap()["BPM"];
@@ -559,17 +510,6 @@ bool SoundSource::processMP4Tag(TagLib::MP4::Tag* mp4) {
}
}
- // Get Cover Art
- if (mp4->itemListMap().contains("covr")) {
- TagLib::MP4::CoverArtList coverArtList = mp4->itemListMap()["covr"]
- .toCoverArtList();
- TagLib::ByteVector data = coverArtList.front().data();
- QImage picture = QImage::fromData(reinterpret_cast<const uchar *>(
- data.data()),
- data.size());
- setCoverArt(picture);
- }
-
// Get BPM
if (mp4->itemListMap().contains("tmpo")) {
QString sBpm = toQString(
@@ -625,4 +565,78 @@ bool SoundSource::processMP4Tag(TagLib::MP4::Tag* mp4) {
return true;
}
+QImage SoundSource::getCoverInID3v2Tag(TagLib::ID3v2::Tag *id3v2) {
+ if (!id3v2) {
+ return QImage();
+ }
+
+ QImage coverArt;
+ TagLib::ID3v2::FrameList covertArtFrame = id3v2->frameListMap()["APIC"];
+ if (!covertArtFrame.isEmpty()) {
+ TagLib::ID3v2::AttachedPictureFrame* picframe = static_cast
+ <TagLib::ID3v2::AttachedPictureFrame*>(covertArtFrame.front());
+ TagLib::ByteVector data = picframe->picture();
+ coverArt = QImage::fromData(
+ reinterpret_cast<const uchar *>(data.data()), data.size());
+ }
+ return coverArt;
+}
+
+QImage SoundSource::getCoverInAPETag(TagLib::APE::Tag *ape) {
+ if (!ape) {
+ return QImage();
+ }
+
+ QImage coverArt;
+ if (ape->itemListMap().contains("COVER ART (FRONT)"))
+ {
+ const TagLib::ByteVector nullStringTerminator(1, 0);
+ TagLib::ByteVector item = ape->itemListMap()["COVER ART (FRONT)"].value();
+ int pos = item.find(nullStringTerminator); // skip the filename
+ if (++pos > 0) {
+ const TagLib::ByteVector& data = item.mid(pos);
+ coverArt = QImage::fromData(
+ reinterpret_cast<const uchar *>(data.data()), data.size());
+ }
+ }
+ return coverArt;
+}
+
+QImage SoundSource::getCoverInXiphComment(TagLib::Ogg::XiphComment *xiph) {
+ if (!xiph) {
+ return QImage();
+ }
+
+ QImage coverArt;
+ if (xiph->fieldListMap().contains("METADATA_BLOCK_PICTURE")) {
+ QByteArray data(QByteArray::fromBase64(
+ xiph->fieldListMap()["METADATA_BLOCK_PICTURE"].front().toCString()));
+ TagLib::ByteVector tdata(data.data(), data.size());
+ TagLib::FLAC::Picture p(tdata);
+ data = QByteArray(p.data().data(), p.data().size());
+ coverArt = QImage::fromData(data);
+ } else if (xiph->fieldListMap().contains("COVERART")) {
+ QByteArray data(QByteArray::fromBase64(
+ xiph->fieldListMap()["COVERART"].toString().toCString()));
+ coverArt = QImage::fromData(data);
+ }
+ return coverArt;
+}
+
+QImage SoundSource::getCoverInMP4Tag(TagLib::MP4::Tag *mp4) {
+ if (!mp4) {
+ return QImage();
+ }
+
+ QImage coverArt;
+ if (mp4->itemListMap().contains("covr")) {
+ TagLib::MP4::CoverArtList coverArtList = mp4->itemListMap()["covr"]
+ .toCoverArtList();
+ TagLib::ByteVector data = coverArtList.front().data();
+ coverArt = QImage::fromData(
+ reinterpret_cast<const uchar *>(data.data()), data.size());
+ }
+ return coverArt;
+}
+
} //namespace Mixxx
diff --git a/src/soundsource.h b/src/soundsource.h
index a0771dffb6..78d06e439a 100644
--- a/src/soundsource.h
+++ b/src/soundsource.h
@@ -67,6 +67,7 @@ public:
virtual long unsigned length() = 0;
static float str2bpm( QString sBpm );
virtual Result parseHeader() = 0;
+ virtual QImage parseCoverArt() = 0;
//static QList<QString> supportedFileExtensions(); //CRAP can't do this!
/** Return a list of cue points stored in the file */
virtual QList<long> *getCuePoints();
@@ -92,7 +93,6 @@ public:
virtual int getBitrate();
virtual unsigned int getSampleRate();
virtual int getChannels();
- virtual QImage getCoverArt();
virtual void setArtist(QString);
virtual void setTitle(QString);
@@ -112,7 +112,6 @@ public:
virtual void setBitrate(int);
virtual void setSampleRate(unsigned int);
virtual void setChannels(int);
- virtual void setCoverArt(QImage);
protected:
// Automatically collects generic data from a TagLib File: title, artist,
@@ -126,6 +125,13 @@ protected:
void processBpmString(QString tagName, QString sBpm);
void parseReplayGainString(QString sReplayGain);
+ // In order to avoid processing images when it's not
+ // needed (TIO building), we must process it separately.
+ QImage getCoverInID3v2Tag(TagLib::ID3v2::Tag* id3v2);
+ QImage getCoverInAPETag(TagLib::APE::Tag* ape);
+ QImage getCoverInXiphComment(TagLib::Ogg::XiphComment* xiph);
+ QImage getCoverInMP4Tag(TagLib::MP4::Tag* mp4);
+
// Taglib strings can be NULL and using it could cause some segfaults,
// so in this case it will return a QString()
QString toQString(TagLib::String tstring) const;
@@ -144,7 +150,6 @@ protected:
QString m_sComposer;
QString m_sGrouping;
QString m_sTrackNumber;
- QImage m_coverArt;
float m_fReplayGain;
QString m_sKey;
float m_fBPM;
diff --git a/src/soundsourcecoreaudio.cpp b/src/soundsourcecoreaudio.cpp
index f875b47f10..c245e9488f 100644
--- a/src/soundsourcecoreaudio.cpp
+++ b/src/soundsourcecoreaudio.cpp
@@ -226,6 +226,22 @@ Result SoundSourceCoreAudio::parseHeader() {
return result ? OK : ERR;
}
+QImage SoundSourceCoreAudio::parseCoverArt() {
+ QImage coverArt;
+ if (getFilename().endsWith(".m4a")) {
+ setType("m4a");
+ TagLib::MP4::File f(getFilename().toLocal8Bit().constData());
+ coverArt = getCoverInMP4Tag(f.tag());
+ } else if (getFilename().endsWith(".mp3")) {
+ setType("mp3");
+ TagLib::MPEG::File f(getFilename().toLocal8Bit().constData());
+ coverArt = getCoverInID3v2Tag(f.ID3v2Tag());
+ if (coverArt.isNull()) {
+ coverArt = getCoverInAPETag(f.APETag());
+ }
+ }
+ return coverArt;
+}
// static
QList<QString> SoundSourceCoreAudio::supportedFileExtensions() {
diff --git a/src/soundsourcecoreaudio.h b/src/soundsourcecoreaudio.h
index f47daf17fa..1bf22067d3 100644
--- a/src/soundsourcecoreaudio.h
+++ b/src/soundsourcecoreaudio.h
@@ -50,6 +50,7 @@ public:
unsigned read(unsigned long size, const SAMPLE *buffer);
inline long unsigned length();
Result parseHeader();
+ QImage parseCoverArt();
static QList<QString> supportedFileExtensions();
private:
unsigned int m_samples; // total number of samples
diff --git a/src/soundsourceffmpeg.h b/src/soundsourceffmpeg.h
index 2be1e7f5e8..c67fb16443 100644
--- a/src/soundsourceffmpeg.h
+++ b/src/soundsourceffmpeg.h
@@ -59,6 +59,7 @@ public:
long seek(long);
unsigned int read(unsigned long size, const SAMPLE*);
Result parseHeader();
+ QImage parseCoverArt();
inline long unsigned length();
bool readInput();
static QList<QString> supportedFileExtensions();
diff --git a/src/soundsourceflac.cpp b/src/soundsourceflac.cpp
index 8c00cad1b3..f3048e2f11 100644
--- a/src/soundsourceflac.cpp
+++ b/src/soundsourceflac.cpp
@@ -165,19 +165,27 @@ Result SoundSourceFLAC::parseHeader() {
processXiphComment(xiph);
}
- // if any cover was found in the tag parsing,
- // try getting the first picture in the list.
- if (getCoverArt().isNull()) {
+ return result ? OK : ERR;
+}
+
+QImage SoundSourceFLAC::parseCoverArt() {
+ QImage coverArt;
+ setType("flac");
+ TagLib::FLAC::File f(m_qFilename.toLocal8Bit().constData());
+ coverArt = getCoverInID3v2Tag(f.ID3v2Tag());
+ if (coverArt.isNull()) {
+ coverArt = getCoverInXiphComment(f.xiphComment());
+ }
+ if (coverArt.isNull()) {
TagLib::List<TagLib::FLAC::Picture*> covers = f.pictureList();
if (!covers.isEmpty()) {
std::list<TagLib::FLAC::Picture*>::iterator it = covers.begin();
TagLib::FLAC::Picture* cover = *it;
- setCoverArt(QImage::fromData(
- QByteArray(cover->data().data(), cover->data().size())));
+ coverArt = QImage::fromData(
+ QByteArray(cover->data().data(), cover->data().size()));
}
}
-
- return result ? OK : ERR;
+ return coverArt;
}
/**
diff --git a/src/soundsourceflac.h b/src/soundsourceflac.h
index d9061318d6..3f7deee158 100644
--- a/src/soundsourceflac.h
+++ b/src/soundsourceflac.h
@@ -36,6 +36,7 @@ public:
unsigned read(unsigned long size, const SAMPLE *buffer);
inline long unsigned length();
Result parseHeader();
+ QImage parseCoverArt();
static QList<QString> supportedFileExtensions();
// callback methods
FLAC__StreamDecoderReadStatus flacRead(FLAC__byte buffer[], size_t *bytes);
diff --git a/src/soundsourcemodplug.h b/src/soundsourcemodplug.h
index cfe8978408..0335bc73f0 100644
--- a/src/soundsourcemodplug.h
+++ b/src/soundsourcemodplug.h
@@ -28,6 +28,7 @@ class SoundSourceModPlug : public Mixxx::SoundSource
unsigned read(unsigned long size, const SAMPLE*);
inline long unsigned length();
Result parseHeader();
+ QImage parseCoverArt();
static QList<QString> supportedFileExtensions();
// apply settings for decoding
diff --git a/src/soundsourcemp3.cpp b/src/soundsourcemp3.cpp
index b378d62e5c..5f4e0c5cb3 100644
--- a/src/soundsourcemp3.cpp
+++ b/src/soundsourcemp3.cpp
@@ -580,6 +580,17 @@ Result SoundSourceMp3::parseHeader() {
return result ? OK : ERR;
}
+QImage SoundSourceMp3::parseCoverArt() {
+ QImage coverArt;
+ setType("mp3");
+ TagLib::MPEG::File f(m_qFilename.toLocal8Bit().constData());
+ coverArt = getCoverInID3v2Tag(f.ID3v2Tag());
+ if (coverArt.isNull()) {
+ coverArt = getCoverInAPETag(f.APETag());
+ }
+ return coverArt;
+}
+
int SoundSourceMp3::findFrame(int pos)
{
// Guess position of frame in m_qSeekList based on average frame size
diff --git a/src/soundsourcemp3.h b/src/soundsourcemp3.h
index 968eee91a6..e6e552676b 100644
--- a/src/soundsourcemp3.h
+++ b/src/soundsourcemp3.h
@@ -62,6 +62,7 @@ public:
/** Return the length of the file in samples. */
inline long unsigned length();
Result parseHeader();
+ QImage parseCoverArt();
static QList<QString> supportedFileExtensions();
private:
diff --git a/src/soundsourceoggvorbis.cpp b/src/soundsourceoggvorbis.cpp
index 7885ee9b25..1967c49b16 100644
--- a/src/soundsourceoggvorbis.cpp
+++ b/src/soundsourceoggvorbis.cpp
@@ -244,6 +244,12 @@ Result SoundSourceOggVorbis::parseHeader() {
return result ? OK : ERR;
}
+QImage SoundSourceOggVorbis::parseCoverArt() {
+ setType("ogg");
+ TagLib::Ogg::Vorbis::File f(m_qFilename.toLocal8Bit().constData());
+ return getCoverInXiphComment(f.tag());
+}
+
/*
Return the length of the file in samples.
*/
diff --git a/src/soundsourceoggvorbis.h b/src/soundsourceoggvorbis.h
index 9bb7424239..2c6e3add82 100644
--- a/src/soundsourceoggvorbis.h
+++ b/src/soundsourceoggvorbis.h
@@ -32,6 +32,7 @@ class SoundSourceOggVorbis : public Mixxx::SoundSource {
unsigned read(unsigned long size, const SAMPLE*);
inline long unsigned length();
Result parseHeader();
+ QImage parseCoverArt();
static QList<QString> supportedFileExtensions();
private:
int channels;
diff --git a/src/soundsourceopus.h b/src/soundsourceopus.h
index fd48b2c1f6..f5927bed77 100644
--- a/src/soundsourceopus.h
+++ b/src/soundsourceopus.h
@@ -22,6 +22,7 @@ class SoundSourceOpus : public Mixxx::SoundSource {
unsigned read(unsigned long size, const SAMPLE*);
inline long unsigned length();
Result parseHeader();
+ QImage parseCoverArt();
static QList<QString> supportedFileExtensions();
private:
diff --git a/src/soundsourceproxy.cpp b/src/soundsourceproxy.cpp
index a5491ad621..35ca0ec7ff 100644
--- a/src/soundsourceproxy.cpp
+++ b/src/soundsourceproxy.cpp
@@ -359,6 +359,10 @@ Result SoundSourceProxy::parseHeader() {
return m_pSoundSource ? m_pSoundSource->parseHeader() : ERR;
}
+QImage SoundSourceProxy::parseCoverArt() {
+ return m_pSoundSource ? m_pSoundSource->parseCoverArt() : QImage();
+}
+
// static
QStringList SoundSourceProxy::supportedFileExtensions()
{
diff --git a/src/soundsourceproxy.h b/src/soundsourceproxy.h
index ef387964a0..ce9a4cc90b 100644
--- a/src/soundsourceproxy.h
+++ b/src/soundsourceproxy.h
@@ -48,6 +48,7 @@ public:
unsigned read(unsigned long size, const SAMPLE*);
long unsigned length();
Result parseHeader();
+ QImage parseCoverArt();
unsigned int getSampleRate();
/** Returns filename */
QString getFilename();
diff --git a/src/soundsourcesndfile.cpp b/src/soundsourcesndfile.cpp
index 49bb283457..f8d780fee0 100644
--- a/src/soundsourcesndfile.cpp
+++ b/src/soundsourcesndfile.cpp
@@ -225,6 +225,38 @@ Result SoundSourceSndFile::parseHeader()
return result ? OK : ERR;
}
+QImage SoundSourceSndFile::parseCoverArt() {
+ QImage coverArt;
+ QString location = getFilename();
+ setType(location.section(".",-1).toLower());
+ QByteArray qBAFilename = m_qFilename.toLocal8Bit();
+
+ if (getType() == "flac") {
+ TagLib::FLAC::File f(qBAFilename.constData());
+ coverArt = getCoverInID3v2Tag(f.ID3v2Tag());
+ if (coverArt.isNull()) {
+ coverArt = getCoverInXiphComment(f.xiphComment());
+ }
+ if (coverArt.isNull()) {
+ TagLib::List<TagLib::FLAC::Picture*> covers = f.pictureList();
+ if (!covers.isEmpty()) {
+ std::list<TagLib::FLAC::Picture*>::iterator it = covers.begin();
+ TagLib::FLAC::Picture* cover = *it;
+ coverArt = QImage::fromData(
+ QByteArray(cover->data().data(), cover->data().size()));
+ }
+ }
+ } else if (getType() == "wav") {
+ TagLib::RIFF::WAV::File f(qBAFilename.constData());
+ coverArt = getCoverInID3v2Tag(f.tag());
+ } else {
+ // Try AIFF
+ TagLib::RIFF::AIFF::File f(qBAFilename.constData());
+ coverArt = getCoverInID3v2Tag(f.tag());
+ }
+ return coverArt;
+}
+
/*
Return the length of the file in samples.
*/
diff --git a/src/soundsourcesndfile.h b/src/soundsourcesndfile.h
index 9d610ce400..a5907f296e 100644
--- a/src/soundsourcesndfile.h
+++ b/src/soundsourcesndfile.h
@@ -38,6 +38,7 @@ public:
unsigned read(unsigned long size, const SAMPLE*);
inline long unsigned length();
Result parseHeader();
+ QImage parseCoverArt();
static QList<QString> supportedFileExtensions();
private:
diff --git a/src/test/coverartcache_test.cpp b/src/test/coverartcache_test.cpp
index 9c4ae3c3e8..b84baddddb 100644
--- a/src/test/coverartcache_test.cpp
+++ b/src/test/coverartcache_test.cpp
@@ -88,8 +88,8 @@ TEST_F(CoverArtCacheTest, loadImage) {
QDir(kTrackLocationTest), true);
SoundSourceProxy proxy(kTrackLocationTest, securityToken);
Mixxx::SoundSource* pProxiedSoundSource = proxy.getProxiedSoundSource();
- ASSERT_TRUE(pProxiedSoundSource != NULL && proxy.parseHeader() == OK);
- img = pProxiedSoundSource->getCoverArt();
+ ASSERT_TRUE(pProxiedSoundSource != NULL);
+ img = proxy.parseCoverArt();
EXPECT_TRUE(img.operator==(res.img));
}
@@ -157,8 +157,8 @@ TEST_F(CoverArtCacheTest, searchImage) {
QDir(kTrackLocationTest), true);
SoundSourceProxy proxy(kTrackLocationTest, securityToken);
Mixxx::SoundSource* pProxiedSoundSource = proxy.getProxiedSoundSource();
- ASSERT_TRUE(pProxiedSoundSource != NULL && proxy.parseHeader() == OK);
- QImage img = pProxiedSoundSource->getCoverArt();
+ ASSERT_TRUE(pProxiedSoundSource != NULL);
+ QImage img = proxy.parseCoverArt();
EXPECT_TRUE(img.operator==(res.img));