1/* 
2 TinyEXIF.h -- A simple ISO C++ library to parse basic EXIF and XMP 
3 information from a JPEG file. 
4 
5 Copyright (c) 2015-2017 Seacave 
6 cdc.seacave@gmail.com 
7 All rights reserved. 
8 
9 Based on the easyexif library (2013 version) 
10 https://github.com/mayanklahiri/easyexif 
11 of Mayank Lahiri (mlahiri@gmail.com). 
12  
13 Redistribution and use in source and binary forms, with or without  
14 modification, are permitted provided that the following conditions are met: 
15 
16 - Redistributions of source code must retain the above copyright notice,  
17 this list of conditions and the following disclaimer. 
18 - Redistributions in binary form must reproduce the above copyright notice,  
19 this list of conditions and the following disclaimer in the documentation  
20 and/or other materials provided with the distribution. 
21 
22 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY EXPRESS  
23 OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES  
24 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN  
25 NO EVENT SHALL THE FREEBSD PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,  
26 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,  
27 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,  
28 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY  
29 OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING  
30 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,  
31 EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
32*/ 
33 
34#ifndef __TINYEXIF_H__ 
35#define __TINYEXIF_H__ 
36 
37#include <cstdint> 
38#include <string> 
39#include <vector> 
40 
41#define TINYEXIF_MAJOR_VERSION 1 
42#define TINYEXIF_MINOR_VERSION 0 
43#define TINYEXIF_PATCH_VERSION 1 
44 
45#ifdef _MSC_VER 
46# ifdef TINYEXIF_EXPORT 
47# define TINYEXIF_LIB __declspec(dllexport) 
48# elif defined(TINYEXIF_IMPORT) 
49# define TINYEXIF_LIB __declspec(dllimport) 
50# else 
51# define TINYEXIF_LIB 
52# endif 
53#elif __GNUC__ >= 4 
54# define TINYEXIF_LIB __attribute__((visibility("default"))) 
55#else 
56# define TINYEXIF_LIB 
57#endif 
58 
59namespace TinyEXIF
60 
61enum ErrorCode
62 PARSE_SUCCESS = 0, // Parse EXIF and/or XMP was successful 
63 PARSE_INVALID_JPEG = 1, // No JPEG markers found in buffer, possibly invalid JPEG file 
64 PARSE_UNKNOWN_BYTEALIGN = 2, // Byte alignment specified in EXIF file was unknown (neither Motorola nor Intel) 
65 PARSE_ABSENT_DATA = 3, // No EXIF and/or XMP data found in JPEG file 
66 PARSE_CORRUPT_DATA = 4, // EXIF and/or XMP header was found, but data was corrupted 
67}; 
68 
69enum FieldCode
70 FIELD_NA = 0, // No EXIF or XMP data 
71 FIELD_EXIF = (1 << 0), // EXIF data available 
72 FIELD_XMP = (1 << 1), // XMP data available 
73 FIELD_ALL = FIELD_EXIF|FIELD_XMP 
74}; 
75 
76class EntryParser
77 
78// 
79// Interface class responsible for fetching stream data to be parsed 
80// 
81class TINYEXIF_LIB EXIFStream
82public
83 virtual ~EXIFStream() {} 
84 
85 // Check the state of the stream. 
86 virtual bool IsValid() const = 0
87 
88 // Return the pointer to the beginning of the desired size buffer 
89 // following current buffer position. 
90 virtual const uint8_t* GetBuffer(unsigned desiredLength) = 0
91 
92 // Advance current buffer position with the desired size; 
93 // return false if stream ends in less than the desired size. 
94 virtual bool SkipBuffer(unsigned desiredLength) = 0
95}; 
96 
97// 
98// Class responsible for storing and parsing EXIF & XMP metadata from a JPEG stream 
99// 
100class TINYEXIF_LIB EXIFInfo
101public
102 EXIFInfo(); 
103 EXIFInfo(EXIFStream& stream); 
104 EXIFInfo(std::istream& stream); // NB: the stream must have been opened in binary mode 
105 EXIFInfo(const uint8_t* data, unsigned length); 
106 
107 // Parsing function for an entire JPEG image stream. 
108 // 
109 // PARAM 'stream': Interface to fetch JPEG image stream. 
110 // PARAM 'data': A pointer to a JPEG image. 
111 // PARAM 'length': The length of the JPEG image. 
112 // RETURN: PARSE_SUCCESS (0) on success with 'result' filled out 
113 // error code otherwise, as defined by the PARSE_* macros 
114 int parseFrom(EXIFStream& stream); 
115 int parseFrom(std::istream& stream); // NB: the stream must have been opened in binary mode 
116 int parseFrom(const uint8_t* data, unsigned length); 
117 
118 // Parsing function for an EXIF segment. This is used internally by parseFrom() 
119 // but can be called for special cases where only the EXIF section is  
120 // available (i.e., a blob starting with the bytes "Exif\0\0"). 
121 int parseFromEXIFSegment(const uint8_t* buf, unsigned len); 
122 
123#ifndef TINYEXIF_NO_XMP_SUPPORT 
124 // Parsing function for an XMP segment. This is used internally by parseFrom() 
125 // but can be called for special cases where only the XMP section is  
126 // available (i.e., a blob starting with the bytes "http://ns.adobe.com/xap/1.0/\0"). 
127 int parseFromXMPSegment(const uint8_t* buf, unsigned len); 
128 int parseFromXMPSegmentXML(const char* szXML, unsigned len); 
129#endif // TINYEXIF_NO_XMP_SUPPORT 
130 
131 // Set all data members to default values. 
132 // Should be called before parsing a new stream. 
133 void clear(); 
134 
135private
136 // Parse tag as Image IFD. 
137 void parseIFDImage(EntryParser&, unsigned&, unsigned&); 
138 // Parse tag as Exif IFD. 
139 void parseIFDExif(EntryParser&); 
140 // Parse tag as GPS IFD. 
141 void parseIFDGPS(EntryParser&); 
142 // Parse tag as MakerNote IFD. 
143 void parseIFDMakerNote(EntryParser&); 
144 
145public
146 // Data fields 
147 uint32_t Fields; // Store if EXIF and/or XMP data fields are available 
148 uint32_t ImageWidth; // Image width reported in EXIF data 
149 uint32_t ImageHeight; // Image height reported in EXIF data 
150 uint32_t RelatedImageWidth; // Original image width reported in EXIF data 
151 uint32_t RelatedImageHeight; // Original image height reported in EXIF data 
152 std::string ImageDescription; // Image description 
153 std::string Make; // Camera manufacturer's name 
154 std::string Model; // Camera model 
155 std::string SerialNumber; // Serial number of the body of the camera 
156 uint16_t Orientation; // Image orientation, start of data corresponds to 
157 // 0: unspecified in EXIF data 
158 // 1: upper left of image 
159 // 3: lower right of image 
160 // 6: upper right of image 
161 // 8: lower left of image 
162 // 9: undefined 
163 double XResolution; // Number of pixels per ResolutionUnit in the ImageWidth direction 
164 double YResolution; // Number of pixels per ResolutionUnit in the ImageLength direction 
165 uint16_t ResolutionUnit; // Unit of measurement for XResolution and YResolution 
166 // 1: no absolute unit of measurement. Used for images that may have a non-square aspect ratio, but no meaningful absolute dimensions 
167 // 2: inch 
168 // 3: centimeter 
169 uint16_t BitsPerSample; // Number of bits per component 
170 std::string Software; // Software used 
171 std::string DateTime; // File change date and time 
172 std::string DateTimeOriginal; // Original file date and time (may not exist) 
173 std::string DateTimeDigitized; // Digitization date and time (may not exist) 
174 std::string SubSecTimeOriginal; // Sub-second time that original picture was taken 
175 std::string Copyright; // File copyright information 
176 double ExposureTime; // Exposure time in seconds 
177 double FNumber; // F/stop 
178 uint16_t ExposureProgram; // Exposure program 
179 // 0: not defined 
180 // 1: manual 
181 // 2: normal program 
182 // 3: aperture priority 
183 // 4: shutter priority 
184 // 5: creative program 
185 // 6: action program 
186 // 7: portrait mode 
187 // 8: landscape mode 
188 uint16_t ISOSpeedRatings; // ISO speed 
189 double ShutterSpeedValue; // Shutter speed (reciprocal of exposure time) 
190 double ApertureValue; // The lens aperture 
191 double BrightnessValue; // The value of brightness 
192 double ExposureBiasValue; // Exposure bias value in EV 
193 double SubjectDistance; // Distance to focus point in meters 
194 double FocalLength; // Focal length of lens in millimeters 
195 uint16_t Flash; // Flash info 
196 // Flash used (Flash&1) 
197 // 0: no flash, >0: flash used 
198 // Flash returned light status ((Flash & 6) >> 1) 
199 // 0: no strobe return detection function 
200 // 1: reserved 
201 // 2: strobe return light not detected 
202 // 3: strobe return light detected 
203 // Flash mode ((Flash & 24) >> 3) 
204 // 0: unknown 
205 // 1: compulsory flash firing 
206 // 2: compulsory flash suppression 
207 // 3: auto mode 
208 // Flash function ((Flash & 32) >> 5) 
209 // 0: flash function present, >0: no flash function 
210 // Flash red-eye ((Flash & 64) >> 6) 
211 // 0: no red-eye reduction mode or unknown, >0: red-eye reduction supported 
212 uint16_t MeteringMode; // Metering mode 
213 // 0: unknown 
214 // 1: average 
215 // 2: center weighted average 
216 // 3: spot 
217 // 4: multi-spot 
218 // 5: pattern 
219 // 6: partial 
220 uint16_t LightSource; // Kind of light source 
221 // 0: unknown 
222 // 1: daylight 
223 // 2: fluorescent 
224 // 3: tungsten (incandescent light) 
225 // 4: flash 
226 // 9: fine weather 
227 // 10: cloudy weather 
228 // 11: shade 
229 // 12: daylight fluorescent (D 5700 - 7100K) 
230 // 13: day white fluorescent (N 4600 - 5400K) 
231 // 14: cool white fluorescent (W 3900 - 4500K) 
232 // 15: white fluorescent (WW 3200 - 3700K) 
233 // 17: standard light A 
234 // 18: standard light B 
235 // 19: standard light C 
236 // 20: D55 
237 // 21: D65 
238 // 22: D75 
239 // 23: D50 
240 // 24: ISO studio tungsten 
241 uint16_t ProjectionType; // Projection type 
242 // 0: unknown projection 
243 // 1: perspective projection 
244 // 2: equirectangular/spherical projection 
245 std::vector<uint16_t> SubjectArea; // Location and area of the main subject in the overall scene expressed in relation to the upper left as origin, prior to rotation 
246 // 0: unknown 
247 // 2: location of the main subject as coordinates (first value is the X coordinate and second is the Y coordinate) 
248 // 3: area of the main subject as a circle (first value is the center X coordinate, second is the center Y coordinate, and third is the diameter) 
249 // 4: area of the main subject as a rectangle (first value is the center X coordinate, second is the center Y coordinate, third is the width of the area, and fourth is the height of the area) 
250 struct TINYEXIF_LIB Calibration_t { // Camera calibration information 
251 double FocalLength; // Focal length (pixels) 
252 double OpticalCenterX; // Principal point X (pixels) 
253 double OpticalCenterY; // Principal point Y (pixels) 
254 } Calibration
255 struct TINYEXIF_LIB LensInfo_t { // Lens information 
256 double FStopMin; // Min aperture (f-stop) 
257 double FStopMax; // Max aperture (f-stop) 
258 double FocalLengthMin; // Min focal length (mm) 
259 double FocalLengthMax; // Max focal length (mm) 
260 double DigitalZoomRatio; // Digital zoom ratio when the image was shot 
261 double FocalLengthIn35mm; // Focal length in 35mm film 
262 double FocalPlaneXResolution; // Number of pixels in the image width (X) direction per FocalPlaneResolutionUnit on the camera focal plane (may not exist) 
263 double FocalPlaneYResolution; // Number of pixels in the image width (Y) direction per FocalPlaneResolutionUnit on the camera focal plane (may not exist) 
264 uint16_t FocalPlaneResolutionUnit;// Unit for measuring FocalPlaneXResolution and FocalPlaneYResolution (may not exist) 
265 // 0: unspecified in EXIF data 
266 // 1: no absolute unit of measurement 
267 // 2: inch 
268 // 3: centimeter 
269 std::string Make; // Lens manufacturer 
270 std::string Model; // Lens model 
271 } LensInfo
272 struct TINYEXIF_LIB Geolocation_t { // GPS information embedded in file 
273 double Latitude; // Image latitude expressed as decimal 
274 double Longitude; // Image longitude expressed as decimal 
275 double Altitude; // Altitude in meters, relative to sea level 
276 int8_t AltitudeRef; // 0: above sea level, -1: below sea level 
277 double RelativeAltitude; // Relative altitude in meters 
278 double RollDegree; // Flight roll in degrees 
279 double PitchDegree; // Flight pitch in degrees 
280 double YawDegree; // Flight yaw in degrees 
281 double SpeedX; // Flight speed on X in meters/second 
282 double SpeedY; // Flight speed on Y in meters/second 
283 double SpeedZ; // Flight speed on Z in meters/second 
284 double AccuracyXY; // GPS accuracy on XY in meters 
285 double AccuracyZ; // GPS accuracy on Z in meters 
286 double GPSDOP; // GPS DOP (data degree of precision) 
287 uint16_t GPSDifferential; // Differential correction applied to the GPS receiver (may not exist) 
288 // 0: measurement without differential correction 
289 // 1: differential correction applied  
290 std::string GPSMapDatum; // Geodetic survey data (may not exist) 
291 std::string GPSTimeStamp; // Time as UTC (Coordinated Universal Time) (may not exist) 
292 std::string GPSDateStamp; // A character string recording date and time information relative to UTC (Coordinated Universal Time) YYYY:MM:DD (may not exist) 
293 struct Coord_t
294 double degrees
295 double minutes
296 double seconds
297 uint8_t direction
298 } LatComponents, LonComponents; // Latitude/Longitude expressed in deg/min/sec 
299 void parseCoords(); // Convert Latitude/Longitude from deg/min/sec to decimal 
300 bool hasLatLon() const; // Return true if (lat,lon) is available 
301 bool hasAltitude() const; // Return true if (alt) is available 
302 bool hasRelativeAltitude()const;// Return true if (rel_alt) is available 
303 bool hasOrientation() const; // Return true if (roll,yaw,pitch) is available 
304 bool hasSpeed() const; // Return true if (speedX,speedY,speedZ) is available 
305 } GeoLocation
306 struct TINYEXIF_LIB GPano_t { // Spherical metadata. https://developers.google.com/streetview/spherical-metadata 
307 double PosePitchDegrees; // Pitch, measured in degrees above the horizon, for the center in the image. Value must be >= -90 and <= 90. 
308 double PoseRollDegrees; // Roll, measured in degrees, of the image where level with the horizon is 0. As roll increases, the horizon rotates counterclockwise in the image. Value must be > -180 and <= 180. 
309 bool hasPosePitchDegrees() const; // Return true if PosePitchDegrees is available 
310 bool hasPoseRollDegrees() const; // Return true if PoseRollDegrees is available 
311 } GPano
312 struct TINYEXIF_LIB MicroVideo_t { // Google camera video file in metadata 
313 uint32_t HasMicroVideo; // not zero if exists 
314 uint32_t MicroVideoVersion; // just regularinfo 
315 uint32_t MicroVideoOffset; // offset from end of file 
316 } MicroVideo
317}; 
318 
319} // namespace TinyEXIF 
320 
321#endif // __TINYEXIF_H__ 
322