mirror of
https://github.com/subsurface/subsurface.git
synced 2025-02-19 22:16:15 +00:00
Break picture handling code from C++ to C.
This commit breaks the loading of images that were done in the divelist into smaller bits. A bit of code refactor was done in order to correct the placement of a few methods. ShiftTimesDialog::EpochFromExiv got moved to Exif::epoch dive_add_picture is now used instead of add_event picture_load_exif_data got implemented using the old listview code. dive_set_geodata_from_picture got implemented using the old listview code. Signed-off-by: Tomaz Canabrava <tomaz.canabrava@intel.com> Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This commit is contained in:
parent
13e8aba7da
commit
d95d1735b5
9 changed files with 87 additions and 70 deletions
|
@ -106,6 +106,7 @@ SET(SUBSURFACE_CORE_LIB_SRCS
|
||||||
#dirk ported some core functionality to c++.
|
#dirk ported some core functionality to c++.
|
||||||
qthelper.cpp
|
qthelper.cpp
|
||||||
divecomputer.cpp
|
divecomputer.cpp
|
||||||
|
exif.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
#the interface, in C++
|
#the interface, in C++
|
||||||
|
@ -132,7 +133,6 @@ SET(SUBSURFACE_INTERFACE
|
||||||
qt-ui/starwidget.cpp
|
qt-ui/starwidget.cpp
|
||||||
qt-ui/subsurfacewebservices.cpp
|
qt-ui/subsurfacewebservices.cpp
|
||||||
qt-ui/tableview.cpp
|
qt-ui/tableview.cpp
|
||||||
qt-ui/exif.cpp
|
|
||||||
qt-ui/divelogimportdialog.cpp
|
qt-ui/divelogimportdialog.cpp
|
||||||
qt-ui/tagwidget.cpp
|
qt-ui/tagwidget.cpp
|
||||||
qt-ui/groupedlineedit.cpp
|
qt-ui/groupedlineedit.cpp
|
||||||
|
|
30
dive.c
30
dive.c
|
@ -2260,14 +2260,26 @@ int average_depth(struct diveplan *dive)
|
||||||
return integral / last_time;
|
return integral / last_time;
|
||||||
}
|
}
|
||||||
|
|
||||||
void picture_load_exif_data(struct picture *p)
|
struct picture *alloc_picture()
|
||||||
{
|
{
|
||||||
|
struct picture *pic = malloc(sizeof(struct picture));
|
||||||
|
if (!pic)
|
||||||
|
exit(1);
|
||||||
|
memset(pic, 0, sizeof(struct picture));
|
||||||
|
return pic;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct picture* dive_add_picture(struct dive *d, char *picture)
|
void dive_add_picture(struct dive *d, struct picture *picture)
|
||||||
{
|
{
|
||||||
|
if (d->picture_list == NULL) {
|
||||||
|
d->picture_list = picture;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
struct picture *last = d->picture_list;
|
||||||
|
while( last->next )
|
||||||
|
last = last->next;
|
||||||
|
last->next = picture;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint dive_get_picture_count(struct dive *d)
|
uint dive_get_picture_count(struct dive *d)
|
||||||
|
@ -2278,7 +2290,15 @@ uint dive_get_picture_count(struct dive *d)
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
void dive_remove_picture(struct dive *d, char *picture)
|
void dive_set_geodata_from_picture(struct dive *d, struct picture *pic)
|
||||||
|
{
|
||||||
|
if (!d->latitude.udeg && pic->latitude.udeg) {
|
||||||
|
d->latitude = pic->latitude;
|
||||||
|
d->longitude = pic->longitude;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void dive_remove_picture(struct dive *d, struct picture *p)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
9
dive.h
9
dive.h
|
@ -286,16 +286,21 @@ struct dive {
|
||||||
struct picture {
|
struct picture {
|
||||||
char *filename;
|
char *filename;
|
||||||
time_t timestamp;
|
time_t timestamp;
|
||||||
|
degrees_t latitude;
|
||||||
|
degrees_t longitude;
|
||||||
struct picture *next;
|
struct picture *next;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define FOR_EACH_PICTURE( DIVE ) \
|
#define FOR_EACH_PICTURE( DIVE ) \
|
||||||
for(struct picture *picture = DIVE->picture_list; picture; picture = picture->next)
|
for(struct picture *picture = DIVE->picture_list; picture; picture = picture->next)
|
||||||
|
|
||||||
extern struct picture *dive_add_picture(struct dive *d, char *picture);
|
|
||||||
extern void dive_remove_picture(struct dive *d, char *picture);
|
extern struct picture *alloc_picture();
|
||||||
|
extern void dive_add_picture(struct dive *d, struct picture *pic);
|
||||||
|
extern void dive_remove_picture(struct dive *d, struct picture *pic);
|
||||||
extern uint dive_get_picture_count(struct dive *d);
|
extern uint dive_get_picture_count(struct dive *d);
|
||||||
extern void picture_load_exif_data(struct picture *p);
|
extern void picture_load_exif_data(struct picture *p);
|
||||||
|
extern void dive_set_geodata_from_picture(struct dive *d, struct picture *pic);
|
||||||
|
|
||||||
|
|
||||||
static inline int dive_has_gps_location(struct dive *dive)
|
static inline int dive_has_gps_location(struct dive *dive)
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include "dive.h"
|
||||||
#include "exif.h"
|
#include "exif.h"
|
||||||
|
|
||||||
using std::string;
|
using std::string;
|
||||||
|
@ -566,3 +567,21 @@ void EXIFInfo::clear()
|
||||||
GeoLocation.LonComponents.seconds = 0;
|
GeoLocation.LonComponents.seconds = 0;
|
||||||
GeoLocation.LonComponents.direction = 0;
|
GeoLocation.LonComponents.direction = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
time_t EXIFInfo::epoch()
|
||||||
|
{
|
||||||
|
struct tm tm;
|
||||||
|
int year, month, day, hour, min, sec;
|
||||||
|
|
||||||
|
if (DateTimeOriginal.size())
|
||||||
|
sscanf(DateTimeOriginal.c_str(), "%d:%d:%d %d:%d:%d", &year, &month, &day, &hour, &min, &sec);
|
||||||
|
else
|
||||||
|
sscanf(DateTime.c_str(), "%d:%d:%d %d:%d:%d", &year, &month, &day, &hour, &min, &sec);
|
||||||
|
tm.tm_year = year;
|
||||||
|
tm.tm_mon = month - 1;
|
||||||
|
tm.tm_mday = day;
|
||||||
|
tm.tm_hour = hour;
|
||||||
|
tm.tm_min = min;
|
||||||
|
tm.tm_sec = sec;
|
||||||
|
return (utc_mktime(&tm));
|
||||||
|
}
|
|
@ -129,6 +129,8 @@ public:
|
||||||
{
|
{
|
||||||
clear();
|
clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
time_t epoch();
|
||||||
};
|
};
|
||||||
|
|
||||||
// Parse was successful
|
// Parse was successful
|
|
@ -764,63 +764,33 @@ void DiveListView::shiftTimes()
|
||||||
|
|
||||||
void DiveListView::loadImages()
|
void DiveListView::loadImages()
|
||||||
{
|
{
|
||||||
struct memblock mem;
|
|
||||||
EXIFInfo exif;
|
|
||||||
int retval;
|
|
||||||
time_t imagetime;
|
|
||||||
struct divecomputer *dc;
|
|
||||||
time_t when;
|
|
||||||
int duration_s;
|
|
||||||
QStringList fileNames = QFileDialog::getOpenFileNames(this, tr("Open Image Files"), lastUsedImageDir(), tr("Image Files (*.jpg *.jpeg *.pnm *.tif *.tiff)"));
|
QStringList fileNames = QFileDialog::getOpenFileNames(this, tr("Open Image Files"), lastUsedImageDir(), tr("Image Files (*.jpg *.jpeg *.pnm *.tif *.tiff)"));
|
||||||
|
|
||||||
if (fileNames.isEmpty())
|
if (fileNames.isEmpty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
updateLastUsedImageDir(QFileInfo(fileNames[0]).dir().path());
|
updateLastUsedImageDir(QFileInfo(fileNames[0]).dir().path());
|
||||||
|
|
||||||
ShiftImageTimesDialog shiftDialog(this);
|
ShiftImageTimesDialog shiftDialog(this);
|
||||||
shiftDialog.setOffset(lastImageTimeOffset());
|
shiftDialog.setOffset(lastImageTimeOffset());
|
||||||
shiftDialog.exec();
|
shiftDialog.exec();
|
||||||
updateLastImageTimeOffset(shiftDialog.amount());
|
updateLastImageTimeOffset(shiftDialog.amount());
|
||||||
|
|
||||||
for (int i = 0; i < fileNames.size(); ++i) {
|
Q_FOREACH(const QString& fileName, fileNames) {
|
||||||
if (readfile(fileNames.at(i).toUtf8().data(), &mem) <= 0)
|
picture *p = alloc_picture();
|
||||||
continue;
|
p->filename = qstrdup(fileName.toUtf8().data());
|
||||||
//TODO: This inner code should be ported to C-Code.
|
picture_load_exif_data(p);
|
||||||
retval = exif.parseFrom((const unsigned char *)mem.buffer, (unsigned)mem.size);
|
|
||||||
free(mem.buffer);
|
if (p->timestamp)
|
||||||
if (retval != PARSE_EXIF_SUCCESS)
|
p->timestamp += shiftDialog.amount(); // TODO: this should be cached and passed to the C-function
|
||||||
continue;
|
|
||||||
imagetime = shiftDialog.epochFromExiv(&exif);
|
|
||||||
if (!imagetime)
|
|
||||||
continue;
|
|
||||||
imagetime += shiftDialog.amount(); // TODO: this should be cached and passed to the C-function
|
|
||||||
int j = 0;
|
int j = 0;
|
||||||
struct dive *dive;
|
struct dive *dive;
|
||||||
for_each_dive (j, dive) {
|
for_each_dive (j, dive) {
|
||||||
if (!dive->selected)
|
if (!dive->selected)
|
||||||
continue;
|
continue;
|
||||||
for_each_dc (dive, dc) {
|
dive_add_picture(dive, p);
|
||||||
when = dc->when ? dc->when : dive->when;
|
dive_set_geodata_from_picture(dive, p);
|
||||||
duration_s = dc->duration.seconds ? dc->duration.seconds : dive->duration.seconds;
|
|
||||||
if (when - 3600 < imagetime && when + duration_s + 3600 > imagetime) {
|
|
||||||
if (when > imagetime) {
|
|
||||||
// Before dive
|
|
||||||
add_event(dc, 0, 123, 0, 0, fileNames.at(i).toUtf8().data());
|
|
||||||
} else if (when + duration_s < imagetime) {
|
|
||||||
// After dive
|
|
||||||
add_event(dc, duration_s, 123, 0, 0, fileNames.at(i).toUtf8().data());
|
|
||||||
} else {
|
|
||||||
add_event(dc, imagetime - when, 123, 0, 0, fileNames.at(i).toUtf8().data());
|
|
||||||
}
|
|
||||||
if (!dive->latitude.udeg && !IS_FP_SAME(exif.GeoLocation.Latitude, 0.0)) {
|
|
||||||
dive->latitude.udeg = lrint(1000000.0 * exif.GeoLocation.Latitude);
|
|
||||||
dive->longitude.udeg = lrint(1000000.0 * exif.GeoLocation.Longitude);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mark_divelist_changed(true);
|
mark_divelist_changed(true);
|
||||||
MainWindow::instance()->refreshDisplay();
|
MainWindow::instance()->refreshDisplay();
|
||||||
MainWindow::instance()->graphics()->replot();
|
MainWindow::instance()->graphics()->replot();
|
||||||
|
|
|
@ -247,31 +247,12 @@ void ShiftImageTimesDialog::syncCameraClicked()
|
||||||
free(mem.buffer);
|
free(mem.buffer);
|
||||||
if (retval != PARSE_EXIF_SUCCESS)
|
if (retval != PARSE_EXIF_SUCCESS)
|
||||||
return;
|
return;
|
||||||
dcImageEpoch = epochFromExiv(&exiv);
|
dcImageEpoch = exiv.epoch();
|
||||||
dcDateTime.setTime_t(dcImageEpoch);
|
dcDateTime.setTime_t(dcImageEpoch);
|
||||||
ui.dcTime->setDateTime(dcDateTime);
|
ui.dcTime->setDateTime(dcDateTime);
|
||||||
connect(ui.dcTime, SIGNAL(dateTimeChanged(const QDateTime &)), this, SLOT(dcDateTimeChanged(const QDateTime &)));
|
connect(ui.dcTime, SIGNAL(dateTimeChanged(const QDateTime &)), this, SLOT(dcDateTimeChanged(const QDateTime &)));
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: This should be moved to C-Code.
|
|
||||||
time_t ShiftImageTimesDialog::epochFromExiv(EXIFInfo *exif)
|
|
||||||
{
|
|
||||||
struct tm tm;
|
|
||||||
int year, month, day, hour, min, sec;
|
|
||||||
|
|
||||||
if (strlen(exif->DateTimeOriginal.c_str()))
|
|
||||||
sscanf(exif->DateTimeOriginal.c_str(), "%d:%d:%d %d:%d:%d", &year, &month, &day, &hour, &min, &sec);
|
|
||||||
else
|
|
||||||
sscanf(exif->DateTime.c_str(), "%d:%d:%d %d:%d:%d", &year, &month, &day, &hour, &min, &sec);
|
|
||||||
tm.tm_year = year;
|
|
||||||
tm.tm_mon = month - 1;
|
|
||||||
tm.tm_mday = day;
|
|
||||||
tm.tm_hour = hour;
|
|
||||||
tm.tm_min = min;
|
|
||||||
tm.tm_sec = sec;
|
|
||||||
return (utc_mktime(&tm));
|
|
||||||
}
|
|
||||||
|
|
||||||
void ShiftImageTimesDialog::dcDateTimeChanged(const QDateTime &newDateTime)
|
void ShiftImageTimesDialog::dcDateTimeChanged(const QDateTime &newDateTime)
|
||||||
{
|
{
|
||||||
if (!dcImageEpoch)
|
if (!dcImageEpoch)
|
||||||
|
|
20
qthelper.cpp
20
qthelper.cpp
|
@ -1,5 +1,8 @@
|
||||||
#include "qthelper.h"
|
#include "qthelper.h"
|
||||||
#include "qt-gui.h"
|
#include "qt-gui.h"
|
||||||
|
#include "dive.h"
|
||||||
|
#include <exif.h>
|
||||||
|
#include "file.h"
|
||||||
#include <QRegExp>
|
#include <QRegExp>
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
|
|
||||||
|
@ -260,3 +263,20 @@ extern "C" xsltStylesheetPtr get_stylesheet(const char *name)
|
||||||
|
|
||||||
return xslt;
|
return xslt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern "C" void picture_load_exif_data(struct picture *p)
|
||||||
|
{
|
||||||
|
EXIFInfo exif;
|
||||||
|
memblock mem;
|
||||||
|
|
||||||
|
if (readfile(p->filename, &mem) <= 0)
|
||||||
|
goto picture_load_exit;
|
||||||
|
if (exif.parseFrom((const unsigned char *)mem.buffer, (unsigned)mem.size) != PARSE_EXIF_SUCCESS)
|
||||||
|
goto picture_load_exit;
|
||||||
|
p->timestamp = exif.epoch();
|
||||||
|
p->longitude.udeg= lrint(1000000.0 * exif.GeoLocation.Longitude);
|
||||||
|
p->latitude.udeg = lrint(1000000.0 * exif.GeoLocation.Latitude);
|
||||||
|
picture_load_exit:
|
||||||
|
free(mem.buffer);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
|
@ -58,7 +58,7 @@ HEADERS = \
|
||||||
qt-ui/starwidget.h \
|
qt-ui/starwidget.h \
|
||||||
qt-ui/subsurfacewebservices.h \
|
qt-ui/subsurfacewebservices.h \
|
||||||
qt-ui/tableview.h \
|
qt-ui/tableview.h \
|
||||||
qt-ui/exif.h \
|
exif.h \
|
||||||
sha1.h \
|
sha1.h \
|
||||||
statistics.h \
|
statistics.h \
|
||||||
subsurfacestartup.h \
|
subsurfacestartup.h \
|
||||||
|
@ -131,7 +131,7 @@ SOURCES = \
|
||||||
qt-ui/starwidget.cpp \
|
qt-ui/starwidget.cpp \
|
||||||
qt-ui/subsurfacewebservices.cpp \
|
qt-ui/subsurfacewebservices.cpp \
|
||||||
qt-ui/tableview.cpp \
|
qt-ui/tableview.cpp \
|
||||||
qt-ui/exif.cpp \
|
exif.cpp \
|
||||||
save-git.c \
|
save-git.c \
|
||||||
save-xml.c \
|
save-xml.c \
|
||||||
sha1.c \
|
sha1.c \
|
||||||
|
|
Loading…
Add table
Reference in a new issue