Mainly changes to make MSVC compilers happy, improved accuracy of GPS coordinates conversion.

v0.27.3
Andreas Huggel 17 years ago
parent 7b72714af1
commit ff47483e85

@ -60,16 +60,16 @@ try {
assert(getv1.ok()); assert(getv1.ok());
const Exiv2::Value &getv2 = xmpData["Xmp.dc.two"].value(); const Exiv2::Value &getv2 = xmpData["Xmp.dc.two"].value();
assert(isEqual(getv2.toFloat(), 3.1415)); assert(isEqual(getv2.toFloat(), 3.1415f));
assert(getv2.ok()); assert(getv2.ok());
assert(getv2.toLong() == 3); assert(getv2.toLong() == 3);
assert(getv2.ok()); assert(getv2.ok());
Exiv2::Rational R = getv2.toRational(); Exiv2::Rational R = getv2.toRational();
assert(getv2.ok()); assert(getv2.ok());
assert(isEqual(static_cast<float>(R.first) / R.second, 3.1415 )); assert(isEqual(static_cast<float>(R.first) / R.second, 3.1415f ));
const Exiv2::Value &getv3 = xmpData["Xmp.dc.three"].value(); const Exiv2::Value &getv3 = xmpData["Xmp.dc.three"].value();
assert(isEqual(getv3.toFloat(), 5.0/7.0)); assert(isEqual(getv3.toFloat(), 5.0f/7.0f));
assert(getv3.ok()); assert(getv3.ok());
assert(getv3.toLong() == 0); // long(5.0 / 7.0) assert(getv3.toLong() == 0); // long(5.0 / 7.0)
assert(getv3.ok()); assert(getv3.ok());

@ -41,6 +41,7 @@ EXIV2_RCSID("@(#) $Id$")
// + standard includes // + standard includes
#include <iostream> #include <iostream>
#include <iomanip> #include <iomanip>
#include <sstream>
// Adobe XMP Toolkit // Adobe XMP Toolkit
#ifdef EXV_HAVE_XMP_TOOLKIT #ifdef EXV_HAVE_XMP_TOOLKIT
@ -479,7 +480,7 @@ namespace Exiv2 {
if (pos == exifData_->end()) return; if (pos == exifData_->end()) return;
if (!prepareXmpTarget(to)) return; if (!prepareXmpTarget(to)) return;
int year, month, day, hour, min, sec; int year, month, day, hour, min, sec;
std::string subsec = ""; std::string subsec;
char buf[30]; char buf[30];
if (std::string(from) != "Exif.GPSInfo.GPSTimeStamp") { if (std::string(from) != "Exif.GPSInfo.GPSTimeStamp") {
@ -519,8 +520,7 @@ namespace Exiv2 {
sec = static_cast<int>(dsec); sec = static_cast<int>(dsec);
dsec -= sec; dsec -= sec;
snprintf(buf, sizeof(buf), "%.9f", dsec); sprintf(buf, "%.9f", dsec);
buf[sizeof(buf) - 1] = 0;
subsec = buf + 1; subsec = buf + 1;
Exiv2::ExifData::iterator datePos = exifData_->findKey(ExifKey("Exif.GPSInfo.GPSDateStamp")); Exiv2::ExifData::iterator datePos = exifData_->findKey(ExifKey("Exif.GPSInfo.GPSDateStamp"));
@ -546,7 +546,7 @@ namespace Exiv2 {
} }
} }
const char *subsecTag = 0; const char* subsecTag = 0;
if (std::string(from) == "Exif.Image.DateTime") { if (std::string(from) == "Exif.Image.DateTime") {
subsecTag = "Exif.Photo.SubSecTime"; subsecTag = "Exif.Photo.SubSecTime";
} }
@ -559,13 +559,16 @@ namespace Exiv2 {
if (subsecTag) { if (subsecTag) {
Exiv2::ExifData::iterator subsec_pos = exifData_->findKey(ExifKey(subsecTag)); Exiv2::ExifData::iterator subsec_pos = exifData_->findKey(ExifKey(subsecTag));
if (subsec_pos != exifData_->end() && !subsec_pos->value().toString().empty()) if ( subsec_pos != exifData_->end()
&& !subsec_pos->value().toString().empty()) {
subsec = std::string(".") + subsec_pos->value().toString(); subsec = std::string(".") + subsec_pos->value().toString();
}
if (erase_) exifData_->erase(subsec_pos); if (erase_) exifData_->erase(subsec_pos);
} }
snprintf(buf, sizeof(buf), "%4d-%02d-%02dT%02d:%02d:%02d%s", year, month, day, hour, min, sec, subsec.c_str()); if (subsec.size() > 10) subsec = subsec.substr(0, 10);
buf[sizeof(buf) - 1] = 0; sprintf(buf, "%4d-%02d-%02dT%02d:%02d:%02d%s",
year, month, day, hour, min, sec, subsec.c_str());
(*xmpData_)[to] = buf; (*xmpData_)[to] = buf;
if (erase_) exifData_->erase(pos); if (erase_) exifData_->erase(pos);
@ -632,25 +635,34 @@ namespace Exiv2 {
return; return;
} }
Exiv2::ExifData::iterator refPos = exifData_->findKey(ExifKey(std::string(from) + "Ref")); Exiv2::ExifData::iterator refPos = exifData_->findKey(ExifKey(std::string(from) + "Ref"));
if (refPos == exifData_->end()) return; if (refPos == exifData_->end()) {
#ifndef SUPPRESS_WARNINGS
double deg = pos->value().toFloat(0); std::cerr << "Warning: Failed to convert " << from << " to " << to << "\n";
double min = pos->value().toFloat(1); #endif
double sec = pos->value().toFloat(2); return;
}
sec = deg * 3600.0 + min * 60.0 + sec; double deg[3];
for (int i = 0; i < 3; ++i) {
int ideg = static_cast<int>(sec / 3600.0); const int32_t z = pos->value().toRational(i).first;
sec -= ideg * 3600; const int32_t d = pos->value().toRational(i).second;
int imin = static_cast<int>(sec / 60.0); if (d == 0.0) {
sec -= imin * 60; #ifndef SUPPRESS_WARNINGS
std::cerr << "Warning: Failed to convert " << from << " to " << to << "\n";
char buf[30]; #endif
return;
snprintf(buf, sizeof(buf), "%d,%d,%.2f%c", ideg, imin, sec, refPos->value().toString().c_str()[0]); }
buf[sizeof(buf) - 1] = 0; // Hack: Need Value::toDouble
deg[i] = static_cast<double>(z)/d;
}
double min = deg[0] * 60.0 + deg[1] + deg[2] / 60.0;
int ideg = static_cast<int>(min / 60.0);
min -= ideg * 60;
std::ostringstream oss;
oss << ideg << ","
<< std::fixed << std::setprecision(7) << min
<< refPos->value().toString().c_str()[0];
(*xmpData_)[to] = oss.str();
(*xmpData_)[to] = buf;
if (erase_) exifData_->erase(pos); if (erase_) exifData_->erase(pos);
if (erase_) exifData_->erase(refPos); if (erase_) exifData_->erase(refPos);
} }
@ -713,15 +725,13 @@ namespace Exiv2 {
// SXMPUtils::ConvertToLocalTime(&datetime); // SXMPUtils::ConvertToLocalTime(&datetime);
snprintf(buf, sizeof(buf), sprintf(buf, "%4d:%02d:%02d %02d:%02d:%02d",
"%4d:%02d:%02d %02d:%02d:%02d", static_cast<int>(datetime.year),
static_cast<int>(datetime.year), static_cast<int>(datetime.month),
static_cast<int>(datetime.month), static_cast<int>(datetime.day),
static_cast<int>(datetime.day), static_cast<int>(datetime.hour),
static_cast<int>(datetime.hour), static_cast<int>(datetime.minute),
static_cast<int>(datetime.minute), static_cast<int>(datetime.second));
static_cast<int>(datetime.second));
buf[sizeof(buf) - 1] = 0;
(*exifData_)[to] = buf; (*exifData_)[to] = buf;
const char *subsecTag = 0; const char *subsecTag = 0;
@ -739,27 +749,25 @@ namespace Exiv2 {
prepareExifTarget(subsecTag, true); prepareExifTarget(subsecTag, true);
if (datetime.nanoSecond) { if (datetime.nanoSecond) {
snprintf(buf, sizeof(buf), "%09d", static_cast<int>(datetime.nanoSecond)); sprintf(buf, "%09d", static_cast<int>(datetime.nanoSecond));
(*exifData_)[subsecTag] = buf; (*exifData_)[subsecTag] = buf;
} }
} }
} }
else { // "Exif.GPSInfo.GPSTimeStamp" else { // "Exif.GPSInfo.GPSTimeStamp"
Rational rhour = floatToRationalCast(datetime.hour); Rational rhour(datetime.hour, 1);
Rational rmin = floatToRationalCast(datetime.minute); Rational rmin(datetime.minute, 1);
Rational rsec = floatToRationalCast(static_cast<float>(datetime.second) + datetime.nanoSecond / 1000000000.0); Rational rsec = floatToRationalCast(static_cast<float>(datetime.second) + datetime.nanoSecond / 1000000000.0f);
std::ostringstream array; std::ostringstream array;
array << rhour << " " << rmin << " " << rsec; array << rhour << " " << rmin << " " << rsec;
(*exifData_)[to] = array.str(); (*exifData_)[to] = array.str();
prepareExifTarget("Exif.GPSInfo.GPSDateStamp", true); prepareExifTarget("Exif.GPSInfo.GPSDateStamp", true);
snprintf(buf, sizeof(buf), sprintf(buf, "%4d:%02d:%02d",
"%4d:%02d:%02d", static_cast<int>(datetime.year),
static_cast<int>(datetime.year), static_cast<int>(datetime.month),
static_cast<int>(datetime.month), static_cast<int>(datetime.day));
static_cast<int>(datetime.day));
buf[sizeof(buf) - 1] = 0;
(*exifData_)["Exif.GPSInfo.GPSDateStamp"] = buf; (*exifData_)["Exif.GPSInfo.GPSDateStamp"] = buf;
} }
@ -885,7 +893,7 @@ namespace Exiv2 {
return; return;
} }
float deg, min, sec; double deg, min, sec;
char ref, sep1, sep2; char ref, sep1, sep2;
ref = value[value.length() - 1]; ref = value[value.length() - 1];
@ -900,24 +908,21 @@ namespace Exiv2 {
} }
else { else {
sec = (min - static_cast<int>(min)) * 60.0; sec = (min - static_cast<int>(min)) * 60.0;
min = static_cast<int>(min); min = static_cast<double>(static_cast<int>(min));
sep2 = ','; sep2 = ',';
} }
if (in.bad() || if ( in.bad() || !(ref == 'N' || ref == 'S' || ref == 'E' || ref == 'W')
!(ref == 'N' || ref == 'S' || ref == 'E' || ref == 'W') || || sep1 != ',' || sep2 != ',' || !in.eof()) {
sep1 != ',' || sep2 != ',' ||
!in.eof()) {
#ifndef SUPPRESS_WARNINGS #ifndef SUPPRESS_WARNINGS
std::cerr << "Warning: Failed to convert " << from << " to " << to << "\n"; std::cerr << "Warning: Failed to convert " << from << " to " << to << "\n";
#endif #endif
return; return;
} }
Rational rdeg = floatToRationalCast(static_cast<float>(deg));
Rational rdeg = floatToRationalCast(deg); Rational rmin = floatToRationalCast(static_cast<float>(min));
Rational rmin = floatToRationalCast(min); Rational rsec = floatToRationalCast(static_cast<float>(sec));
Rational rsec = floatToRationalCast(sec);
std::ostringstream array; std::ostringstream array;
array << rdeg << " " << rmin << " " << rsec; array << rdeg << " " << rmin << " " << rsec;

@ -2082,7 +2082,7 @@ namespace Exiv2 {
char s[5]; char s[5];
for (int i = 0; i < 4; ++i) { for (int i = 0; i < 4; ++i) {
s[i] = value.toLong(i); s[i] = static_cast<char>(value.toLong(i));
} }
s[4] = '\0'; s[4] = '\0';

@ -50,7 +50,7 @@ namespace Exiv2 {
// class declarations // class declarations
class Value; class Value;
class Entry; class Entry;
class TagInfo; struct TagInfo;
// ***************************************************************************** // *****************************************************************************
// type definitions // type definitions

@ -410,7 +410,7 @@ namespace Exiv2 {
} }
bool b = stringTo<bool>(s, ok); bool b = stringTo<bool>(s, ok);
if (ok) return b ? 1.0 : 0.0; if (ok) return b ? 1.0f : 0.0f;
// everything failed, return from stringTo<float> is probably the best fit // everything failed, return from stringTo<float> is probably the best fit
return ret; return ret;
@ -441,7 +441,7 @@ namespace Exiv2 {
if (std::labs(static_cast<long>(f)) > 2147) den = 10000; if (std::labs(static_cast<long>(f)) > 2147) den = 10000;
if (std::labs(static_cast<long>(f)) > 214748) den = 100; if (std::labs(static_cast<long>(f)) > 214748) den = 100;
if (std::labs(static_cast<long>(f)) > 21474836) den = 1; if (std::labs(static_cast<long>(f)) > 21474836) den = 1;
const float rnd = f >= 0 ? 0.5 : -0.5; const float rnd = f >= 0 ? 0.5f : -0.5f;
const int32_t nom = static_cast<int32_t>(f * den + rnd); const int32_t nom = static_cast<int32_t>(f * den + rnd);
const int32_t g = gcd(nom, den); const int32_t g = gcd(nom, den);

Loading…
Cancel
Save