diff options
Diffstat (limited to 'core/imagedownloader.cpp')
-rw-r--r-- | core/imagedownloader.cpp | 90 |
1 files changed, 44 insertions, 46 deletions
diff --git a/core/imagedownloader.cpp b/core/imagedownloader.cpp index fd155bec6..7dc35695d 100644 --- a/core/imagedownloader.cpp +++ b/core/imagedownloader.cpp @@ -93,40 +93,36 @@ Thumbnailer::Thumbnail Thumbnailer::fetchImage(const QString &filename, const QS mediatype_t type = get_metadata(qPrintable(filename), &md); // For io error or video, return early with the appropriate dummy-icon. - if (type == MEDIATYPE_IO_ERROR) { - return { failImage, MEDIATYPE_IO_ERROR }; - } else if (type == MEDIATYPE_VIDEO) { - addVideoThumbnailToCache(originalFilename, md.duration); - return { videoImage, MEDIATYPE_VIDEO }; - } + if (type == MEDIATYPE_IO_ERROR) + return { failImage, MEDIATYPE_IO_ERROR, 0 }; + else if (type == MEDIATYPE_VIDEO) + return addVideoThumbnailToCache(originalFilename, md.duration); // Try if Qt can parse this image. If it does, use this as a thumbnail. QImage thumb(filename); if (!thumb.isNull()) { - addPictureThumbnailToCache(originalFilename, thumb); - return { thumb, MEDIATYPE_PICTURE }; + int size = maxThumbnailSize(); + thumb = thumb.scaled(size, size, Qt::KeepAspectRatio); + return addPictureThumbnailToCache(originalFilename, thumb); } // Neither our code, nor Qt could determine the type of this object from looking at the data. // Try to check for a video-file extension. Since we couldn't parse the video file, // we pass 0 as the duration. - if (hasVideoFileExtension(filename)) { - addVideoThumbnailToCache(originalFilename, {0} ); - return { videoImage, MEDIATYPE_VIDEO }; - } + if (hasVideoFileExtension(filename)) + return addVideoThumbnailToCache(originalFilename, {0} ); // Give up: we simply couldn't determine what this thing is. // But since we managed to read this file, mark this file in the cache as unknown. - addUnknownThumbnailToCache(originalFilename); - return { unknownImage, MEDIATYPE_UNKNOWN }; + return addUnknownThumbnailToCache(originalFilename); } else if (tryDownload) { // This has to be done in UI main thread, because QNetworkManager refuses // to treat requests from other threads. invokeMethod() is Qt's way of calling a // function in a different thread, namely the thread the called object is associated to. QMetaObject::invokeMethod(ImageDownloader::instance(), "load", Qt::AutoConnection, Q_ARG(QUrl, url), Q_ARG(QString, originalFilename)); - return { QImage(), MEDIATYPE_STILL_LOADING }; + return { QImage(), MEDIATYPE_STILL_LOADING, 0 }; } - return { QImage(), MEDIATYPE_IO_ERROR }; + return { QImage(), MEDIATYPE_IO_ERROR, 0 }; } // Fetch a picture based on its original filename. If there is a translated filename (obtained either @@ -142,7 +138,7 @@ Thumbnailer::Thumbnail Thumbnailer::getHashedImage(const QString &filename, bool // If there is a translated filename, try that first. // Note that we set the default type to io-error, so that if we didn't try // the local filename first, we will load the file from the canonical filename. - Thumbnail thumbnail { QImage(), MEDIATYPE_IO_ERROR }; + Thumbnail thumbnail { QImage(), MEDIATYPE_IO_ERROR, 0 }; if (localFilename != filename) thumbnail = fetchImage(localFilename, filename, tryDownload); @@ -199,7 +195,9 @@ Thumbnailer::Thumbnail Thumbnailer::getVideoThumbnailFromStream(QDataStream &str // If reading did not succeed, schedule for recalculation - this thumbnail might // have been written by an older version, which couldn't extract the duration. - if (stream.status() != QDataStream::Ok) + // Likewise test the duration and number of pictures for sanity (no videos longer than 10 h, + // no more than 10000 pictures). + if (stream.status() != QDataStream::Ok || duration > 36000 || numPics > 10000) return { QImage(), MEDIATYPE_VIDEO, 0 }; // Currently, we support only one picture @@ -211,7 +209,7 @@ Thumbnailer::Thumbnail Thumbnailer::getVideoThumbnailFromStream(QDataStream &str } // No picture -> show dummy-icon - return { res.isNull() ? videoImage : res, MEDIATYPE_VIDEO, {(int32_t)duration} }; + return { res.isNull() ? videoImage : res, MEDIATYPE_VIDEO, (int32_t)duration }; } // Fetch a thumbnail from cache. @@ -220,7 +218,7 @@ Thumbnailer::Thumbnail Thumbnailer::getThumbnailFromCache(const QString &picture { QString filename = thumbnailFileName(picture_filename); if (filename.isEmpty()) - return { QImage(), MEDIATYPE_UNKNOWN }; + return { QImage(), MEDIATYPE_UNKNOWN, 0 }; QFile file(filename); if (prefs.auto_recalculate_thumbnails) { @@ -256,7 +254,7 @@ Thumbnailer::Thumbnail Thumbnailer::getThumbnailFromCache(const QString &picture } } -void Thumbnailer::addVideoThumbnailToCache(const QString &picture_filename, duration_t duration) +Thumbnailer::Thumbnail Thumbnailer::addVideoThumbnailToCache(const QString &picture_filename, duration_t duration) { // The format of video thumbnails: // uint32 MEDIATYPE_VIDEO @@ -267,43 +265,43 @@ void Thumbnailer::addVideoThumbnailToCache(const QString &picture_filename, dura // QImage frame QString filename = thumbnailFileName(picture_filename); QSaveFile file(filename); - if (!file.open(QIODevice::WriteOnly)) - return; - QDataStream stream(&file); + if (file.open(QIODevice::WriteOnly)) { + QDataStream stream(&file); - stream << (quint32)MEDIATYPE_VIDEO; - stream << (quint32)duration.seconds; - stream << (quint32)0; // Currently, we don't support extraction of images - file.commit(); + stream << (quint32)MEDIATYPE_VIDEO; + stream << (quint32)duration.seconds; + stream << (quint32)0; // Currently, we don't support extraction of images + file.commit(); + } + return { videoImage, MEDIATYPE_VIDEO, duration }; } -void Thumbnailer::addPictureThumbnailToCache(const QString &picture_filename, const QImage &thumbnail) +Thumbnailer::Thumbnail Thumbnailer::addPictureThumbnailToCache(const QString &picture_filename, const QImage &thumbnail) { - if (thumbnail.isNull()) - return; - // The format of a picture-thumbnail is very simple: // uint32 MEDIATYPE_PICTURE // QImage thumbnail QString filename = thumbnailFileName(picture_filename); QSaveFile file(filename); - if (!file.open(QIODevice::WriteOnly)) - return; - QDataStream stream(&file); + if (file.open(QIODevice::WriteOnly)) { + QDataStream stream(&file); - stream << (quint32)MEDIATYPE_PICTURE; - stream << thumbnail; - file.commit(); + stream << (quint32)MEDIATYPE_PICTURE; + stream << thumbnail; + file.commit(); + } + return { thumbnail, MEDIATYPE_PICTURE, 0 }; } -void Thumbnailer::addUnknownThumbnailToCache(const QString &picture_filename) +Thumbnailer::Thumbnail Thumbnailer::addUnknownThumbnailToCache(const QString &picture_filename) { QString filename = thumbnailFileName(picture_filename); QSaveFile file(filename); - if (!file.open(QIODevice::WriteOnly)) - return; - QDataStream stream(&file); - stream << (quint32)MEDIATYPE_UNKNOWN; + if (file.open(QIODevice::WriteOnly)) { + QDataStream stream(&file); + stream << (quint32)MEDIATYPE_UNKNOWN; + } + return { unknownImage, MEDIATYPE_UNKNOWN, 0 }; } void Thumbnailer::recalculate(QString filename) @@ -317,7 +315,7 @@ void Thumbnailer::recalculate(QString filename) return; QMutexLocker l(&lock); - emit thumbnailChanged(filename, thumbnail.img); + emit thumbnailChanged(filename, thumbnail.img, thumbnail.duration); workingOn.remove(filename); } @@ -339,7 +337,7 @@ void Thumbnailer::processItem(QString filename, bool tryDownload) } QMutexLocker l(&lock); - emit thumbnailChanged(filename, thumbnail.img); + emit thumbnailChanged(filename, thumbnail.img, thumbnail.duration); workingOn.remove(filename); } @@ -352,7 +350,7 @@ void Thumbnailer::imageDownloaded(QString filename) void Thumbnailer::imageDownloadFailed(QString filename) { - emit thumbnailChanged(filename, failImage); + emit thumbnailChanged(filename, failImage, duration_t{ 0 }); QMutexLocker l(&lock); workingOn.remove(filename); } |