#1233 Fixed bug in samples/geotag.cpp

This commit is contained in:
clanmills
2017-05-08 10:57:28 +01:00
parent fa449a4d2c
commit 038fe6cb94
+59 -46
View File
@@ -2,6 +2,8 @@
// geotag.cpp, $Rev: 2286 $
// Sample program to read gpx files and update images with GPS tags
// g++ geotag.cpp -o geotag -lexiv2 -lexpat
#include <exiv2/exiv2.hpp>
#include <iostream>
@@ -32,9 +34,6 @@ using namespace std;
#ifndef lengthof
#define lengthof(x) (sizeof(*x)/sizeof(x))
#endif
#ifndef nil
#define nil NULL
#endif
#if defined(_MSC_VER) || defined(__MINGW__)
#include <windows.h>
@@ -80,8 +79,6 @@ char* realpath(const char* file,char* path)
}
#endif
char gDeg[10];
// Command-line parser
class Options {
public:
@@ -139,6 +136,17 @@ enum
, typeMax = 7
};
// forward declaration
class Position;
// globals
typedef std::map<time_t,Position> TimeDict_t;
typedef std::map<time_t,Position>::iterator TimeDict_i;
typedef std::vector<std::string> strings_t;
const char* gDeg = NULL ; // string "°" or "deg"
TimeDict_t gTimeDict ;
strings_t gFiles;
// Position (from gpx file)
class Position
{
@@ -244,18 +252,12 @@ std::string Position::toString()
return std::string(result);
}
// defaults
int Position::adjust_ = 0;
int Position::tz_ = timeZoneAdjust();
int Position::dst_ = 0;
time_t Position::deltaMax_ = 60 ;
// globals
typedef std::map<time_t,Position> TimeDict_t;
typedef std::map<time_t,Position>::iterator TimeDict_i;
typedef std::vector<std::string> strings_t;
TimeDict_t gTimeDict ;
strings_t gFiles;
///////////////////////////////////////////////////////////
// UserData - used by XML Parser
class UserData
@@ -581,8 +583,6 @@ time_t readImageTime(std::string path,std::string* pS=NULL)
using namespace Exiv2;
time_t result = 0 ;
static std::map<std::string,time_t> cache;
if ( cache.count(path) == 1 ) return cache[path];
const char* dateStrings[] =
{ "Exif.Photo.DateTimeOriginal"
@@ -590,21 +590,21 @@ time_t readImageTime(std::string path,std::string* pS=NULL)
, "Exif.Image.DateTime"
, NULL
};
const char* ds = dateStrings[0] ;
const char* dateString = dateStrings[0] ;
while ( !result && ds++ ) {
do {
try {
Image::AutoPtr image = ImageFactory::open(path);
if ( image.get() ) {
image->readMetadata();
ExifData &exifData = image->exifData();
// printf("%s => %s\n",(ds-1), exifData[ds-1].toString().c_str());
result = parseTime(exifData[ds-1].toString().c_str(),true);
if ( result && pS ) *pS = exifData[ds-1].toString();
// printf("%s => %s\n",dateString, exifData[dateString].toString().c_str());
result = parseTime(exifData[dateString].toString().c_str(),true);
if ( result && pS ) *pS = exifData[dateString].toString();
}
} catch ( ... ) {};
}
if ( result ) cache[path] = result;
} while ( !result && ++dateString );
return result ;
}
@@ -627,8 +627,8 @@ int readFile(const char* path,Options /* options */)
FILE* f = fopen(path,"r");
int nResult = f ? typeFile : typeUnknown;
if ( f ) {
const char* docs[] = { ".doc",".txt", nil };
const char* code[] = { ".cpp",".h" ,".pl" ,".py" ,".pyc", nil };
const char* docs[] = { ".doc",".txt", NULL };
const char* code[] = { ".cpp",".h" ,".pl" ,".py" ,".pyc", NULL };
const char* ext = strstr(path,".");
if ( ext ) {
if ( sina(ext,docs) ) nResult = typeDoc;
@@ -791,15 +791,15 @@ int main(int argc,const char* argv[])
if ( needv && !value) key = kwNEEDVALUE;
switch ( key ) {
case kwDST : options.dst = true ; break;
case kwHELP : options.help = true ; break;
case kwVERSION : options.version = true ; break;
case kwDRYRUN : options.dryrun = true ; break;
case kwVERBOSE : options.verbose = true ; break;
case kwASCII : options.ascii = true ; break;
case kwTZ : Position::tz_ = parseTZ(value);break;
case kwADJUST : Position::adjust_ = ivalue;break;
case kwDELTA : Position::deltaMax_= ivalue;break;
case kwDST : options.dst = true ; break;
case kwHELP : options.help = true ; break;
case kwVERSION : options.version = true ; break;
case kwDRYRUN : options.dryrun = true ; break;
case kwVERBOSE : options.verbose = true ; break;
case kwASCII : options.ascii = true ; break;
case kwTZ : Position::tz_ = parseTZ(value);break;
case kwADJUST : Position::adjust_ = ivalue;break;
case kwDELTA : Position::deltaMax_ = ivalue;break;
case kwNEEDVALUE: fprintf(stderr,"error: %s requires a value\n",arg); result = resultSyntaxError ; break ;
case kwSYNTAX : default:
{
@@ -807,30 +807,29 @@ int main(int argc,const char* argv[])
if ( options.verbose ) printf("%s %s ",arg,types[type]) ;
if ( type == typeImage ) {
time_t t = readImageTime(std::string(arg)) ;
char buffer[1024];
#ifdef __APPLE__
char* path = realpath(arg,buffer);
char buffer[1024];
#else
char* path = realpath(arg,NULL);
char* buffer = NULL;
#endif
char* path = realpath(arg,buffer);
if ( t && path ) {
if ( options.verbose) printf("%s %ld %s",path,(long int)t,asctime(localtime(&t)));
gFiles.push_back(path);
}
if ( path && path != buffer ) :: free((void*) path);
if ( path && path != buffer ) ::free((void*) path);
}
if ( type == typeUnknown ) {
fprintf(stderr,"error: illegal syntax %s\n",arg);
result = resultSyntaxError ;
}
if ( options.verbose ) printf("\n") ;
}break;
} break;
}
}
if ( options.help ) ::help(program,keywords,kwMAX,options.verbose);
if ( options.version ) ::version(program);
strcpy(gDeg,options.ascii?"deg":"°");
gDeg = options.ascii ? "deg" : "°";
if ( !result ) {
sort(gFiles.begin(),gFiles.end(),mySort);
@@ -848,13 +847,27 @@ int main(int argc,const char* argv[])
s-= m*60 ;
printf("tz,dst,adjust = %d,%d,%d total = %dsecs (= %d:%d:%d)\n",t,d,a,A,h,m,s);
}
for ( size_t p = 0 ; !options.dryrun && p < gFiles.size() ; p++ ) {
std::string arg = gFiles[p] ;
/*
if ( options.verbose ) {
printf("Time Dictionary\n");
for ( TimeDict_i it = gTimeDict.begin() ; it != gTimeDict.end() ; it++ ) {
std::string sTime = getExifTime(it->first);
Position* pPos = &it->second;
std::string sPos = Position::toExifString(pPos->lat(),false,true)
+ " "
+ Position::toExifString(pPos->lon(),false,true)
;
printf("%s %s\n",sTime.c_str(), sPos.c_str());
}
}
*/
for ( size_t p = 0 ; p < gFiles.size() ; p++ ) {
std::string path = gFiles[p] ;
std::string stamp ;
try {
time_t t = readImageTime(arg,&stamp) ;
time_t t = readImageTime(path,&stamp) ;
Position* pPos = searchTimeDict(gTimeDict,t,Position::deltaMax_);
Exiv2::Image::AutoPtr image = Exiv2::ImageFactory::open(gFiles[p]);
Exiv2::Image::AutoPtr image = Exiv2::ImageFactory::open(path);
if ( image.get() ) {
image->readMetadata();
Exiv2::ExifData& exifData = image->exifData();
@@ -875,11 +888,11 @@ int main(int argc,const char* argv[])
exifData["Exif.GPSInfo.GPSTimeStamp" ] = Position::toExifTimeStamp(stamp);
exifData["Exif.Image.GPSTag" ] = 4908;
printf("%s %s % 2d\n",arg.c_str(),pPos->toString().c_str(),pPos->delta());
printf("%s %s % 2d\n",path.c_str(),pPos->toString().c_str(),pPos->delta());
} else {
printf("%s *** not in time dict ***\n",arg.c_str());
printf("%s *** not in time dict ***\n",path.c_str());
}
image->writeMetadata();
if ( !options.dryrun ) image->writeMetadata();
}
} catch ( ... ) {};
}