summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohannes Hofmann <Johannes.Hofmann@gmx.de>2009-04-07 14:30:26 +0200
committerJohannes Hofmann <Johannes.Hofmann@gmx.de>2009-04-07 14:30:26 +0200
commit8d2d73759dfe0c193c29b7e1f0b90a0873c3b9e7 (patch)
treee6d3d610c5eb88e1d1edb06998275e9241ea1206
parent73b38c69e3dadacda33a2df00b3b5f62bc895256 (diff)
switch ImageMetadata to exiv2 (mostly by Konrad Golling)
-rw-r--r--configure.ac4
-rw-r--r--src/ImageMetaData.cxx323
2 files changed, 155 insertions, 172 deletions
diff --git a/configure.ac b/configure.ac
index de7e818..e9cf00e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -60,5 +60,9 @@ LIBS="`$GSLCONFIG --libs` $LIBS"
AC_CHECK_HEADERS([tiffio.h], [], [echo "Error: tiffio.h not found."; exit 1;])
AC_CHECK_LIB([tiff], [TIFFOpen], [], [echo "Error: libtiff.so not found."; exit 1;])
+# Check for exiv2
+AC_CHECK_HEADERS([exiv2/exif.hpp], [], [echo "Error: exiv2/exif.hpp not found."; exit 1;])
+LIBS="$LIBS -lexiv2"
+
AC_CONFIG_FILES([Makefile src/Makefile])
AC_OUTPUT
diff --git a/src/ImageMetaData.cxx b/src/ImageMetaData.cxx
index f22a641..1c3b2f5 100644
--- a/src/ImageMetaData.cxx
+++ b/src/ImageMetaData.cxx
@@ -12,12 +12,14 @@
#include <string.h>
#include <fcntl.h>
#include <libgen.h>
+#include <assert.h>
#include <sys/param.h>
#include <sys/types.h>
-#include <sys/wait.h>
#include <sys/stat.h>
-#include "util.h"
+#include <exiv2/image.hpp>
+#include <exiv2/exif.hpp>
+
#include "ImageMetaData.H"
ImageMetaData::ImageMetaData() {
@@ -65,87 +67,89 @@ ImageMetaData::save_image(char *in_img, char *out_img) {
return save_image_jpgcom(in_img, out_img);
}
-static double
-degminsecstr2double(char *val) {
- double ret, dv;
-
- ret = 0.0;
- for (dv=1.0; dv <= 3600.0; dv = dv * 60.0) {
- ret = ret + atof(val) / dv;
- val = strchr(val, ',');
- if (!val || val[1] == '\0') {
- break;
- } else {
- val++;
+int
+ImageMetaData::load_image_exif(char *name) {
+ Exiv2::Image::AutoPtr image = Exiv2::ImageFactory::open(name);
+ assert(image.get() != 0);
+ image->readMetadata();
+ Exiv2::ExifData &exifData = image->exifData();
+ if (exifData.empty())
+ {
+ fprintf(stderr, "%s: No Exif data found in the file", name);
+ return 0;
}
- }
- return ret;
-}
+ Exiv2::ExifData::iterator pos = exifData.end();
+
+ if (!_manufacturer )
+ {
+ Exiv2::ExifKey key("Exif.Image.Make"); // tag auch wirklich vorhanden?
+ pos = exifData.findKey(key);
+ if (pos != exifData.end() && pos->size() )
+ _manufacturer = strdup(pos->toString().c_str());
+ }
-#define EXIF_MANUFACTURER 0x010f
-#define EXIF_MODEL 0x0110
-#define EXIF_FOCAL_LENGTH 0x920a
-#define EXIF_FOCAL_LENGTH_IN_35MM_FILM 0xa405
-#define EXIF_GPS_LATIITUDE 0x0002
-#define EXIF_GPS_LONGITUDE 0x0004
-#define EXIF_GPS_ALTITUDE 0x0006
+ if(!_model)
+ {
+ Exiv2::ExifKey key("Exif.Image.Model");
+ pos = exifData.findKey(key);
+ if (pos != exifData.end() && pos->size() )
+ _model = strdup(pos->toString().c_str());
+ }
-int
-ImageMetaData::load_image_exif(char *name) {
- const char * args[32];
- FILE *p;
- pid_t pid;
- int status;
- char buf[1024];
- char val[1024];
- int id;
-
- args[0] = "exif";
- args[1] = "-i";
- args[2] = "-m";
- args[3] = name;
- args[4] = NULL;
-
- p = pexecvp(args[0], const_cast<char * const *>(args), &pid, "r");
-
- if (p) {
- while (fgets(buf, sizeof(buf), p) != NULL) {
- if (sscanf(buf, "%x\t%[^\n]\n", &id, val) != 2) {
- continue;
+ if (isnan(_focal_length))
+ {
+ Exiv2::ExifKey key("Exif.Photo.FocalLength");
+ pos = exifData.findKey(key);
+ if (pos != exifData.end() && pos->toFloat() >= 0)
+ _focal_length = pos->toFloat();
+ }
+
+ if (isnan(_focal_length_35mm))
+ {
+ Exiv2::ExifKey key("Exif.Photo.FocalLengthIn35mmFilm");
+ pos = exifData.findKey(key);
+ if (pos != exifData.end() && pos->toFloat() >= 0)
+ _focal_length_35mm = pos->toFloat();
+ }
+
+ if (isnan(_longitude))
+ {
+ Exiv2::ExifKey key("Exif.GPSInfo.GPSLongitude");
+ pos = exifData.findKey(key);
+ if (pos != exifData.end())
+ {
+ if ( pos->toFloat() >= 0)
+ _longitude = pos->toFloat();
+ if ( pos->toFloat(1) >= 0)
+ _longitude += pos->toFloat(1)/60;
+ if ( pos->toFloat(2) >= 0)
+ _longitude += pos->toFloat(2)/3600;
}
+ }
- switch(id) {
- case EXIF_MANUFACTURER:
- if (!_manufacturer) _manufacturer = strdup(val);
- break;
- case EXIF_MODEL:
- if (!_model) _model = strdup(val);
- break;
- case EXIF_FOCAL_LENGTH:
- if (isnan(_focal_length)) _focal_length = atof(val);
- break;
- case EXIF_FOCAL_LENGTH_IN_35MM_FILM:
- if (isnan(_focal_length_35mm)) _focal_length_35mm = atof(val);
- break;
- case EXIF_GPS_LONGITUDE:
- if (isnan(_longitude)) _longitude = degminsecstr2double(val);
- break;
- case EXIF_GPS_LATIITUDE:
- if (isnan(_latitude)) _latitude = degminsecstr2double(val);
- break;
- case EXIF_GPS_ALTITUDE:
- if (isnan(_height)) _height = atof(val);
- break;
+ if (isnan(_latitude))
+ {
+ Exiv2::ExifKey key("Exif.GPSInfo.GPSLatitude");
+ pos = exifData.findKey(key);
+ if (pos != exifData.end())
+ {
+ if ( pos->toFloat() >= 0)
+ _latitude = pos->toFloat();
+ if ( pos->toFloat(1) >= 0)
+ _latitude += pos->toFloat(1)/60;
+ if ( pos->toFloat(2) >= 0)
+ _latitude += pos->toFloat(2)/3600;
}
}
- }
- fclose(p);
- waitpid(pid, &status, 0);
- if (WEXITSTATUS(status) == 127 || WEXITSTATUS(status) == 126) {
- fprintf(stderr, "%s not found\n", args[0]);
- }
+ if (isnan(_height))
+ {
+ Exiv2::ExifKey key("Exif.GPSInfo.GPSAltitude");
+ pos = exifData.findKey(key);
+ if (pos != exifData.end() && pos->toFloat() >= 0)
+ _height = pos->toFloat();
+ }
return 0;
}
@@ -155,76 +159,74 @@ ImageMetaData::load_image_exif(char *name) {
int
ImageMetaData::load_image_jpgcom(char *name) {
- const char * args[32];
- FILE *p;
- pid_t pid;
- int status;
- char buf[1024];
double lo, la, he, dir, ni, ti, fr, k0, k1, x0 = 0.0;
int pt = 0;
int n, ret = 1;
- args[0] = "rdjpgcom";
- args[1] = name;
- args[2] = NULL;
-
- p = pexecvp(args[0], const_cast<char * const *>(args), &pid, "r");
-
- if (p) {
- while (fgets(buf, sizeof(buf), p) != NULL) {
- if ((n = sscanf(buf, GIPFEL_FORMAT_2,
- &lo, &la, &he, &dir, &ni, &ti, &fr, &pt, &k0, &k1, &x0)) >= 8) {
-
- _longitude = lo;
- _latitude = la;
- _height = he;
- _direction = dir;
- _nick = ni;
- _tilt = ti;
- _focal_length_35mm = fr;
- _projection_type = pt;
-
- if (n >= 10) {
- _k0 = k0;
- _k1 = k1;
- _x0 = x0;
- }
-
- ret = 0;
-
- break;
+ Exiv2::Image::AutoPtr image = Exiv2::ImageFactory::open(name);
+ assert (image.get() != 0);
+ image->readMetadata();
+ const char *com = image->comment().c_str();
+
+ if ((n = sscanf(com, GIPFEL_FORMAT_2,
+ &lo, &la, &he, &dir, &ni, &ti, &fr, &pt, &k0, &k1, &x0)) >= 8)
+ {
+ _longitude = lo;
+ _latitude = la;
+ _height = he;
+ _direction = dir;
+ _nick = ni;
+ _tilt = ti;
+ _focal_length_35mm = fr;
+ _projection_type = pt;
+
+ if (n >= 10)
+ {
+ _k0 = k0;
+ _k1 = k1;
+ _x0 = x0;
}
+ ret = 0;
}
-
- fclose(p);
- waitpid(pid, &status, 0);
- if (WEXITSTATUS(status) == 127 || WEXITSTATUS(status) == 126) {
- fprintf(stderr, "%s not found\n", args[0]);
- }
- }
-
return ret;
}
int
ImageMetaData::save_image_jpgcom(char *in_img, char *out_img) {
- const char * args[32];
- FILE *p;
- pid_t pid;
char buf[1024], tmpname[MAXPATHLEN];
- int status, err = 0;
- ssize_t n;
- int tmp_fd;
- char *dirbuf;
-
- dirbuf = strdup(out_img);
- snprintf(tmpname, sizeof(tmpname), "%s/.gipfelXXXXXX", dirname(dirbuf));
- free(dirbuf);
- tmp_fd = mkstemp(tmpname);
- if (tmp_fd < 0) {
- perror("mkstemp");
- return 1;
- }
+ int n, err = 0;
+
+ char* dirbuf = strdup(out_img);
+ snprintf(tmpname, sizeof(tmpname), "%s/.gipfelXXXXXX", dirname(dirbuf));
+ free(dirbuf);
+
+ int in_fd = open(in_img, O_RDONLY);
+ if (in_fd == -1) {
+ perror("open");
+ return 1;
+ }
+
+ int out_fd = open(tmpname, O_WRONLY | O_TRUNC | O_CREAT);
+ if (out_fd == -1) {
+ perror("open");
+ close(in_fd);
+ return 1;
+ }
+
+ while ((n = read(in_fd, buf, sizeof(buf))) != 0) {
+ if (write(out_fd, buf, n) != n) {
+ perror("write");
+ err++;
+ break;
+ }
+ }
+
+ close(in_fd);
+
+ Exiv2::Image::AutoPtr image = Exiv2::ImageFactory::open(tmpname);
+ assert (image.get() != 0);
+ image->readMetadata();
+ image->clearComment();
snprintf(buf, sizeof(buf), GIPFEL_FORMAT_2,
_longitude,
@@ -235,49 +237,26 @@ ImageMetaData::save_image_jpgcom(char *in_img, char *out_img) {
_tilt,
_focal_length_35mm,
_projection_type,
- _k0, _k1, _x0);
-
- // try to save gipfel data in JPEG comment section
- args[0] = "wrjpgcom";
- args[1] = "-replace";
- args[2] = "-comment";
- args[3] = buf;
- args[4] = in_img;
- args[5] = NULL;
-
- p = pexecvp(args[0], const_cast<char * const *>(args), &pid, "r");
-
- if (p) {
- while ((n = fread(buf, 1, sizeof(buf), p)) != 0) {
- if (write(tmp_fd, buf, n) != n) {
- perror("write");
- err++;
- break;
- }
- }
- fclose(p);
- waitpid(pid, &status, 0);
- if (WEXITSTATUS(status) != 0)
- err++;
- if (WEXITSTATUS(status) == 127 || WEXITSTATUS(status) == 126)
- fprintf(stderr, "%s not found\n", args[0]);
- } else {
- perror("pexecvp");
- err++;
- }
+ _k0, _k1, _x0);
- fsync(tmp_fd); /* make sure data is on disk before replacing orig file */
- close(tmp_fd);
- if (!err) {
- if (rename(tmpname, out_img) != 0) {
- perror("rename");
- err++;
- unlink(tmpname);
- }
- }
+ image->setComment(buf);
+ image->writeMetadata();
+
+ fsync(out_fd); /* make sure data is on disk before replacing orig file */
+ close(out_fd);
+
+ struct stat stFileInfo;
+ if (! stat(out_img,&stFileInfo) )
+ unlink(out_img);
+ if (rename(tmpname, out_img) != 0)
+ {
+ perror("rename");
+ err++;
+ unlink(tmpname);
+ }
- return err != 0;
+ return (err != 0);
}
void