From 05381eb7e06a778e47aee13c96bc6b4282e923ec Mon Sep 17 00:00:00 2001 From: "Robert C. Helling" Date: Thu, 19 Feb 2015 18:23:24 +0100 Subject: [PATCH 1/4] Add hashes to pictures This adds SHA1 hashes to successfully loaded images and saves those to xml. Signed-off-by: Robert C. Helling --- dive.c | 2 ++ dive.h | 1 + parse-xml.c | 2 ++ qt-ui/divepicturewidget.cpp | 43 +++++++++++++++++++++++++++++++------------ qt-ui/divepicturewidget.h | 7 +++++++ qt-ui/mainwindow.h | 4 ++++ qthelper.cpp | 6 ++++++ qthelper.h | 1 - save-xml.c | 5 +++++ 9 files changed, 58 insertions(+), 13 deletions(-) diff --git a/dive.c b/dive.c index 7583686..fc0fbb8 100644 --- a/dive.c +++ b/dive.c @@ -392,6 +392,7 @@ static void copy_pl(struct picture *sp, struct picture *dp) { *dp = *sp; dp->filename = copy_string(sp->filename); + dp->hash = copy_string(sp->hash); } /* copy an element in a list of tags */ @@ -2936,6 +2937,7 @@ static void picture_free(struct picture *p) if (!p) return; free(p->filename); + free(p->hash); free(p); } void dive_remove_picture(char *filename) diff --git a/dive.h b/dive.h index 8247a5f..653b113 100644 --- a/dive.h +++ b/dive.h @@ -364,6 +364,7 @@ struct dive_components { /* picture list and methods related to dive picture handling */ struct picture { char *filename; + char *hash; offset_t offset; degrees_t latitude; degrees_t longitude; diff --git a/parse-xml.c b/parse-xml.c index 1ac2b41..a957102 100644 --- a/parse-xml.c +++ b/parse-xml.c @@ -1294,6 +1294,8 @@ static void try_to_fill_dive(struct dive *dive, const char *name, char *buf) return; if (MATCH("gps.picture", gps_picture_location, cur_picture)) return; + if (MATCH("hash.picture", utf8_string, &cur_picture->hash)) + return; if (MATCH("cylinderstartpressure", pressure, &dive->cylinder[0].start)) return; if (MATCH("cylinderendpressure", pressure, &dive->cylinder[0].end)) diff --git a/qt-ui/divepicturewidget.cpp b/qt-ui/divepicturewidget.cpp index 92695b6..4a205da 100644 --- a/qt-ui/divepicturewidget.cpp +++ b/qt-ui/divepicturewidget.cpp @@ -4,6 +4,23 @@ #include "divelist.h" #include #include +#include +#include + +SHashedImage::SHashedImage(struct picture *picture) : QImage(picture->filename) +{ + if (isNull()) { + // Hash lookup. + } else { + QCryptographicHash hash(QCryptographicHash::Sha1); + QFile imagefile(picture->filename); + imagefile.open(QIODevice::ReadOnly); + hash.addData(&imagefile); + free(picture->hash); + picture->hash = strdup(hash.result().toHex().data()); + MainWindow::instance()->hashOf.insert(QString(picture->filename), hash.result()); + } +} DivePictureModel *DivePictureModel::instance() { @@ -15,20 +32,21 @@ DivePictureModel::DivePictureModel() : numberOfPictures(0) { } -typedef QPair SPixmap; -typedef QList SPixmapList; +typedef struct picture *picturepointer; +typedef QPair SPixmap; +typedef QList SPictureList; -SPixmap scaleImages(const QString &s) +SPixmap scaleImages(picturepointer picture) { static QHash cache; SPixmap ret; - ret.first = s; - if (cache.contains(s)) { - ret.second = cache.value(s); + ret.first = picture; + if (cache.contains(picture->filename)) { + ret.second = cache.value(picture->filename); } else { int dim = defaultIconMetrics().sz_pic; - QImage p = QImage(s).scaled(dim, dim, Qt::KeepAspectRatio); - cache.insert(s, p); + QImage p = SHashedImage(picture).scaled(dim, dim, Qt::KeepAspectRatio); + cache.insert(picture->filename, p); ret.second = p; } return ret; @@ -49,14 +67,15 @@ void DivePictureModel::updateDivePictures() } stringPixmapCache.clear(); - QStringList pictures; + SPictureList pictures; FOR_EACH_PICTURE_NON_PTR(displayed_dive) { stringPixmapCache[QString(picture->filename)].offsetSeconds = picture->offset.seconds; - pictures.push_back(QString(picture->filename)); + pictures.push_back(picture); } - Q_FOREACH (const SPixmap &pixmap, QtConcurrent::blockingMapped(pictures, scaleImages)) - stringPixmapCache[pixmap.first].image = pixmap.second; + QList list = QtConcurrent::blockingMapped(pictures, scaleImages); + Q_FOREACH (const SPixmap &pixmap, list) + stringPixmapCache[pixmap.first->filename].image = pixmap.second; beginInsertRows(QModelIndex(), 0, numberOfPictures - 1); endInsertRows(); diff --git a/qt-ui/divepicturewidget.h b/qt-ui/divepicturewidget.h index aa524e1..e8104a1 100644 --- a/qt-ui/divepicturewidget.h +++ b/qt-ui/divepicturewidget.h @@ -5,11 +5,18 @@ #include #include +typedef QPair SHashedFilename; + struct PhotoHelper { QImage image; int offsetSeconds; }; +class SHashedImage : public QImage { +public: + SHashedImage(struct picture *picture); +}; + class DivePictureModel : public QAbstractTableModel { Q_OBJECT public: diff --git a/qt-ui/mainwindow.h b/qt-ui/mainwindow.h index 85a6312..1782953 100644 --- a/qt-ui/mainwindow.h +++ b/qt-ui/mainwindow.h @@ -11,6 +11,7 @@ #include #include #include +#include #include "ui_mainwindow.h" @@ -91,6 +92,9 @@ public: void checkSurvey(QSettings *s); void setApplicationState(const QByteArray& state); QUndoStack *undoStack; + QHash hashOf; + QHash localFilenameOf; + private slots: /* file menu action */ diff --git a/qthelper.cpp b/qthelper.cpp index b26bdf4..d449268 100644 --- a/qthelper.cpp +++ b/qthelper.cpp @@ -5,6 +5,7 @@ #include "subsurfacewebservices.h" #include "usersurvey.h" #include "membuffer.h" +#include "mainwindow.h" #include #include "file.h" #include @@ -401,3 +402,8 @@ extern "C" void reverseGeoLookup(degrees_t latitude, degrees_t longitude, uint32 ds->notes = add_to_string(ds->notes, "countrytag: %s", address.value("country").toString().toUtf8().data()); } } + +extern "C" char * hashstring(char * filename) +{ + return MainWindow::instance()->hashOf[QString(filename)].toHex().data(); +} diff --git a/qthelper.h b/qthelper.h index a367a9d..61e968c 100644 --- a/qthelper.h +++ b/qthelper.h @@ -16,5 +16,4 @@ bool gpsHasChanged(struct dive *dive, struct dive *master, const QString &gps_te extern "C" const char *printGPSCoords(int lat, int lon); QList getDivesInTrip(dive_trip_t *trip); QString gasToStr(struct gasmix gas); - #endif // QTHELPER_H diff --git a/save-xml.c b/save-xml.c index d5f1e15..f5e1d5e 100644 --- a/save-xml.c +++ b/save-xml.c @@ -359,6 +359,8 @@ static void save_dc(struct membuffer *b, struct dive *dive, struct divecomputer put_format(b, " \n"); } +extern char * hashstring(char * filename); + static void save_picture(struct membuffer *b, struct picture *pic) { put_string(b, " longitude, "", "'"); } + if (hashstring(pic->filename)) + put_format(b, " hash='%s'", hashstring(pic->filename)); + put_string(b, "/>\n"); } -- 1.9.3 (Apple Git-50)