#ifndef DNGINFO_TIFF_H #define DNGINFO_TIFF_H #include #include #include #include #include #include constexpr int16_t TIFF_MAGIC = 42; enum ByteOrder: uint16_t { LE = 0x4949, BE = 0x4d4d }; enum FieldType: uint16_t { BYTE = 1, ASCII = 2, SHORT = 3, LONG = 4, RATIONAL = 5, SBYTE = 6, UNDEFINED = 7, SSHORT = 8, SLONG = 9, SRATIONAL = 10, FLOAT = 11, DOUBLE = 12 }; enum TiffTag: uint16_t { NEW_SUBFILE_TYPE = 0xFE, IMAGE_WIDTH = 0x100, IMAGE_LENGTH = 0x101, BITS_PER_SAMPLE = 0x102, COMPRESSION = 0x103, PHOTOMETRIC_INTERPRETATION = 0x106, IMAGE_DESCRIPTION = 0x10E, MANUFACTURER = 0x10F, MODEL = 0x110, STRIP_OFFSETS = 0x111, ORIENTATION = 0x112, SAMPLES_PER_PIXEL = 0x115, ROWS_PER_STRIP = 0x116, STRIP_BYTE_COUNTS = 0x117, X_RESOLUTION = 0x11A, Y_RESOLUTION = 0x11B, PLANAR_CONFIGURATION = 0x11C, RESOLUTION_UNIT = 0x128, SOFTWARE = 0x131, DATE_TIME = 0x132, XML_PACKET = 0x2BC, CFA_REPEAT_PATTERN_DIM = 0x828D, CFA_PATTERN = 0x828E, EXPOSURE_TIME = 0x829A, F_NUMBER = 0x829D, EXIF_IFD = 0x8769, ISO_SPEED_RATINGS = 0x8827, DATE_TIME_ORIGINAL = 0x9003, FOCAL_LENGTH = 0x920A, TIFF_EP_STANDARD_ID = 0x9216 }; enum PhotometricInterpretation: uint16_t { WHITE_IS_ZERO = 0, BLACK_IS_ZERO = 1, RGB = 2, PALETTE_COLOR = 3, TRANSPARENCY_MASK = 4, YCBCR = 6, COLOR_FILTER_ARRAY = 32803, LINEAR_RAW = 34892 }; enum Compression: uint16_t { NO_COMPRESSION = 1, HUFFMAN = 2, PACK_BITS = 32773 }; enum ResolutionUnit: uint16_t { NO_UNIT = 1, INCH = 2, CENTIMETER = 3 }; enum Orientation: uint16_t { NORMAL = 1, FLIP_HORIZONTAL = 2, FLIP_BOTH = 3, FLIP_VERTICAL = 4, NORMAL_ROTATED = 5, FLIP_HORIZONTAL_ROTATED = 6, FLIP_BOTH_ROTATED = 7, FLIP_VERTICAL_ROTATED = 8 }; enum PlanarConfiguration : uint16_t { CHUNKY = 1, PLANAR = 2 }; struct TIFFHeader { ByteOrder byteOrder; uint16_t magic; uint32_t firstIfdOffset; }; struct IfdEntry { TiffTag tag; FieldType type; uint32_t numberOfValues; uint32_t valueOrOffset; }; template struct RationalType { T numerator; T denominator; }; using Rational = RationalType; using SRational = RationalType; enum CFAPatternDim: uint16_t {}; enum CFAPattern: uint8_t { RED = 0, GREEN = 1, BLUE = 2, CYAN = 3, MAGENTA = 4, YELLOW = 5, WHITE = 6 }; std::ostream& operator<<(std::ostream& stream, Compression compression); std::ostream& operator<<(std::ostream& stream, PhotometricInterpretation pr); template std::ostream& operator<<(std::ostream& stream, const RationalType& rational); std::ostream& operator<<(std::ostream& stream, ResolutionUnit unit); std::ostream& operator<<(std::ostream& stream, Orientation orientation); std::ostream& operator<<(std::ostream& stream, PlanarConfiguration conf); template std::ostream& operator<<(std::ostream& stream, const std::vector& vector); class ImageFileDirectory { public: using EntryValueType = std::variant, std::vector, ResolutionUnit, std::vector, Orientation, std::vector, PlanarConfiguration, std::vector, CFAPatternDim, std::vector, CFAPattern, std::vector, std::vector, std::vector, std::vector, std::vector, std::vector, std::vector, std::vector, std::vector, std::vector, std::vector>; public: explicit ImageFileDirectory(char* ptr, char* filePtr); uint32_t nextOffset() const; std::optional operator[](TiffTag tag) const; void dumpInfo() const; private: size_t sizeOfType(FieldType type) const; template void parseValue(char* filePtr, IfdEntry* entry); template void parseValueImpl(char* filePtr, IfdEntry* entry); private: uint16_t _entriesCount; IfdEntry* _entries; uint32_t _nextIfdOffset; std::map _entriesMap; }; class TIFF { public: explicit TIFF(std::string fileName); std::vector ifds() const; private: std::unique_ptr _data; std::vector _ifds; }; #endif //DNGINFO_TIFF_H