From 36f705679942fe9a5d06114e94ced9fc2b97d687 Mon Sep 17 00:00:00 2001 From: cDc Date: Sat, 9 Dec 2017 11:59:09 +0200 Subject: [PATCH] try recover missing EXIF filds from XMP --- README.md | 22 +++++++++++++++ TinyEXIF.cpp | 76 +++++++++++++++++++++++++++++++++------------------- TinyEXIF.h | 24 ++++++++--------- main.cpp | 10 ++++--- 4 files changed, 89 insertions(+), 43 deletions(-) diff --git a/README.md b/README.md index a209fc0..decd06a 100644 --- a/README.md +++ b/README.md @@ -38,3 +38,25 @@ int main(int argc, const char** argv) { } ``` See `main.cpp` for more details. + +## Copyright + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + - Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + - Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY EXPRESS +OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN +NO EVENT SHALL THE FREEBSD PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/TinyEXIF.cpp b/TinyEXIF.cpp index e679e67..974ce17 100644 --- a/TinyEXIF.cpp +++ b/TinyEXIF.cpp @@ -13,22 +13,22 @@ Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - -- Redistributions of source code must retain the above copyright notice, + - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - -- Redistributions in binary form must reproduce the above copyright notice, + - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - NO EVENT SHALL THE FREEBSD PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY EXPRESS + OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + NO EVENT SHALL THE FREEBSD PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "TinyEXIF.h" @@ -637,19 +637,19 @@ int EXIFInfo::parseFrom(const uint8_t* buf, unsigned len) { inline operator uint32_t& () { return val; } inline int operator () (int code=PARSE_ABSENT_DATA) const { return val&FIELD_ALL ? (int)PARSE_SUCCESS : code; } } app1s(Fields); - for (unsigned pos=2; posQueryUnsignedAttribute("tiff:Orientation", &_Orientation); + Orientation = (uint16_t)_Orientation; + } + if (ImageWidth == 0 && ImageHeight == 0) { + document->QueryUnsignedAttribute("tiff:ImageWidth", &ImageWidth); + if (document->QueryUnsignedAttribute("tiff:ImageHeight", &ImageHeight) != tinyxml2::XML_SUCCESS) + document->QueryUnsignedAttribute("tiff:ImageLength", &ImageHeight) ; + } + if (XResolution == 0 && YResolution == 0 && ResolutionUnit == 0) { + document->QueryDoubleAttribute("tiff:XResolution", &XResolution); + document->QueryDoubleAttribute("tiff:YResolution", &YResolution); + uint32_t _ResolutionUnit(0); + document->QueryUnsignedAttribute("tiff:ResolutionUnit", &_ResolutionUnit); + ResolutionUnit = (uint16_t)_ResolutionUnit; + } + + // Try parsing the XMP content for projection type. { const tinyxml2::XMLElement* const element(document->FirstChildElement("GPano:ProjectionType")); if (element != NULL) { @@ -875,7 +894,7 @@ int EXIFInfo::parseFromXMPSegment(const uint8_t* buf, unsigned len) { } } - // Now try parsing the XMP content for DJI info. + // 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); @@ -887,7 +906,7 @@ int EXIFInfo::parseFromXMPSegment(const uint8_t* buf, unsigned len) { void EXIFInfo::Geolocation_t::parseCoords() { - // convert GPS latitude + // Convert GPS latitude if (LatComponents.degrees != DBL_MAX || LatComponents.minutes != 0 || LatComponents.seconds != 0) { @@ -898,7 +917,7 @@ void EXIFInfo::Geolocation_t::parseCoords() { if ('S' == LatComponents.direction) Latitude = -Latitude; } - // convert GPS longitude + // Convert GPS longitude if (LonComponents.degrees != DBL_MAX || LonComponents.minutes != 0 || LonComponents.seconds != 0) { @@ -909,7 +928,7 @@ void EXIFInfo::Geolocation_t::parseCoords() { if ('W' == LonComponents.direction) Longitude = -Longitude; } - // convert GPS altitude + // Convert GPS altitude if (hasAltitude() && AltitudeRef == 1) { Altitude = -Altitude; @@ -951,6 +970,9 @@ void EXIFInfo::clear() { RelatedImageWidth = 0; RelatedImageHeight= 0; Orientation = 0; + XResolution = 0; + YResolution = 0; + ResolutionUnit = 0; BitsPerSample = 0; ExposureTime = 0; FNumber = 0; diff --git a/TinyEXIF.h b/TinyEXIF.h index 7511c57..80aa49d 100644 --- a/TinyEXIF.h +++ b/TinyEXIF.h @@ -13,22 +13,22 @@ Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - -- Redistributions of source code must retain the above copyright notice, + - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - -- Redistributions in binary form must reproduce the above copyright notice, + - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - NO EVENT SHALL THE FREEBSD PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY EXPRESS + OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + NO EVENT SHALL THE FREEBSD PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef __TINYEXIF_H__ diff --git a/main.cpp b/main.cpp index 67af930..05984bf 100644 --- a/main.cpp +++ b/main.cpp @@ -41,10 +41,12 @@ int main(int argc, const char** argv) std::cout << "CameraModel " << imageEXIF.Make << " - " << imageEXIF.Model << "\n"; if (!imageEXIF.SerialNumber.empty()) std::cout << "SerialNumber " << imageEXIF.SerialNumber << "\n"; - std::cout << "Orientation " << imageEXIF.Orientation << "\n"; - std::cout << "Resolution " << imageEXIF.XResolution << "x" << imageEXIF.YResolution << "\n"; - std::cout << "ResolutionUnit " << imageEXIF.ResolutionUnit << "\n"; - std::cout << "BitsPerSample " << imageEXIF.BitsPerSample << "\n"; + if (imageEXIF.Orientation) + std::cout << "Orientation " << imageEXIF.Orientation << "\n"; + if (imageEXIF.XResolution || imageEXIF.YResolution || imageEXIF.ResolutionUnit) + std::cout << "Resolution " << imageEXIF.XResolution << "x" << imageEXIF.YResolution << " (" << imageEXIF.ResolutionUnit << ")\n"; + if (imageEXIF.BitsPerSample) + std::cout << "BitsPerSample " << imageEXIF.BitsPerSample << "\n"; if (!imageEXIF.Software.empty()) std::cout << "Software " << imageEXIF.Software << "\n"; if (!imageEXIF.DateTime.empty())