diff options
-rw-r--r-- | core/qthelper.cpp | 22 | ||||
-rw-r--r-- | core/qthelper.h | 1 | ||||
-rw-r--r-- | qt-models/divepicturemodel.cpp | 52 |
3 files changed, 66 insertions, 9 deletions
diff --git a/core/qthelper.cpp b/core/qthelper.cpp index fb32fabe5..55015d226 100644 --- a/core/qthelper.cpp +++ b/core/qthelper.cpp @@ -1054,7 +1054,6 @@ extern "C" void reverseGeoLookup(degrees_t latitude, degrees_t longitude, uint32 QHash<QString, QByteArray> hashOf; QMutex hashOfMutex; QHash<QByteArray, QString> localFilenameOf; -QHash <QString, QImage > thumbnailCache; static QByteArray getHash(const QString &filename) { @@ -1077,6 +1076,19 @@ const QString hashfile_name() return QString(system_default_directory()).append("/hashes"); } +static QString thumbnailDir() +{ + return QString(system_default_directory()) + "/thumbnails/"; +} + +// Return filename of thumbnail if it is known to us. +// If this is an unknown thumbnail, return an empty string. +QString thumbnailFileName(const QString &filename) +{ + QString hash = getHash(filename).toHex(); + return hash.isEmpty() ? QString() : thumbnailDir() + hash; +} + extern "C" char *hashfile_name_string() { return copy_qstring(hashfile_name()); @@ -1090,7 +1102,8 @@ void read_hashes() QDataStream stream(&hashfile); stream >> localFilenameOf; stream >> hashOf; - stream >> thumbnailCache; + QHash <QString, QImage> thumbnailCache; + stream >> thumbnailCache; // For backwards compatibility hashfile.close(); } localFilenameOf.remove(""); @@ -1100,6 +1113,9 @@ void read_hashes() if (iter.value().isEmpty()) iter.remove(); } + + // Make sure that the thumbnail directory exists + QDir().mkpath(thumbnailDir()); } void write_hashes() @@ -1111,7 +1127,7 @@ void write_hashes() QDataStream stream(&hashfile); stream << localFilenameOf; stream << hashOf; - stream << thumbnailCache; + stream << QHash<QString,QImage>(); // Empty thumbnailCache - for backwards compatibility hashfile.commit(); } else { qWarning() << "Cannot open hashfile for writing: " << hashfile.fileName(); diff --git a/core/qthelper.h b/core/qthelper.h index 4c0dcda66..ac1de4df8 100644 --- a/core/qthelper.h +++ b/core/qthelper.h @@ -30,6 +30,7 @@ void write_hashes(); void updateHash(struct picture *picture); QByteArray hashFile(const QString &filename); QString hashString(const char *filename); +QString thumbnailFileName(const QString &filename); void learnImages(const QDir dir, int max_recursions); void add_hash(const QString &filename, const QByteArray &hash); void hashPicture(struct picture *picture); diff --git a/qt-models/divepicturemodel.cpp b/qt-models/divepicturemodel.cpp index b27799c67..e92a16bd0 100644 --- a/qt-models/divepicturemodel.cpp +++ b/qt-models/divepicturemodel.cpp @@ -4,17 +4,58 @@ #include "core/metrics.h" #include "core/divelist.h" #include "core/imagedownloader.h" +#include "core/qthelper.h" +#include "core/metadata.h" #include <QtConcurrent> -extern QHash <QString, QImage> thumbnailCache; -static QMutex thumbnailMutex; static const int maxZoom = 3; // Maximum zoom: thrice of standard size static QImage getThumbnailFromCache(const PictureEntry &entry) { - QMutexLocker l(&thumbnailMutex); - return thumbnailCache.value(entry.filename); + // First, check if we know a hash for this filename + QString filename = thumbnailFileName(entry.filename); + if (filename.isEmpty()) + return QImage(); + + QFile file(filename); + if (!file.open(QIODevice::ReadOnly)) + return QImage(); + QDataStream stream(&file); + + // Each thumbnail file is composed of a media-type and an image file. + // Currently, the type is ignored. This will be used to mark videos. + quint32 type; + QImage res; + stream >> type; + stream >> res; + return res; +} + +static void addThumbnailToCache(const QImage &thumbnail, const PictureEntry &entry) +{ + if (thumbnail.isNull()) + return; + + QString filename = thumbnailFileName(entry.filename); + + // If we got a thumbnail, we are guaranteed to have its hash and therefore + // thumbnailFileName() should return a filename. + if (filename.isEmpty()) { + qWarning() << "Internal error: can't get filename of recently created thumbnail"; + return; + } + + QSaveFile file(filename); + if (!file.open(QIODevice::WriteOnly)) + return; + QDataStream stream(&file); + + // For format of the file, see comments in getThumnailForCache + quint32 type = MEDIATYPE_PICTURE; + stream << type; + stream << thumbnail; + file.commit(); } static void scaleImages(PictureEntry &entry, int maxSize) @@ -25,8 +66,7 @@ static void scaleImages(PictureEntry &entry, int maxSize) if (thumbnail.isNull() || (thumbnail.size().width() < maxSize && thumbnail.size().height() < maxSize)) { qDebug() << "No thumbnail in cache for" << entry.filename; thumbnail = SHashedImage(entry.picture).scaled(maxSize, maxSize, Qt::KeepAspectRatio); - QMutexLocker l(&thumbnailMutex); - thumbnailCache.insert(entry.filename, thumbnail); + addThumbnailToCache(thumbnail, entry); } entry.image = thumbnail; |