dnginfo/TIFF.h

228 lines
5.6 KiB
C++

#ifndef DNGINFO_TIFF_H
#define DNGINFO_TIFF_H
#include <string>
#include <memory>
#include <cstdint>
#include <vector>
#include <map>
#include <variant>
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,
COPYRIGHT_NOTICE = 0x8298,
EXPOSURE_TIME = 0x829A,
F_NUMBER = 0x829D,
EXIF_IFD = 0x8769,
GPS_INFO = 0x8825,
ISO_SPEED_RATINGS = 0x8827,
DATE_TIME_ORIGINAL = 0x9003,
FOCAL_LENGTH = 0x920A,
TIFF_EP_STANDARD_ID = 0x9216,
DNG_VERSION = 0xC612,
DNG_BACKWARD_VERSION = 0xC613,
UNIQUE_CAMERA_MODEL = 0xC614,
CFA_PLANE_COLOR = 0xC616,
CFA_LAYOUT = 0xC617,
BLACK_LEVEL_REPEAT_DIM = 0xC619,
BLACK_LEVEL = 0xC61A,
WHITE_LEVEL = 0xC61D,
DEFAULT_SCALE = 0xC61E,
DEFAULT_CROP_ORIGIN = 0xC61F,
DEFAULT_CROP_SIZE = 0xC620,
COLOR_MATRIX_1 = 0xC621,
COLOR_MATRIX_2 = 0xC622,
CAMERA_CALIBRATION_1 = 0xC623,
CAMERA_CALIBRATION_2 = 0xC624,
AS_SHOT_NEUTRAL = 0xC628,
BASELINE_EXPOSURE = 0xC62A,
CALIBRATION_ILLUMINANT_1 = 0xC65A,
CALIBRATION_ILLUMINANT_2 = 0xC65B,
ACTIVE_AREA = 0xC68D,
FORWARD_MATRIX_1 = 0xC714,
FORWARD_MATRIX_2 = 0xC715,
OPCODE_LIST_1 = 0xC740,
OPCODE_LIST_2 = 0xC741,
OPCODE_LIST_3 = 0xC74E,
NOISE_PROFILE = 0xC761
};
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 <typename T>
struct RationalType {
T numerator;
T denominator;
};
using Rational = RationalType<uint32_t>;
using SRational = RationalType<int32_t>;
enum CFAPatternDim: uint16_t {};
enum CFAPattern: uint8_t {
RED = 0,
GREEN = 1,
BLUE = 2,
CYAN = 3,
MAGENTA = 4,
YELLOW = 5,
WHITE = 6
};
enum CFALayout: uint16_t {
RECTANGULAR = 1,
STAGGERED_LAYOUT_A = 2,
STAGGERED_LAYOUT_B = 3,
STAGGERED_LAYOUT_C = 4,
STAGGERED_LAYOUT_D = 5,
STAGGERED_LAYOUT_E = 6,
STAGGERED_LAYOUT_F = 7,
STAGGERED_LAYOUT_G = 8,
STAGGERED_LAYOUT_H = 9
};
std::ostream& operator<<(std::ostream& stream, Compression compression);
std::ostream& operator<<(std::ostream& stream, PhotometricInterpretation pr);
template<typename T> std::ostream& operator<<(std::ostream& stream, const RationalType<T>& 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<typename T> std::ostream& operator<<(std::ostream& stream, const std::vector<T>& vector);
class ImageFileDirectory {
public:
using EntryValueType = std::variant<uint8_t, uint16_t, uint32_t, Rational, int8_t, int16_t, int32_t, SRational, float, double, std::string,
Compression, PhotometricInterpretation, std::vector<Compression>, std::vector<PhotometricInterpretation>,
ResolutionUnit, std::vector<ResolutionUnit>, Orientation, std::vector<Orientation>,
PlanarConfiguration, std::vector<PlanarConfiguration>,
CFAPatternDim, std::vector<CFAPatternDim>,
CFAPattern, std::vector<CFAPattern>,
CFALayout, std::vector<CFALayout>,
std::vector<uint8_t>, std::vector<uint16_t>, std::vector<uint32_t>, std::vector<Rational>,
std::vector<int8_t>, std::vector<int16_t>, std::vector<int32_t>, std::vector<SRational>,
std::vector<float>, std::vector<double>>;
public:
explicit ImageFileDirectory(char* ptr, char* filePtr);
uint32_t nextOffset() const;
std::optional<EntryValueType> operator[](TiffTag tag) const;
void dumpInfo() const;
private:
size_t sizeOfType(FieldType type) const;
template<typename T> void parseValue(char* filePtr, IfdEntry* entry);
template<typename T> void parseValueImpl(char* filePtr, IfdEntry* entry);
private:
uint16_t _entriesCount;
IfdEntry* _entries;
uint32_t _nextIfdOffset;
std::map<TiffTag, EntryValueType> _entriesMap;
};
class TIFF {
public:
explicit TIFF(std::string fileName);
std::vector<ImageFileDirectory> ifds() const;
private:
std::unique_ptr<char[]> _data;
std::vector<ImageFileDirectory> _ifds;
};
#endif //DNGINFO_TIFF_H