When downloading images, dont use extension to determine file format, instead look JFIF and PNG in first few data bytes.

BUG: 378
This commit is contained in:
craig.p.drummond
2014-01-07 20:02:40 +00:00
parent e54cd69a83
commit 84a1fa0de0
7 changed files with 44 additions and 33 deletions

View File

@@ -42,6 +42,9 @@
22. Set cover-widget icon size to at least twice tab-widget large icon size.
23. Remove usage of Gtk-style on-off button for Gtk style, and instead give
checkboxes better text and adjust config layout.
24. Better control over 'Subscribe' button in podcast search dialog.
25. When downloading images, dont use extension to determine file format,
instead look JFIF and PNG in first few data bytes.
1.2.2
-----

View File

@@ -544,17 +544,17 @@ void CoverDialog::downloadJobFinished()
QString host=reply->property(constHostProperty).toString();
QString url=reply->url().toString();
QByteArray data=reply->readAll();
FileType fileType=url.endsWith(".jpg") || url.endsWith(".jpeg") ? FT_Jpg : (url.endsWith(".png") ? FT_Png : FT_Other);
QImage img=QImage::fromData(data, FT_Jpg==fileType ? "JPG" : (FT_Png==fileType ? "PNG" : 0));
const char *format=Covers::imageFormat(data);
QImage img=QImage::fromData(data, format);
if (!img.isNull()) {
bool isLarge=reply->property(constThumbProperty).toString().isEmpty();
QTemporaryFile *temp=0;
if (isLarge || (reply->property(constThumbProperty).toString()==reply->property(constLargeProperty).toString())) {
temp=new QTemporaryFile(QDir::tempPath()+"/cantata_XXXXXX."+(FT_Jpg==fileType ? "jpg" : "png"));
temp=new QTemporaryFile(QDir::tempPath()+"/cantata_XXXXXX."+(format ? QString(QLatin1String(format)).toLower() : "png"));
if (temp->open()) {
if (FT_Other==fileType) {
if (!format) {
img.save(temp, "PNG");
} else {
temp->write(data);

View File

@@ -89,12 +89,6 @@ public:
DL_LargeSave
};
enum FileType {
FT_Jpg,
FT_Png,
FT_Other
};
CoverDialog(QWidget *parent);
virtual ~CoverDialog();

View File

@@ -96,9 +96,9 @@ static bool canSaveTo(const QString &dir)
static const QString typeFromRaw(const QByteArray &raw)
{
if (raw.size()>9 && /*raw[0]==0xFF && raw[1]==0xD8 && raw[2]==0xFF*/ raw[6]=='J' && raw[7]=='F' && raw[8]=='I' && raw[9]=='F') {
if (Covers::isJpg((raw))) {
return constExtensions[0];
} else if (raw.size()>4 && /*raw[0]==0x89 &&*/ raw[1]=='P' && raw[2]=='N' && raw[3]=='G') {
} else if (Covers::isPng(raw)) {
return constExtensions[1];
}
return QString();
@@ -229,6 +229,21 @@ bool Covers::saveScaledCover(const QImage &img, const QString &artist, const QSt
return status;
}
bool Covers::isJpg(const QByteArray &data)
{
return data.size()>9 && /*data[0]==0xFF && data[1]==0xD8 && data[2]==0xFF*/ data[6]=='J' && data[7]=='F' && data[8]=='I' && data[9]=='F';
}
bool Covers::isPng(const QByteArray &data)
{
return data.size()>4 && /*data[0]==0x89 &&*/ data[1]=='P' && data[2]=='N' && data[3]=='G';
}
const char * Covers::imageFormat(const QByteArray &data)
{
return isJpg(data) ? "JPG" : (isPng(data) ? "PNG" : 0);
}
QString Covers::encodeName(QString name)
{
name.replace("/", "_");
@@ -651,10 +666,8 @@ void CoverDownloader::jobFinished()
if (it!=end) {
QByteArray data=reply->ok() ? reply->readAll() : QByteArray();
QString url=reply->url().toString();
Covers::Image img;
img.img= data.isEmpty() ? QImage() : QImage::fromData(data, url.endsWith(".jpg", Qt::CaseInsensitive) || url.endsWith(".jpeg", Qt::CaseInsensitive)
? "JPG" : (url.endsWith(".png", Qt::CaseInsensitive) ? "PNG" : 0));
img.img= data.isEmpty() ? QImage() : QImage::fromData(data, Covers::imageFormat(data));
Job job=it.value();
if (!img.img.isNull() && img.img.size().width()<32) {

View File

@@ -171,6 +171,9 @@ public:
static QString fixArtist(const QString &artist);
static QPixmap * getScaledCover(const QString &artist, const QString &album, int size);
static bool saveScaledCover(const QImage &img, const QString &artist, const QString &album, int size);
static bool isJpg(const QByteArray &data);
static bool isPng(const QByteArray &data);
static const char * imageFormat(const QByteArray &data);
Covers();
void readConfig();

View File

@@ -552,18 +552,18 @@ void OnlineServicesModel::imageDownloaded()
}
QString url=j->url().toString();
bool png=url.endsWith(".png", Qt::CaseInsensitive);
QImage img=QImage::fromData(data, png ? "PNG" : "JPG");
QImage img=QImage::fromData(data, Covers::imageFormat(data));
if (img.isNull()) {
DBUG << url << "null image";
return;
}
bool png=Covers::isPng(data);
QString id=j->property(constIdProperty).toString();
Song song;
song.albumartist=song.artist=j->property(constArtistProperty).toString();
song.album=j->property(constAlbumProperty).toString();
DBUG << "Got image" << id << song.artist << song.album;
DBUG << "Got image" << id << song.artist << song.album << png;
OnlineService *srv=service(id);
if (id==PodcastService::constName) {
MusicLibraryItem *podcast=srv->childItem(song.artist);
@@ -599,21 +599,18 @@ void OnlineServicesModel::imageDownloaded()
? Utils::cacheDir(id.toLower(), true)+Covers::encodeName(song.album.isEmpty() ? song.artist : (song.artist+" - "+song.album))+(png ? ".png" : ".jpg")
: cacheName);
if (maxSize>0 || !cacheName.isEmpty()) {
QImage img=QImage::fromData(data, png ? "PNG" : "JPG");
if (!img.isNull()) {
if (maxSize>32 && (img.width()>maxSize || img.height()>maxSize)) {
img=img.scaled(maxSize, maxSize, Qt::KeepAspectRatio, Qt::SmoothTransformation);
}
DBUG << "Saved scaled image to" << fileName << maxSize;
img.save(fileName);
if (!song.album.isEmpty()) {
song.track=1;
song.setKey();
Covers::self()->emitCoverUpdated(song, img, fileName);
}
return;
if (!img.isNull() && (maxSize>0 || !cacheName.isEmpty())) {
if (maxSize>32 && (img.width()>maxSize || img.height()>maxSize)) {
img=img.scaled(maxSize, maxSize, Qt::KeepAspectRatio, Qt::SmoothTransformation);
}
DBUG << "Saved scaled image to" << fileName << maxSize;
img.save(fileName);
if (!song.album.isEmpty()) {
song.track=1;
song.setKey();
Covers::self()->emitCoverUpdated(song, img, fileName);
}
return;
}
QFile f(fileName);
if (f.open(QIODevice::WriteOnly)) {

View File

@@ -279,7 +279,8 @@ void PodcastPage::imageJobFinished()
if (imageSpinner) {
imageSpinner->stop();
}
QImage img=QImage::fromData(imageJob->readAll());
QByteArray data=imageJob->readAll();
QImage img=QImage::fromData(data, Covers::imageFormat(data));
if (!img.isNull()) {
if (img.width()>maxImageSize || img.height()>maxImageSize) {
img=img.scaled(maxImageSize, maxImageSize, Qt::KeepAspectRatio, Qt::SmoothTransformation);