diff --git a/demo.cpp b/demo.cpp index 67394ec..7b3c6f6 100644 --- a/demo.cpp +++ b/demo.cpp @@ -68,12 +68,15 @@ int main(int argc, char *argv[]) { result.GeoLocation.LonComponents.seconds, result.GeoLocation.LonComponents.direction); printf("GPS Altitude : %f m\n", result.GeoLocation.Altitude); + printf("GPS Precision (DOP) : %f\n", result.GeoLocation.DOP); printf("Lens min focal length: %f mm\n", result.LensInfo.FocalLengthMin); printf("Lens max focal length: %f mm\n", result.LensInfo.FocalLengthMax); printf("Lens f-stop min : f/%.1f\n", result.LensInfo.FStopMin); printf("Lens f-stop max : f/%.1f\n", result.LensInfo.FStopMax); printf("Lens make : %s\n", result.LensInfo.Make.c_str()); printf("Lens model : %s\n", result.LensInfo.Model.c_str()); + printf("Focal plane XRes : %f\n", result.LensInfo.FocalPlaneXResolution); + printf("Focal plane YRes : %f\n", result.LensInfo.FocalPlaneYResolution); return 0; } diff --git a/exif.cpp b/exif.cpp index 826f5f7..7a964e1 100644 --- a/exif.cpp +++ b/exif.cpp @@ -682,12 +682,28 @@ int easyexif::EXIFInfo::parseFromEXIFSegment(const unsigned char *buf, this->ImageHeight = result.val_short().front(); break; + case 0xa20e: + // EXIF Focal plane X-resolution + if (result.format() == 5) { + this->LensInfo.FocalPlaneXResolution = result.val_rational()[0]; + } + break; + + case 0xa20f: + // EXIF Focal plane Y-resolution + if (result.format() == 5) { + this->LensInfo.FocalPlaneYResolution = result.val_rational()[0]; + } + break; + case 0xa405: // Focal length in 35mm film if (result.format() == 3) this->FocalLengthIn35mm = result.val_short().front(); break; + case 0xa432: + // Focal length and FStop. if (result.format() == 5) { this->LensInfo.FocalLengthMin = result.val_rational()[0]; this->LensInfo.FocalLengthMax = result.val_rational()[1]; @@ -695,12 +711,16 @@ int easyexif::EXIFInfo::parseFromEXIFSegment(const unsigned char *buf, this->LensInfo.FStopMax = result.val_rational()[3]; } break; + case 0xa433: + // Lens make. if (result.format() == 2) { this->LensInfo.Make = result.val_string(); } break; + case 0xa434: + // Lens model. if (result.format() == 2) { this->LensInfo.Model = result.val_string(); } @@ -784,12 +804,13 @@ int easyexif::EXIFInfo::parseFromEXIFSegment(const unsigned char *buf, case 5: // GPS altitude reference (below or above sea level) this->GeoLocation.AltitudeRef = *(buf + offs + 8); - if (1 == this->GeoLocation.AltitudeRef) + if (1 == this->GeoLocation.AltitudeRef) { this->GeoLocation.Altitude = -this->GeoLocation.Altitude; + } break; case 6: - // GPS altitude reference + // GPS altitude if (format == 5) { this->GeoLocation.Altitude = parse_value( buf + data + tiff_header_start, alignIntel); @@ -798,6 +819,14 @@ int easyexif::EXIFInfo::parseFromEXIFSegment(const unsigned char *buf, } } break; + + case 11: + // GPS degree of precision (DOP) + if (format == 5) { + this->GeoLocation.DOP = parse_value( + buf + data + tiff_header_start, alignIntel); + } + break; } offs += 12; } @@ -841,6 +870,7 @@ void easyexif::EXIFInfo::clear() { GeoLocation.Longitude = 0; GeoLocation.Altitude = 0; GeoLocation.AltitudeRef = 0; + GeoLocation.DOP = 0; GeoLocation.LatComponents.degrees = 0; GeoLocation.LatComponents.minutes = 0; GeoLocation.LatComponents.seconds = 0; @@ -855,6 +885,8 @@ void easyexif::EXIFInfo::clear() { LensInfo.FocalLengthMin = 0; LensInfo.FStopMax = 0; LensInfo.FStopMin = 0; + LensInfo.FocalPlaneYResolution = 0; + LensInfo.FocalPlaneXResolution = 0; LensInfo.Make = ""; LensInfo.Model = ""; } diff --git a/exif.h b/exif.h index 3fe9acb..870b21e 100644 --- a/exif.h +++ b/exif.h @@ -1,5 +1,5 @@ /************************************************************************** - exif.h -- A simple ISO C++ library to parse basic EXIF + exif.h -- A simple ISO C++ library to parse basic EXIF information from a JPEG file. Based on the description of the EXIF file format at: @@ -15,7 +15,7 @@ ================ 2.2: Release December 2014 - -- + -- 2.1: Released July 2013 -- fixed a bug where JPEGs without an EXIF SubIFD would not be parsed @@ -31,25 +31,25 @@ -- added GPS support 1.0: Released 2010 - - Redistribution and use in source and binary forms, with or without + + 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, - this list of conditions and the following disclaimer in the documentation + -- 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, + 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 __EXIF_H @@ -59,7 +59,7 @@ namespace easyexif { -// +// // Class responsible for storing and parsing EXIF information from a JPEG blob // class EXIFInfo { @@ -74,7 +74,7 @@ class EXIFInfo { int parseFrom(const std::string &data); // Parsing function for an EXIF segment. This is used internally by parseFrom() - // but can be called for special cases where only the EXIF section is + // but can be called for special cases where only the EXIF section is // available (i.e., a blob starting with the bytes "Exif\0\0"). int parseFromEXIFSegment(const unsigned char *buf, unsigned len); @@ -82,7 +82,7 @@ class EXIFInfo { void clear(); // Data fields filled out by parseFrom() - char ByteAlign; // 0 = Motorola byte alignment, 1 = Intel + char ByteAlign; // 0 = Motorola byte alignment, 1 = Intel std::string ImageDescription; // Image description std::string Make; // Camera manufacturer's name std::string Model; // Camera model @@ -122,18 +122,21 @@ class EXIFInfo { double Longitude; // Image longitude expressed as decimal double Altitude; // Altitude in meters, relative to sea level char AltitudeRef; // 0 = above sea level, -1 = below sea level + double DOP; // GPS degree of precision (DOP) struct Coord_t { double degrees; double minutes; double seconds; char direction; - } LatComponents, LonComponents; // Latitude, Longitude expressed in deg/min/sec + } LatComponents, LonComponents; // Latitude, Longitude expressed in deg/min/sec } GeoLocation; struct LensInfo_t { // Lens information double FStopMin; // Min aperture (f-stop) double FStopMax; // Max aperture (f-stop) double FocalLengthMin; // Min focal length (mm) double FocalLengthMax; // Max focal length (mm) + double FocalPlaneXResolution; // Focal plane X-resolution + double FocalPlaneYResolution; // Focal plane Y-resolution std::string Make; // Lens manufacturer std::string Model; // Lens model } LensInfo; diff --git a/test-images/down-mirrored.jpg.expected b/test-images/down-mirrored.jpg.expected index 3872608..1eb683f 100644 --- a/test-images/down-mirrored.jpg.expected +++ b/test-images/down-mirrored.jpg.expected @@ -23,9 +23,12 @@ Lens focal length : 0.000000 mm GPS Latitude : 0.000000 deg (0.000000 deg, 0.000000 min, 0.000000 sec ?) GPS Longitude : 0.000000 deg (0.000000 deg, 0.000000 min, 0.000000 sec ?) GPS Altitude : 0.000000 m +GPS Precision (DOP) : 0.000000 Lens min focal length: 0.000000 mm Lens max focal length: 0.000000 mm Lens f-stop min : f/0.0 Lens f-stop max : f/0.0 Lens make : Lens model : +Focal plane XRes : 0.000000 +Focal plane YRes : 0.000000 diff --git a/test-images/evil1.jpg b/test-images/evil1.jpg new file mode 100644 index 0000000..addb2d7 Binary files /dev/null and b/test-images/evil1.jpg differ diff --git a/test-images/evil1.jpg.expected b/test-images/evil1.jpg.expected new file mode 100644 index 0000000..c12f27e --- /dev/null +++ b/test-images/evil1.jpg.expected @@ -0,0 +1,34 @@ +Camera make : Canon +Camera model : Canon PowerShot S400 +Software : Adobe Photoshop 7.0 +Bits per sample : 0 +Image width : 400 +Image height : 300 +Image description : +Image orientation : 1 +Image copyright : +Image date/time : 2003:05:25 11:11:41 +Original date/time : 2003:05:24 16:40:33 +Digitize date/time : 2003:05:24 16:40:33 +Subsecond time : +Exposure time : 1/8 s +F-stop : f/2.8 +ISO speed : 0 +Subject distance : 0.000000 m +Exposure bias : 0.000000 EV +Flash used? : 1 +Metering mode : 5 +Lens focal length : 7.406250 mm +35mm focal length : 0 mm +GPS Latitude : 0.000000 deg (0.000000 deg, 0.000000 min, 0.000000 sec ?) +GPS Longitude : 0.000000 deg (0.000000 deg, 0.000000 min, 0.000000 sec ?) +GPS Altitude : 0.000000 m +GPS Precision (DOP) : 0.000000 +Lens min focal length: 0.000000 mm +Lens max focal length: 0.000000 mm +Lens f-stop min : f/0.0 +Lens f-stop max : f/0.0 +Lens make : +Lens model : +Focal plane XRes : 8114.285714 +Focal plane YRes : 8114.285714 diff --git a/test-images/lens_info.jpg.expected b/test-images/lens_info.jpg.expected index 150d0ae..c175a08 100644 --- a/test-images/lens_info.jpg.expected +++ b/test-images/lens_info.jpg.expected @@ -23,9 +23,12 @@ Lens focal length : 0.000000 mm GPS Latitude : 0.000000 deg (0.000000 deg, 0.000000 min, 0.000000 sec ?) GPS Longitude : 0.000000 deg (0.000000 deg, 0.000000 min, 0.000000 sec ?) GPS Altitude : 0.000000 m +GPS Precision (DOP) : 0.000000 Lens min focal length: 10.000000 mm Lens max focal length: 400.000000 mm Lens f-stop min : f/1.1 Lens f-stop max : f/1.2 Lens make : Lens Maker Inc. Lens model : Lens Model mk I +Focal plane XRes : 0.000000 +Focal plane YRes : 0.000000 diff --git a/test-images/right.jpg.expected b/test-images/right.jpg.expected index 0e8d026..1520034 100644 --- a/test-images/right.jpg.expected +++ b/test-images/right.jpg.expected @@ -23,9 +23,12 @@ Lens focal length : 0.000000 mm GPS Latitude : 0.000000 deg (0.000000 deg, 0.000000 min, 0.000000 sec ?) GPS Longitude : 0.000000 deg (0.000000 deg, 0.000000 min, 0.000000 sec ?) GPS Altitude : 0.000000 m +GPS Precision (DOP) : 0.000000 Lens min focal length: 0.000000 mm Lens max focal length: 0.000000 mm Lens f-stop min : f/0.0 Lens f-stop max : f/0.0 Lens make : Lens model : +Focal plane XRes : 0.000000 +Focal plane YRes : 0.000000 diff --git a/test-images/short-ascii-II.jpg.expected b/test-images/short-ascii-II.jpg.expected index 39f8d19..ddeb34e 100644 --- a/test-images/short-ascii-II.jpg.expected +++ b/test-images/short-ascii-II.jpg.expected @@ -23,9 +23,12 @@ Lens focal length : 3.510000 mm GPS Latitude : 0.000000 deg (0.000000 deg, 0.000000 min, 0.000000 sec ?) GPS Longitude : 0.000000 deg (0.000000 deg, 0.000000 min, 0.000000 sec ?) GPS Altitude : 0.000000 m +GPS Precision (DOP) : 0.000000 Lens min focal length: 0.000000 mm Lens max focal length: 0.000000 mm Lens f-stop min : f/0.0 Lens f-stop max : f/0.0 Lens make : Lens model : +Focal plane XRes : 0.000000 +Focal plane YRes : 0.000000 diff --git a/test-images/short-ascii-MM.jpg.expected b/test-images/short-ascii-MM.jpg.expected index b10a9a2..4fdb263 100644 --- a/test-images/short-ascii-MM.jpg.expected +++ b/test-images/short-ascii-MM.jpg.expected @@ -23,9 +23,12 @@ Lens focal length : 21.300000 mm GPS Latitude : 0.000000 deg (0.000000 deg, 0.000000 min, 0.000000 sec ?) GPS Longitude : 0.000000 deg (0.000000 deg, 0.000000 min, 0.000000 sec ?) GPS Altitude : 0.000000 m +GPS Precision (DOP) : 0.000000 Lens min focal length: 0.000000 mm Lens max focal length: 0.000000 mm Lens f-stop min : f/0.0 Lens f-stop max : f/0.0 Lens make : Lens model : +Focal plane XRes : 8114.285714 +Focal plane YRes : 8114.285714 diff --git a/test-images/sony-alpha-6000.jpg.expected b/test-images/sony-alpha-6000.jpg.expected index be2a578..a9304fa 100644 --- a/test-images/sony-alpha-6000.jpg.expected +++ b/test-images/sony-alpha-6000.jpg.expected @@ -23,9 +23,12 @@ Lens focal length : 22.000000 mm GPS Latitude : 0.000000 deg (0.000000 deg, 0.000000 min, 0.000000 sec ?) GPS Longitude : 0.000000 deg (0.000000 deg, 0.000000 min, 0.000000 sec ?) GPS Altitude : 0.000000 m +GPS Precision (DOP) : 0.000000 Lens min focal length: 16.000000 mm Lens max focal length: 50.000000 mm Lens f-stop min : f/3.5 Lens f-stop max : f/5.6 Lens make : Lens model : E PZ 16-50mm F3.5-5.6 OSS +Focal plane XRes : 0.000000 +Focal plane YRes : 0.000000 diff --git a/test-images/test1.jpg.expected b/test-images/test1.jpg.expected index bb33c40..15e6100 100644 --- a/test-images/test1.jpg.expected +++ b/test-images/test1.jpg.expected @@ -23,9 +23,12 @@ Lens focal length : 4.280000 mm GPS Latitude : 37.885000 deg (37.000000 deg, 53.100000 min, 0.000000 sec N) GPS Longitude : -122.622500 deg (122.000000 deg, 37.350000 min, 0.000000 sec W) GPS Altitude : 122.000000 m +GPS Precision (DOP) : 0.000000 Lens min focal length: 0.000000 mm Lens max focal length: 0.000000 mm Lens f-stop min : f/0.0 Lens f-stop max : f/0.0 Lens make : Lens model : +Focal plane XRes : 0.000000 +Focal plane YRes : 0.000000 diff --git a/test-images/test2.jpg.expected b/test-images/test2.jpg.expected index 10eb505..5f5a8e3 100644 --- a/test-images/test2.jpg.expected +++ b/test-images/test2.jpg.expected @@ -23,9 +23,12 @@ Lens focal length : 4.280000 mm GPS Latitude : 37.814667 deg (37.000000 deg, 48.880000 min, 0.000000 sec N) GPS Longitude : -122.264167 deg (122.000000 deg, 15.850000 min, 0.000000 sec W) GPS Altitude : 2.000000 m +GPS Precision (DOP) : 0.000000 Lens min focal length: 0.000000 mm Lens max focal length: 0.000000 mm Lens f-stop min : f/0.0 Lens f-stop max : f/0.0 Lens make : Lens model : +Focal plane XRes : 0.000000 +Focal plane YRes : 0.000000 diff --git a/test-images/test3.jpg.expected b/test-images/test3.jpg.expected index 256db1b..840d550 100644 --- a/test-images/test3.jpg.expected +++ b/test-images/test3.jpg.expected @@ -23,9 +23,12 @@ Lens focal length : 4.280000 mm GPS Latitude : 37.776333 deg (37.000000 deg, 46.580000 min, 0.000000 sec N) GPS Longitude : -122.419667 deg (122.000000 deg, 25.180000 min, 0.000000 sec W) GPS Altitude : 15.833345 m +GPS Precision (DOP) : 0.000000 Lens min focal length: 0.000000 mm Lens max focal length: 0.000000 mm Lens f-stop min : f/0.0 Lens f-stop max : f/0.0 Lens make : Lens model : +Focal plane XRes : 0.000000 +Focal plane YRes : 0.000000