aboutsummaryrefslogtreecommitdiffstats
path: root/qt-models/divepicturemodel.cpp
diff options
context:
space:
mode:
authorGravatar Berthold Stoeger <bstoeger@mail.tuwien.ac.at>2018-04-29 23:07:05 +0300
committerGravatar Dirk Hohndel <dirk@hohndel.org>2018-05-13 13:52:35 -0700
commit6618c9ebfc6a7cebbef687fcb3aa74c70f504ff2 (patch)
treefcb8930645e83c79236bb5a5a0b0a77bf0210f6e /qt-models/divepicturemodel.cpp
parentc0bca3ad04762a7178bda37be4c2ed87ae7e5f4e (diff)
downloadsubsurface-6618c9ebfc6a7cebbef687fcb3aa74c70f504ff2.tar.gz
Dive pictures: save thumbnails to individual files
The old code loaded all thumbnails into memory at once. This does not scale to logs with thousands of pictures. Therefore, save the pictures to individual files and only load the currently needed pictures. Currently, this will make changing switching between dives slower, because the thumbnails are loaded from disk. In the future, it is planned to do this in a background thread without blocking the user interface. A notable difference to the old code: Thumbnails are now indexed by the image-hash (i.e. the content of the raw image) and not by the filename of the image. Thus, different paths to the same image should only be saved once. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Diffstat (limited to 'qt-models/divepicturemodel.cpp')
-rw-r--r--qt-models/divepicturemodel.cpp52
1 files changed, 46 insertions, 6 deletions
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;