From 98dc256e0a4957ee09c53906f2890d0aea266930 Mon Sep 17 00:00:00 2001 From: cDc Date: Wed, 15 Aug 2018 13:44:36 +0300 Subject: [PATCH] add PARROT camera support to XMP --- TinyEXIF.cpp | 50 +++++++++++++++++++++++++++++++++++--------------- main.cpp | 2 +- 2 files changed, 36 insertions(+), 16 deletions(-) diff --git a/TinyEXIF.cpp b/TinyEXIF.cpp index 4317023..6d6cc31 100644 --- a/TinyEXIF.cpp +++ b/TinyEXIF.cpp @@ -998,33 +998,53 @@ int EXIFInfo::parseFromXMPSegment(const uint8_t* buf, unsigned len) { if (szProjectionType != NULL) { if (0 == _tcsicmp(szProjectionType, "perspective")) ProjectionType = 1; - else if (0 == _tcsicmp(szProjectionType, "equirectangular") || - 0 == _tcsicmp(szProjectionType, "spherical")) + else + if (0 == _tcsicmp(szProjectionType, "equirectangular") || + 0 == _tcsicmp(szProjectionType, "spherical")) ProjectionType = 2; } } } // Try parsing the XMP content for senseFly info. + struct ParseXMP { + static bool Value(const tinyxml2::XMLElement* document, const char* name, double& value) { + if (document->QueryDoubleAttribute(name, &value) == tinyxml2::XML_SUCCESS) + return true; + const tinyxml2::XMLElement* const element(document->FirstChildElement(name)); + if (element != NULL && element->QueryDoubleText(&value) == tinyxml2::XML_SUCCESS) + return true; + return false; + } + }; if (0 == _tcsicmp(Make.c_str(), "senseFly")) { - document->QueryDoubleAttribute("Camera:Roll", &GeoLocation.RollDegree); - if (document->QueryDoubleAttribute("Camera:Pitch", &GeoLocation.PitchDegree) == tinyxml2::XML_SUCCESS) { + ParseXMP::Value(document, "Camera:Roll", GeoLocation.RollDegree); + if (ParseXMP::Value(document, "Camera:Pitch", GeoLocation.PitchDegree)) { // convert to DJI format: senseFly uses pitch 0 as NADIR, whereas DJI -90 GeoLocation.PitchDegree = Tools::NormD180(GeoLocation.PitchDegree-90.0); } - document->QueryDoubleAttribute("Camera:Yaw", &GeoLocation.YawDegree); - document->QueryDoubleAttribute("Camera:GPSXYAccuracy", &GeoLocation.AccuracyXY); - document->QueryDoubleAttribute("Camera:GPSZAccuracy", &GeoLocation.AccuracyZ); + ParseXMP::Value(document, "Camera:Yaw", GeoLocation.YawDegree); + ParseXMP::Value(document, "Camera:GPSXYAccuracy", GeoLocation.AccuracyXY); + ParseXMP::Value(document, "Camera:GPSZAccuracy", GeoLocation.AccuracyZ); + } else + if (0 == _tcsicmp(Make.c_str(), "PARROT")) { + ParseXMP::Value(document, "Camera:Roll", GeoLocation.RollDegree); + if (ParseXMP::Value(document, "Camera:Pitch", GeoLocation.PitchDegree)) { + // convert to DJI format: senseFly uses pitch 0 as NADIR, whereas DJI -90 + GeoLocation.PitchDegree = Tools::NormD180(GeoLocation.PitchDegree-90.0); + } + ParseXMP::Value(document, "Camera:Yaw", GeoLocation.YawDegree); + ParseXMP::Value(document, "Camera:AboveGroundAltitude", GeoLocation.RelativeAltitude); } else { // Try parsing the XMP content for DJI info. - document->QueryDoubleAttribute("drone-dji:AbsoluteAltitude", &GeoLocation.Altitude); - document->QueryDoubleAttribute("drone-dji:RelativeAltitude", &GeoLocation.RelativeAltitude); - document->QueryDoubleAttribute("drone-dji:GimbalRollDegree", &GeoLocation.RollDegree); - document->QueryDoubleAttribute("drone-dji:GimbalPitchDegree", &GeoLocation.PitchDegree); - document->QueryDoubleAttribute("drone-dji:GimbalYawDegree", &GeoLocation.YawDegree); - document->QueryDoubleAttribute("drone-dji:CalibratedFocalLength", &Calibration.FocalLength); - document->QueryDoubleAttribute("drone-dji:CalibratedOpticalCenterX", &Calibration.OpticalCenterX); - document->QueryDoubleAttribute("drone-dji:CalibratedOpticalCenterY", &Calibration.OpticalCenterY); + ParseXMP::Value(document, "drone-dji:AbsoluteAltitude", GeoLocation.Altitude); + ParseXMP::Value(document, "drone-dji:RelativeAltitude", GeoLocation.RelativeAltitude); + ParseXMP::Value(document, "drone-dji:GimbalRollDegree", GeoLocation.RollDegree); + ParseXMP::Value(document, "drone-dji:GimbalPitchDegree", GeoLocation.PitchDegree); + ParseXMP::Value(document, "drone-dji:GimbalYawDegree", GeoLocation.YawDegree); + ParseXMP::Value(document, "drone-dji:CalibratedFocalLength", Calibration.FocalLength); + ParseXMP::Value(document, "drone-dji:CalibratedOpticalCenterX", Calibration.OpticalCenterX); + ParseXMP::Value(document, "drone-dji:CalibratedOpticalCenterY", Calibration.OpticalCenterY); } return PARSE_SUCCESS; diff --git a/main.cpp b/main.cpp index 8478ee5..323128b 100644 --- a/main.cpp +++ b/main.cpp @@ -126,7 +126,7 @@ int main(int argc, const char** argv) std::cout << "GeoLocation.AltitudeRef " << (int)imageEXIF.GeoLocation.AltitudeRef << "\n"; } if (imageEXIF.GeoLocation.hasRelativeAltitude()) - std::cout << "GeoLocation.RelativeAltitude " << imageEXIF.GeoLocation.RelativeAltitude << "\n"; + std::cout << "GeoLocation.RelativeAltitude " << imageEXIF.GeoLocation.RelativeAltitude << " m" << "\n"; if (imageEXIF.GeoLocation.hasOrientation()) { std::cout << "GeoLocation.RollDegree " << imageEXIF.GeoLocation.RollDegree << "\n"; std::cout << "GeoLocation.PitchDegree " << imageEXIF.GeoLocation.PitchDegree << "\n";