diff options
| -rw-r--r-- | configure.ac | 4 | ||||
| -rw-r--r-- | src/ImageMetaData.cxx | 323 | 
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  | 
