/*------------------------------------------------------------- tiio_jpg_exif.h Based on source code of a public domain software "Exif Jpeg header manipulation tool (jhead)" by Matthias Wandel. For now it is used only for obtaining resolution values. http://www.sentex.net/~mwandel/jhead/ -------------------------------------------------------------*/ #pragma once #ifndef TIIO_JPG_EXIF_H #define TIIO_JPG_EXIF_H #include // undefining ReadAllTags will load only resolution information #define ReadAllTags #undef ReadAllTags #define MAX_COMMENT_SIZE 16000 #define MAX_DATE_COPIES 10 #ifdef _WIN32 #define PATH_MAX _MAX_PATH #define SLASH '\\' #else #ifndef PATH_MAX #define PATH_MAX 1024 #endif #define SLASH '/' #endif class JpgExifReader { enum FORMATS { FMT_BYTE = 1, FMT_STRING, FMT_USHORT, FMT_ULONG, FMT_URATIONAL, FMT_SBYTE, FMT_UNDEFINED, FMT_SSHORT, FMT_SLONG, FMT_SRATIONAL, FMT_SINGLE, FMT_DOUBLE }; int NUM_FORMATS = FMT_DOUBLE; struct ExifImageInfo { float xResolution = 0.0; float yResolution = 0.0; int ResolutionUnit; #ifdef ReadAllTags char FileName[PATH_MAX + 1]; time_t FileDateTime; unsigned FileSize; char CameraMake[32]; char CameraModel[40]; char DateTime[20]; unsigned Height, Width; int Orientation; int IsColor; int Process; int FlashUsed; float FocalLength; float ExposureTime; float ApertureFNumber; float Distance; float CCDWidth; float ExposureBias; float DigitalZoomRatio; int FocalLength35mmEquiv; // Exif 2.2 tag - usually not present. int Whitebalance; int MeteringMode; int ExposureProgram; int ExposureMode; int ISOequivalent; int LightSource; int DistanceRange; char Comments[MAX_COMMENT_SIZE]; int CommentWidthchars; // If nonzero, widechar comment, indicates number of // chars. unsigned ThumbnailOffset; // Exif offset to thumbnail unsigned ThumbnailSize; // Size of thumbnail. unsigned LargestExifOffset; // Last exif data referenced (to check if // thumbnail is at end) char ThumbnailAtEnd; // Exif header ends with the thumbnail // (we can only modify the thumbnail if its at the end) int ThumbnailSizeOffset; int DateTimeOffsets[MAX_DATE_COPIES]; int numDateTimeTags = 0; int GpsInfoPresent; char GpsLat[31]; char GpsLong[31]; char GpsAlt[20]; int QualityGuess; #endif } ImageInfo; #ifdef ReadAllTags unsigned char* DirWithThumbnailPtrs; double FocalplaneXRes; double FocalplaneUnits; int ExifImageWidth; // for fixing the rotation. void* OrientationPtr[2]; int OrientationNumFormat[2]; int NumOrientations = 0; #endif int MotorolaOrder = 0; int Get16u(void* Short); unsigned Get32u(void* Long); int Get32s(void* Long); void PrintFormatNumber(void* ValuePtr, int Format, int ByteCount); double ConvertAnyFormat(void* ValuePtr, int Format); public: void process_EXIF(unsigned char* ExifSection, unsigned int length); void ProcessExifDir(unsigned char* DirStart, unsigned char* OffsetBase, unsigned ExifLength, int NestingLevel); // obtaining resolution info bool containsResolution() { return ImageInfo.xResolution != 0.0; } float getXResolution() { return ImageInfo.xResolution; } float getYResolution() { return ImageInfo.yResolution; } int getResolutionUnit() { return ImageInfo.ResolutionUnit; } }; #endif