1
0
mirror of https://github.com/cdcseacave/TinyEXIF.git synced 2026-07-21 19:23:01 +04:00
Files
TinyEXIF/TinyEXIF.h
T
2025-11-17 18:47:27 +02:00

313 lines
16 KiB
C++

/*
TinyEXIF.h -- A simple ISO C++ library to parse basic EXIF and XMP
information from a JPEG file.
Copyright (c) 2015-2025 Seacave
cdc.seacave@gmail.com
MIT License
*/
#ifndef __TINYEXIF_H__
#define __TINYEXIF_H__
#include <cstdint>
#include <string>
#include <vector>
#define TINYEXIF_MAJOR_VERSION 1
#define TINYEXIF_MINOR_VERSION 0
#define TINYEXIF_PATCH_VERSION 3
#ifdef _MSC_VER
# ifdef TINYEXIF_EXPORT
# define TINYEXIF_LIB __declspec(dllexport)
# elif defined(TINYEXIF_IMPORT)
# define TINYEXIF_LIB __declspec(dllimport)
# else
# define TINYEXIF_LIB
# endif
#elif __GNUC__ >= 4
# define TINYEXIF_LIB __attribute__((visibility("default")))
#else
# define TINYEXIF_LIB
#endif
namespace TinyEXIF {
enum ErrorCode {
PARSE_SUCCESS = 0, // Parse EXIF and/or XMP was successful
PARSE_INVALID_JPEG = 1, // No JPEG markers found in buffer, possibly invalid JPEG file
PARSE_UNKNOWN_BYTEALIGN = 2, // Byte alignment specified in EXIF file was unknown (neither Motorola nor Intel)
PARSE_ABSENT_DATA = 3, // No EXIF and/or XMP data found in JPEG file
PARSE_CORRUPT_DATA = 4, // EXIF and/or XMP header was found, but data was corrupted
};
enum FieldCode {
FIELD_NA = 0, // No EXIF or XMP data
FIELD_EXIF = (1 << 0), // EXIF data available
FIELD_XMP = (1 << 1), // XMP data available
FIELD_ALL = FIELD_EXIF|FIELD_XMP
};
class EntryParser;
//
// Interface class responsible for fetching stream data to be parsed
//
class TINYEXIF_LIB EXIFStream {
public:
virtual ~EXIFStream() {}
// Check the state of the stream.
virtual bool IsValid() const = 0;
// Return the pointer to the beginning of the desired size buffer
// following current buffer position.
virtual const uint8_t* GetBuffer(unsigned desiredLength) = 0;
// Advance current buffer position with the desired size;
// return false if stream ends in less than the desired size.
virtual bool SkipBuffer(unsigned desiredLength) = 0;
};
//
// Class responsible for storing and parsing EXIF & XMP metadata from a JPEG stream
//
class TINYEXIF_LIB EXIFInfo {
public:
EXIFInfo();
EXIFInfo(EXIFStream& stream);
EXIFInfo(std::istream& stream); // NB: the stream must have been opened in binary mode
EXIFInfo(const uint8_t* data, unsigned length);
// Parsing function for an entire JPEG image stream.
//
// PARAM 'stream': Interface to fetch JPEG image stream.
// PARAM 'data': A pointer to a JPEG image.
// PARAM 'length': The length of the JPEG image.
// RETURN: PARSE_SUCCESS (0) on success with 'result' filled out
// error code otherwise, as defined by the PARSE_* macros
int parseFrom(EXIFStream& stream);
int parseFrom(std::istream& stream); // NB: the stream must have been opened in binary mode
int parseFrom(const uint8_t* data, unsigned length);
// 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
// available (i.e., a blob starting with the bytes "Exif\0\0").
int parseFromEXIFSegment(const uint8_t* buf, unsigned len);
#ifndef TINYEXIF_NO_XMP_SUPPORT
// Parsing function for an XMP segment. This is used internally by parseFrom()
// but can be called for special cases where only the XMP section is
// available (i.e., a blob starting with the bytes "http://ns.adobe.com/xap/1.0/\0").
int parseFromXMPSegment(const uint8_t* buf, unsigned len);
int parseFromXMPSegmentXML(const char* szXML, unsigned len);
#endif // TINYEXIF_NO_XMP_SUPPORT
// Set all data members to default values.
// Should be called before parsing a new stream.
void clear();
private:
// Parse tag as Image IFD.
void parseIFDImage(EntryParser&, unsigned&, unsigned&);
// Parse tag as Exif IFD.
void parseIFDExif(EntryParser&);
// Parse tag as GPS IFD.
void parseIFDGPS(EntryParser&);
// Parse tag as MakerNote IFD.
void parseIFDMakerNote(EntryParser&);
public:
// Data fields
uint32_t Fields; // Store if EXIF and/or XMP data fields are available
uint32_t ImageWidth; // Image width reported in EXIF data
uint32_t ImageHeight; // Image height reported in EXIF data
uint32_t RelatedImageWidth; // Original image width reported in EXIF data
uint32_t RelatedImageHeight; // Original image height reported in EXIF data
std::string ImageDescription; // Image description
std::string Make; // Camera manufacturer's name
std::string Model; // Camera model
std::string SerialNumber; // Serial number of the body of the camera
uint16_t Orientation; // Image orientation, start of data corresponds to
// 0: unspecified in EXIF data
// 1: upper left of image
// 3: lower right of image
// 6: upper right of image
// 8: lower left of image
// 9: undefined
double XResolution; // Number of pixels per ResolutionUnit in the ImageWidth direction
double YResolution; // Number of pixels per ResolutionUnit in the ImageLength direction
uint16_t ResolutionUnit; // Unit of measurement for XResolution and YResolution
// 1: no absolute unit of measurement. Used for images that may have a non-square aspect ratio, but no meaningful absolute dimensions
// 2: inch
// 3: centimeter
uint16_t BitsPerSample; // Number of bits per component
std::string Software; // Software used
std::string DateTime; // File change date and time
std::string DateTimeOriginal; // Original file date and time (may not exist)
std::string DateTimeDigitized; // Digitization date and time (may not exist)
std::string SubSecTimeOriginal; // Sub-second time that original picture was taken
std::string Copyright; // File copyright information
double ExposureTime; // Exposure time in seconds
double FNumber; // F/stop
uint16_t ExposureProgram; // Exposure program
// 0: not defined
// 1: manual
// 2: normal program
// 3: aperture priority
// 4: shutter priority
// 5: creative program
// 6: action program
// 7: portrait mode
// 8: landscape mode
uint16_t ISOSpeedRatings; // ISO speed
double ShutterSpeedValue; // Shutter speed (reciprocal of exposure time)
double ApertureValue; // The lens aperture
double BrightnessValue; // The value of brightness
double ExposureBiasValue; // Exposure bias value in EV
double SubjectDistance; // Distance to focus point in meters
double FocalLength; // Focal length of lens in millimeters
uint16_t Flash; // Flash info
// Flash used (Flash&1)
// 0: no flash, >0: flash used
// Flash returned light status ((Flash & 6) >> 1)
// 0: no strobe return detection function
// 1: reserved
// 2: strobe return light not detected
// 3: strobe return light detected
// Flash mode ((Flash & 24) >> 3)
// 0: unknown
// 1: compulsory flash firing
// 2: compulsory flash suppression
// 3: auto mode
// Flash function ((Flash & 32) >> 5)
// 0: flash function present, >0: no flash function
// Flash red-eye ((Flash & 64) >> 6)
// 0: no red-eye reduction mode or unknown, >0: red-eye reduction supported
uint16_t MeteringMode; // Metering mode
// 0: unknown
// 1: average
// 2: center weighted average
// 3: spot
// 4: multi-spot
// 5: pattern
// 6: partial
uint16_t LightSource; // Kind of light source
// 0: unknown
// 1: daylight
// 2: fluorescent
// 3: tungsten (incandescent light)
// 4: flash
// 9: fine weather
// 10: cloudy weather
// 11: shade
// 12: daylight fluorescent (D 5700 - 7100K)
// 13: day white fluorescent (N 4600 - 5400K)
// 14: cool white fluorescent (W 3900 - 4500K)
// 15: white fluorescent (WW 3200 - 3700K)
// 17: standard light A
// 18: standard light B
// 19: standard light C
// 20: D55
// 21: D65
// 22: D75
// 23: D50
// 24: ISO studio tungsten
uint16_t ProjectionType; // Projection type
// 0: unknown projection
// 1: perspective projection
// 2: equirectangular/spherical projection
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
// 0: unknown
// 2: location of the main subject as coordinates (first value is the X coordinate and second is the Y coordinate)
// 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)
// 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)
struct TINYEXIF_LIB Calibration_t { // Camera calibration information
double FocalLength; // Focal length (pixels)
double OpticalCenterX; // Principal point X (pixels)
double OpticalCenterY; // Principal point Y (pixels)
bool hasCalibration() const; // Return true if FocalLength, OpticalCenterX, OpticalCenterY are available (nonzero)
} Calibration;
struct TINYEXIF_LIB Distortion_t { // Lens distortion information
uint32_t DewarpFlag; // Dewarp flag - indicates whether undistortion has been applied to the image
// UINT32_MAX: flag missing from EXIF data
// 0: no dewarp (raw image) - the image is distorted, should also have coefficients
// 1: dewarp applied (undistorted image)
double K1;
double K2;
double P1;
double P2;
double K3;
bool hasDewarpFlag() const; // Return true if DewarpFlag is available
bool hasDistortion() const; // Return true if any of K1, K2, P1, P2, K3 are available
} Distortion;
struct TINYEXIF_LIB 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 DigitalZoomRatio; // Digital zoom ratio when the image was shot
double FocalLengthIn35mm; // Focal length in 35mm film
double FocalPlaneXResolution; // Number of pixels in the image width (X) direction per FocalPlaneResolutionUnit on the camera focal plane (may not exist)
double FocalPlaneYResolution; // Number of pixels in the image width (Y) direction per FocalPlaneResolutionUnit on the camera focal plane (may not exist)
uint16_t FocalPlaneResolutionUnit;// Unit for measuring FocalPlaneXResolution and FocalPlaneYResolution (may not exist)
// 0: unspecified in EXIF data
// 1: no absolute unit of measurement
// 2: inch
// 3: centimeter
std::string Make; // Lens manufacturer
std::string Model; // Lens model
} LensInfo;
struct TINYEXIF_LIB Geolocation_t { // GPS information embedded in file
double Latitude; // Image latitude expressed as decimal
double Longitude; // Image longitude expressed as decimal
double Altitude; // Altitude in meters, relative to sea level
int8_t AltitudeRef; // 0: above sea level, -1: below sea level
double RelativeAltitude; // Relative altitude in meters
double RollDegree; // Flight roll in degrees
double PitchDegree; // Flight pitch in degrees
double YawDegree; // Flight yaw in degrees
double SpeedX; // Flight speed on X in meters/second
double SpeedY; // Flight speed on Y in meters/second
double SpeedZ; // Flight speed on Z in meters/second
double AccuracyXY; // GPS accuracy on XY in meters
double AccuracyZ; // GPS accuracy on Z in meters
double GPSDOP; // GPS DOP (data degree of precision)
uint16_t GPSDifferential; // Differential correction applied to the GPS receiver (may not exist)
// 0: measurement without differential correction
// 1: differential correction applied
std::string GPSMapDatum; // Geodetic survey data (may not exist)
std::string GPSTimeStamp; // Time as UTC (Coordinated Universal Time) (may not exist)
std::string GPSDateStamp; // A character string recording date and time information relative to UTC (Coordinated Universal Time) YYYY:MM:DD (may not exist)
struct Coord_t {
double degrees;
double minutes;
double seconds;
uint8_t direction;
} LatComponents, LonComponents; // Latitude/Longitude expressed in deg/min/sec
void parseCoords(); // Convert Latitude/Longitude from deg/min/sec to decimal
bool hasLatLon() const; // Return true if (lat,lon) is available
bool hasAltitude() const; // Return true if (alt) is available
bool hasRelativeAltitude()const;// Return true if (rel_alt) is available
bool hasOrientation() const; // Return true if (roll,yaw,pitch) is available
bool hasSpeed() const; // Return true if (speedX,speedY,speedZ) is available
bool hasAccuracy() const; // Return true if (accuracyXY,accuracyZ) is available
} GeoLocation;
struct TINYEXIF_LIB GPano_t { // Spherical metadata. https://developers.google.com/streetview/spherical-metadata
double PosePitchDegrees; // Pitch, measured in degrees above the horizon, for the center in the image. Value must be >= -90 and <= 90.
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.
bool hasPosePitchDegrees() const; // Return true if PosePitchDegrees is available
bool hasPoseRollDegrees() const; // Return true if PoseRollDegrees is available
} GPano;
struct TINYEXIF_LIB MicroVideo_t { // Google camera video file in metadata
uint32_t HasMicroVideo; // not zero if exists
uint32_t MicroVideoVersion; // just regularinfo
uint32_t MicroVideoOffset; // offset from end of file
} MicroVideo;
};
} // namespace TinyEXIF
#endif // __TINYEXIF_H__