2 * SomePlayer - An alternate music player for Maemo 5
3 * Copyright (C) 2010 Nikolay (somebody) Tischenko <niktischenko@gmail.com>
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21 #include "coverfinder.h"
25 #include <QtConcurrentRun>
30 #include <mpeg/id3v2/frames/attachedpictureframe.h>
32 using namespace SomePlayer::DataObjects;
34 CoverFinder::CoverFinder(QObject *parent) :
37 _defaultCover = QImage(":/images/defaultcover.png");
38 SUFFIXES << "png" << "jpg" << "jpeg" << "bmp" << "gif";
39 NAMES << "cover" << "folder" << "album";
40 DIRS << "cover" << "folder" << ".cover" << ".folder";
41 PRIOR_NAMES << "front" << "cover";
42 UNPRIOR_NAMES << "disk" << "back" << "booklet" << "cd";
45 bool CoverFinder::_find(QString path) {
47 QFileInfoList items = dir.entryInfoList(QDir::Files);
48 QFileInfoList dirs = dir.entryInfoList(QDir::NoDotAndDotDot | QDir::AllDirs | QDir::Hidden);
50 QFileInfoList appropriate_pics;
51 foreach (QFileInfo item, items) {
52 if (SUFFIXES.contains(item.suffix().toLower())) {
54 if (NAMES.contains(item.baseName().toLower())) {
55 emit found(QImage(item.absoluteFilePath()));
56 emit foundPath(item.absoluteFilePath());
61 foreach (QFileInfo item, pics) {
62 QImage i(item.absoluteFilePath());
63 if (0.8 <= (i.width()*1.0/(i.height()+1.0)) <= 1.2) {
64 appropriate_pics << item;
67 if (!appropriate_pics.isEmpty()) {
68 foreach (QString name, PRIOR_NAMES) {
69 foreach (QFileInfo item, appropriate_pics) {
70 if (item.baseName().toLower().contains(name)) {
71 emit found(QImage(item.absoluteFilePath()));
72 emit foundPath(item.absoluteFilePath());
77 QFileInfoList unprior;
78 foreach (QString name, UNPRIOR_NAMES) {
79 foreach (QFileInfo item, appropriate_pics) {
80 if (item.baseName().toLower().contains(name)) {
85 if (appropriate_pics.size() > unprior.size()) {
86 foreach (QFileInfo item, appropriate_pics) {
87 if (!unprior.contains(item)) {
88 emit found(QImage(item.absoluteFilePath()));
89 emit foundPath(item.absoluteFilePath());
94 emit found(QImage(unprior.at(0).absoluteFilePath()));
95 emit foundPath(unprior.at(0).absoluteFilePath());
98 foreach(QFileInfo item, dirs) {
99 if (DIRS.contains(item.fileName().toLower())) {
100 if (_find(item.absoluteFilePath())) {
108 QImage &CoverFinder::defaultCover() {
109 return _defaultCover;
112 bool CoverFinder::_extract(QString file) {
113 QFileInfo info(file);
114 QString suffix = info.suffix().toLower();
115 TagLib::ID3v2::Tag *tag = NULL;
117 TagLib::File *f = NULL;
118 if (suffix == "mp3") {
119 f = new TagLib::MPEG::File(QFile::encodeName(file).data(), true, TagLib::AudioProperties::Fast);
120 if (f == NULL) return false;
121 tag = ((TagLib::MPEG::File*)f)->ID3v2Tag();
123 } else if (suffix == "flac") {
124 f = new TagLib::FLAC::File(QFile::encodeName(file).data(), true, TagLib::AudioProperties::Fast);
125 if (f == NULL) return false;
126 tag = ((TagLib::FLAC::File*)f)->ID3v2Tag();
129 if (todo && tag != NULL) {
130 TagLib::ID3v2::FrameList l = tag->frameList("APIC");
133 TagLib::ID3v2::AttachedPictureFrame *pic = static_cast<TagLib::ID3v2::AttachedPictureFrame *>(l.front());
135 img.loadFromData((const uchar *) pic->picture().data(), pic->picture().size());
139 if (f != NULL) delete f;
143 void CoverFinder::find(Track track) {
144 QFileInfo filePath(track.source());
145 QtConcurrent::run(this, &CoverFinder::_async_find, filePath, track);
148 bool CoverFinder::_async_find(QFileInfo filePath, Track track) {
149 if (!_find(filePath.absolutePath()) && !_tfind(track.metadata().artist(), track.metadata().album()) &&
150 !_malfind(filePath.absolutePath()+"/.mediaartlocal/"+track.mediaArtLocal()) &&
151 !_extract(filePath.absoluteFilePath())) {
152 emit found(_defaultCover);
158 bool CoverFinder::_tfind(QString artist, QString album) {
159 QString aname = artist.toLower();
160 QString aalbum = album.toLower();
161 aname.replace("/", "");
162 QString aaname = aname+" - "+aalbum;
163 aaname.replace("/", "");
164 QString fname1 = QDir::homePath()+"/.covers/"+aaname+".jpg";
165 QString fname2 = QDir::homePath()+"/.covers/"+aname+".jpg";
166 if (QFile::exists(fname1)) {
167 emit found(QImage(fname1));
168 emit foundPath(fname1);
170 } else if (QFile::exists(fname2)) {
171 emit found(QImage(fname2));
172 emit foundPath(fname2);
178 bool CoverFinder::_malfind(QString path) {
179 if (QFile::exists(path)) {
180 emit found(QImage(path));
181 emit foundPath(path);