summaryrefslogtreecommitdiff
path: root/src/ImageMetaData.cxx
diff options
context:
space:
mode:
authorJohannes Hofmann <Johannes.Hofmann@gmx.de>2006-10-30 18:18:57 +0100
committerJohannes Hofmann <Johannes.Hofmann@gmx.de>2006-10-30 18:18:57 +0100
commitda5192170bb7ed19a8eadbc8ac393b0fa222c7df (patch)
tree534176e18b1cc6d8ac4f1926cb4c43c26168095b /src/ImageMetaData.cxx
parent20d0a75d72711a11694c4796529acba280ac9443 (diff)
consolidate ExifImageMetaData and src/JpgcomImageMetaData into ImageMetaData
Diffstat (limited to 'src/ImageMetaData.cxx')
-rw-r--r--src/ImageMetaData.cxx242
1 files changed, 234 insertions, 8 deletions
diff --git a/src/ImageMetaData.cxx b/src/ImageMetaData.cxx
index 5c54a17..424a792 100644
--- a/src/ImageMetaData.cxx
+++ b/src/ImageMetaData.cxx
@@ -17,32 +17,258 @@
// USA.
//
+#include <stdlib.h>
#include <stdio.h>
#include <math.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/stat.h>
+
+
+#include "util.h"
#include "ImageMetaData.H"
ImageMetaData::ImageMetaData() {
longitude = NAN;
latitude = NAN;
- height = NAN;
- direction = NAN;
- nick = NAN;
- tilt = NAN;
- focallength_sensor_ratio = NAN;
- projection_type = -1;
+ height = 0.0;
+ direction = 0.0;
+ nick = 0.0;
+ tilt = 0.0;
+ focallength_sensor_ratio = 1.0;
+ projection_type = 1;
}
+
int
ImageMetaData::load_image(char *name) {
- return 1;
+ int ret;
+
+ ret = load_image_jpgcom(name);
+ if (ret != 0) {
+ ret = load_image_exif(name);
+ }
+
+ return ret;
}
int
ImageMetaData::save_image(char *in_img, char *out_img) {
- return 1;
+ 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++;
+ }
+ }
+
+ return ret;
+}
+
+#define EXIF_FOCAL_LENGTH_IN_35MM_FILM 0xa405
+#define EXIF_GPS_LATIITUDE 0x0002
+#define EXIF_GPS_LONGITUDE 0x0004
+#define EXIF_GPS_ALTITUDE 0x0006
+
+int
+ImageMetaData::load_image_exif(char *name) {
+ 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], args, &pid, "r");
+
+ if (p) {
+ while (fgets(buf, sizeof(buf), p) != NULL) {
+ if (sscanf(buf, "%x\t%[^\n]\n", &id, val) != 2) {
+ continue;
+ }
+
+ switch(id) {
+ case EXIF_FOCAL_LENGTH_IN_35MM_FILM:
+ focallength_sensor_ratio = atof(val) / 35.0;
+ break;
+ case EXIF_GPS_LONGITUDE:
+ longitude = degminsecstr2double(val);
+ break;
+ case EXIF_GPS_LATIITUDE:
+ latitude = degminsecstr2double(val);
+ break;
+ case EXIF_GPS_ALTITUDE:
+ height = atof(val);
+ break;
+ }
+ }
+ }
+
+ fclose(p);
+ waitpid(pid, &status, 0);
+ if (WEXITSTATUS(status) == 127 || WEXITSTATUS(status) == 126) {
+ fprintf(stderr, "%s not found\n", args[0]);
+ }
+
+ return 0;
+}
+
+
+#define GIPFEL_FORMAT_1 "gipfel: longitude %lf, latitude %lf, height %lf, direction %lf, nick %lf, tilt %lf, scale %lf, projection type %d"
+#define GIPFEL_FORMAT_2 "gipfel: longitude %lf, latitude %lf, height %lf, direction %lf, nick %lf, tilt %lf, focallength_sensor_ratio %lf, projection type %d"
+
+int
+ImageMetaData::load_image_jpgcom(char *name) {
+ char * args[32];
+ FILE *p;
+ pid_t pid;
+ int status;
+ char buf[1024];
+ double lo, la, he, dir, ni, ti, fr;
+ int pt;
+ int ret = 1;
+
+ args[0] = "rdjpgcom";
+ args[1] = name;
+ args[2] = NULL;
+
+ p = pexecvp(args[0], args, &pid, "r");
+
+ if (p) {
+ while (fgets(buf, sizeof(buf), p) != NULL) {
+ if (sscanf(buf, GIPFEL_FORMAT_2,
+ &lo, &la, &he, &dir, &ni, &ti, &fr, &pt) >= 7) {
+
+ longitude = lo;
+ latitude = la;
+ height = he;
+ direction = dir;
+ nick = ni;
+ tilt = ti;
+ focallength_sensor_ratio = fr;
+ projection_type = pt;
+
+ ret = 0;
+
+ break;
+ } else if (sscanf(buf, GIPFEL_FORMAT_1,
+ &lo, &la, &he, &dir, &ni, &ti, &fr, &pt) >= 7) {
+
+ longitude = lo;
+ latitude = la;
+ height = he;
+ direction = dir;
+ nick = ni;
+ tilt = ti;
+ focallength_sensor_ratio = fr;
+ projection_type = pt;
+
+ ret = 2; // special return value for compatibility with
+ // old format
+
+ break;
+ }
+ }
+
+ 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) {
+ char * args[32];
+ FILE *p, *out;
+ pid_t pid;
+ char buf[1024];
+ int status;
+ size_t n;
+ struct stat in_stat, out_stat;
+
+ if (stat(in_img, &in_stat) != 0) {
+ perror("stat");
+ return 1;
+ }
+
+ if (stat(out_img, &out_stat) == 0) {
+ if (in_stat.st_ino == out_stat.st_ino) {
+ fprintf(stderr, "Input image %s and output image %s are the same file\n",
+ in_img, out_img);
+ return 1;
+ }
+ }
+
+ out = fopen(out_img, "w");
+ if (out == NULL) {
+ perror("fopen");
+ return 1;
+ }
+
+ snprintf(buf, sizeof(buf), GIPFEL_FORMAT_2,
+ longitude,
+ latitude,
+ height,
+ direction,
+ nick,
+ tilt,
+ focallength_sensor_ratio,
+ projection_type);
+
+ // 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], args, &pid, "r");
+
+ if (p) {
+ while ((n = fread(buf, 1, sizeof(buf), p)) != 0) {
+ if (fwrite(buf, 1, n, out) != n) {
+ perror("fwrite");
+ fclose(out);
+ fclose(p);
+ waitpid(pid, &status, 0);
+ }
+ }
+ fclose(p);
+ waitpid(pid, &status, 0);
+ if (WEXITSTATUS(status) == 127 || WEXITSTATUS(status) == 126) {
+ fprintf(stderr, "%s not found\n", args[0]);
+ }
+ }
+
+ fclose(out);
+ return 0;
+}
+
+
double
ImageMetaData::get_longitude() {
return longitude;