33#include "libavutil/avconfig.h"
43#define EXIF_II_LONG 0x49492a00
44#define EXIF_MM_LONG 0x4d4d002a
46#define BASE_TAG_SIZE 12
47#define IFD_EXTRA_SIZE 6
49#define EXIF_TAG_NAME_LENGTH 32
50#define MAKERNOTE_TAG 0x927c
51#define ORIENTATION_TAG 0x112
52#define EXIFIFD_TAG 0x8769
53#define IMAGE_WIDTH_TAG 0x100
54#define IMAGE_LENGTH_TAG 0x101
55#define PIXEL_X_TAG 0xa002
56#define PIXEL_Y_TAG 0xa003
64 {
"GPSVersionID", 0x00},
65 {
"GPSLatitudeRef", 0x01},
66 {
"GPSLatitude", 0x02},
67 {
"GPSLongitudeRef", 0x03},
68 {
"GPSLongitude", 0x04},
69 {
"GPSAltitudeRef", 0x05},
70 {
"GPSAltitude", 0x06},
71 {
"GPSTimeStamp", 0x07},
72 {
"GPSSatellites", 0x08},
74 {
"GPSMeasureMode", 0x0A},
76 {
"GPSSpeedRef", 0x0C},
78 {
"GPSTrackRef", 0x0E},
80 {
"GPSImgDirectionRef", 0x10},
81 {
"GPSImgDirection", 0x11},
82 {
"GPSMapDatum", 0x12},
83 {
"GPSDestLatitudeRef", 0x13},
84 {
"GPSDestLatitude", 0x14},
85 {
"GPSDestLongitudeRef", 0x15},
86 {
"GPSDestLongitude", 0x16},
87 {
"GPSDestBearingRef", 0x17},
88 {
"GPSDestBearing", 0x18},
89 {
"GPSDestDistanceRef", 0x19},
90 {
"GPSDestDistance", 0x1A},
91 {
"GPSProcessingMethod", 0x1B},
92 {
"GPSAreaInformation", 0x1C},
93 {
"GPSDateStamp", 0x1D},
94 {
"GPSDifferential", 0x1E},
95 {
"ImageWidth", 0x100},
96 {
"ImageLength", 0x101},
97 {
"BitsPerSample", 0x102},
98 {
"Compression", 0x103},
99 {
"PhotometricInterpretation", 0x106},
100 {
"Orientation", 0x112},
101 {
"SamplesPerPixel", 0x115},
102 {
"PlanarConfiguration", 0x11C},
103 {
"YCbCrSubSampling", 0x212},
104 {
"YCbCrPositioning", 0x213},
105 {
"XResolution", 0x11A},
106 {
"YResolution", 0x11B},
107 {
"ResolutionUnit", 0x128},
108 {
"StripOffsets", 0x111},
109 {
"RowsPerStrip", 0x116},
110 {
"StripByteCounts", 0x117},
111 {
"JPEGInterchangeFormat", 0x201},
112 {
"JPEGInterchangeFormatLength",0x202},
113 {
"TransferFunction", 0x12D},
114 {
"WhitePoint", 0x13E},
115 {
"PrimaryChromaticities", 0x13F},
116 {
"YCbCrCoefficients", 0x211},
117 {
"ReferenceBlackWhite", 0x214},
119 {
"ImageDescription", 0x10E},
124 {
"Copyright", 0x8298},
125 {
"ExifVersion", 0x9000},
126 {
"FlashpixVersion", 0xA000},
127 {
"ColorSpace", 0xA001},
128 {
"ComponentsConfiguration", 0x9101},
129 {
"CompressedBitsPerPixel", 0x9102},
130 {
"PixelXDimension", 0xA002},
131 {
"PixelYDimension", 0xA003},
132 {
"MakerNote", 0x927C},
133 {
"UserComment", 0x9286},
134 {
"RelatedSoundFile", 0xA004},
135 {
"DateTimeOriginal", 0x9003},
136 {
"DateTimeDigitized", 0x9004},
137 {
"SubSecTime", 0x9290},
138 {
"SubSecTimeOriginal", 0x9291},
139 {
"SubSecTimeDigitized", 0x9292},
140 {
"ImageUniqueID", 0xA420},
141 {
"ExposureTime", 0x829A},
143 {
"ExposureProgram", 0x8822},
144 {
"SpectralSensitivity", 0x8824},
145 {
"ISOSpeedRatings", 0x8827},
147 {
"ShutterSpeedValue", 0x9201},
148 {
"ApertureValue", 0x9202},
149 {
"BrightnessValue", 0x9203},
150 {
"ExposureBiasValue", 0x9204},
151 {
"MaxApertureValue", 0x9205},
152 {
"SubjectDistance", 0x9206},
153 {
"MeteringMode", 0x9207},
154 {
"LightSource", 0x9208},
156 {
"FocalLength", 0x920A},
157 {
"SubjectArea", 0x9214},
158 {
"FlashEnergy", 0xA20B},
159 {
"SpatialFrequencyResponse", 0xA20C},
160 {
"FocalPlaneXResolution", 0xA20E},
161 {
"FocalPlaneYResolution", 0xA20F},
162 {
"FocalPlaneResolutionUnit", 0xA210},
163 {
"SubjectLocation", 0xA214},
164 {
"ExposureIndex", 0xA215},
165 {
"SensingMethod", 0xA217},
166 {
"FileSource", 0xA300},
167 {
"SceneType", 0xA301},
168 {
"CFAPattern", 0xA302},
169 {
"CustomRendered", 0xA401},
170 {
"ExposureMode", 0xA402},
171 {
"WhiteBalance", 0xA403},
172 {
"DigitalZoomRatio", 0xA404},
173 {
"FocalLengthIn35mmFilm", 0xA405},
174 {
"SceneCaptureType", 0xA406},
175 {
"GainControl", 0xA407},
176 {
"Contrast", 0xA408},
177 {
"Saturation", 0xA409},
178 {
"Sharpness", 0xA40A},
179 {
"DeviceSettingDescription", 0xA40B},
180 {
"SubjectDistanceRange", 0xA40C},
183 {
"RelatedImageFileFormat", 0x1000},
184 {
"RelatedImageWidth", 0x1001},
185 {
"RelatedImageLength", 0x1002},
188 {
"PrintImageMatching", 0xC4A5},
193 {
"InteropIFD", 0xA005},
194 {
"GlobalParametersIFD", 0x0190},
195 {
"ProfileIFD", 0xc6f5},
259 le ? bytestream2_put_le16(pb,
value) : bytestream2_put_be16(pb,
value);
264 le ? bytestream2_put_le32(pb,
value) : bytestream2_put_be32(pb,
value);
269 le ? bytestream2_put_le64(pb,
value) : bytestream2_put_be64(pb,
value);
277 switch (
entry->type) {
308 if (!
entry->value.ptr)
310 switch (
entry->type) {
312 for (
size_t i = 0;
i <
entry->count;
i++)
316 for (
size_t i = 0;
i <
entry->count;
i++)
320 for (
size_t i = 0;
i <
entry->count;
i++)
324 for (
size_t i = 0;
i <
entry->count;
i++)
328 for (
size_t i = 0;
i <
entry->count;
i++)
332 for (
size_t i = 0;
i <
entry->count;
i++) {
339 for (
size_t i = 0;
i <
entry->count;
i++) {
367 switch (
entry->type) {
369 for (
size_t i = 0;
i <
entry->count;
i++)
373 for (
size_t i = 0;
i <
entry->count;
i++)
377 for (
size_t i = 0;
i <
entry->count;
i++)
381 for (
size_t i = 0;
i <
entry->count;
i++)
385 for (
size_t i = 0;
i <
entry->count;
i++) {
386 const av_alias64
a = { .f64 =
entry->value.dbl[
i] };
391 for (
size_t i = 0;
i <
entry->count;
i++) {
392 const av_alias32
a = { .f32 =
entry->value.dbl[
i] };
398 for (
size_t i = 0;
i <
entry->count;
i++) {
418static const uint8_t
foveon_header[] = {
'F',
'O',
'V',
'E',
'O',
'N', 0, 0, };
422static const uint8_t
olympus2_header[] = {
'O',
'L',
'Y',
'M',
'P',
'U',
'S', 0,
'I',
'I', };
423static const uint8_t
panasonic_header[] = {
'P',
'a',
'n',
'a',
's',
'o',
'n',
'i',
'c', 0, 0, 0, };
424static const uint8_t
sigma_header[] = {
'S',
'I',
'G',
'M',
'A', 0, 0, 0, };
425static const uint8_t
sony_header[] = {
'S',
'O',
'N',
'Y',
' ',
'D',
'S',
'C',
' ', 0, 0, 0, };
433#define MAKERNOTE_STRUCT(h, r) { \
435 .header_size = sizeof((h)), \
483 int ret = 0, makernote_offset = -1,
tell, is_ifd, count;
498 av_log(logctx,
AV_LOG_DEBUG,
"TIFF Tag: id: 0x%04x, type: %d, count: %u, offset: %d, "
499 "payload: %" PRIu32
"\n",
entry->id,
type, count,
tell, payload);
520 if (makernote_offset < 0)
527 entry->ifd_offset = makernote_offset > 0 ? makernote_offset : 0;
528 if (
entry->ifd_offset) {
530 if (!
entry->ifd_lead)
549 entry->count = count;
564 size_t required_size;
572 "not enough bytes remaining in EXIF buffer: 2 required\n");
580 "not enough bytes remaining in EXIF buffer. entries: %" PRIu32
"\n", entries);
584 if (entries > 4096) {
587 "too many entries: %" PRIu32
"\n", entries);
592 ifd->
count = entries;
615 memset(ifd->
entries, 0, required_size);
617 for (uint32_t
i = 0;
i < entries;
i++) {
668 for (
size_t i = 0;
i < ifd->
count;
i++) {
682 for (
size_t i = 0;
i < ifd->
count;
i++) {
688 total_size +=
BASE_TAG_SIZE + (payload_size > 4 ? payload_size : 0);
701 for (
size_t i = 0;
i < ifd->
count;
i++) {
703 av_log(logctx,
AV_LOG_DEBUG,
"writing TIFF entry: id: 0x%04" PRIx16
", type: %d, count: %"
704 PRIu32
", offset: %d, offset value: %d\n",
720 if (
entry->ifd_offset)
729 if (payload_size > 4) {
756 size_t size, headsize = 8;
758 int ret = 0, off = 0, next;
770 switch (header_mode) {
810 uint16_t extra_tag = 0xFFFCu -
i;
827 extra_ifds[extras++] = *cloned;
848 for (
int i = 0;
i < extras;
i++) {
890 switch (header_mode) {
943 for (
int extra_tag = 0xFFFCu; extra_tag > 0xFFECu; extra_tag--) {
963#define COLUMN_SEP(i, c) ((i) ? ((i) % (c) ? ", " : "\n") : "")
975 for (uint16_t
i = 0;
i < ifd->
count;
i++) {
989 switch (
entry->type) {
997 for (uint32_t j = 0; j <
entry->count; j++)
1002 for (uint32_t j = 0; j <
entry->count; j++)
1007 for (uint32_t j = 0; j <
entry->count; j++)
1012 for (uint32_t j = 0; j <
entry->count; j++)
1020 for (uint32_t j = 0; j <
entry->count; j++)
1024 for (uint32_t j = 0; j <
entry->count; j++)
1058#define EXIF_COPY(fname, srcname) do { \
1060 if (av_size_mult(src->count, sizeof(*(fname)), &sz) < 0) { \
1061 ret = AVERROR(ENOMEM); \
1064 (fname) = av_memdup((srcname), sz); \
1066 ret = AVERROR(ENOMEM); \
1075 memset(
dst, 0,
sizeof(*
dst));
1081 dst->ifd_offset =
src->ifd_offset;
1082 if (
src->ifd_lead) {
1084 if (!
dst->ifd_lead) {
1099 dst->value.ifd = *cloned;
1128 if (!
dst->value.str) {
1143 memset(
dst, 0,
sizeof(*
dst));
1155 for (
size_t i = 0;
i < ifd->
count;
i++) {
1164 return ret < 0 ? ret : ret +
offset;
1179 uint32_t count,
const uint8_t *ifd_lead, uint32_t ifd_offset,
const void *
value)
1187 || ifd_lead && !ifd_offset || !ifd_lead && ifd_offset
1199 size_t required_size;
1213 src.ifd_lead = (uint8_t *) ifd_lead;
1214 src.ifd_offset = ifd_offset;
1243 for (
size_t i = 0;
i < ifd->
count;
i++) {
1285 size_t required_size;
1293 for (
size_t i = 0;
i < ret->
count;
i++) {
1310 {1, 8, 3, 6}, {4, 7, 2, 5},
1321 int rot = (int)(rotation + 0.5);
1322 rot = (((rot % 360) + 360) % 360) / 90;
1328 switch (orientation) {
1373 uint64_t orientation = 1;
1374 uint64_t
w =
frame->width;
1375 uint64_t
h =
frame->height;
1386 if (orientation != 1)
1387 av_log(logctx,
AV_LOG_DEBUG,
"matrix contains nontrivial EXIF orientation: %" PRIu64
"\n", orientation);
1389 for (
size_t i = 0;
i < ifd->
count;
i++) {
1405 for (
size_t j = 0; j < exif->
count; j++) {
1419 if (or && or->
value.
uint[0] != orientation) {
1435 if (
ph &&
ph->value.uint[0] !=
h) {
1437 ph->value.uint[0] =
h;
1439 if (!or && orientation != 1) {
1457 if (!pw &&
w &&
w <= 0xFFFFu || !
ph &&
h &&
h <= 0xFFFFu) {
1464 if (exif_found > 0) {
1475 if (!pw &&
w &&
w <= 0xFFFFu) {
1480 if (!
ph &&
h &&
h <= 0xFFFFu) {
1501 if (!buffer_ptr || *buffer_ptr)
1536 }
else if (sd_exif) {
1546 return !!(rewrite || sd_exif);
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
#define av_assert0(cond)
assert() equivalent, that is always enabled.
static int BS_FUNC tell(const BSCTX *bc)
Return number of bits already read.
void av_bprintf(AVBPrint *buf, const char *fmt,...)
void av_bprint_init(AVBPrint *buf, unsigned size_init, unsigned size_max)
#define AV_BPRINT_SIZE_UNLIMITED
static av_always_inline int bytestream2_tell_p(const PutByteContext *p)
static av_always_inline unsigned int bytestream2_get_buffer(GetByteContext *g, uint8_t *dst, unsigned int size)
static av_always_inline void bytestream2_init_writer(PutByteContext *p, uint8_t *buf, int buf_size)
static av_always_inline int bytestream2_get_bytes_left(const GetByteContext *g)
static av_always_inline void bytestream2_init(GetByteContext *g, const uint8_t *buf, int buf_size)
static av_always_inline int bytestream2_seek(GetByteContext *g, int offset, int whence)
static av_always_inline int bytestream2_seek_p(PutByteContext *p, int offset, int whence)
static av_always_inline int bytestream2_tell(const GetByteContext *g)
static av_always_inline unsigned int bytestream2_put_buffer(PutByteContext *p, const uint8_t *src, unsigned int size)
static int FUNC metadata(CodedBitstreamContext *ctx, RWContext *rw, APVRawMetadata *current)
#define flags(name, subs,...)
#define i(width, name, range_min, range_max)
static int FUNC ph(CodedBitstreamContext *ctx, RWContext *rw, H266RawPH *current)
static const uint8_t sigma_header[]
int av_exif_get_entry(void *logctx, AVExifMetadata *ifd, uint16_t id, int flags, AVExifEntry **value)
Get an entry with the tagged ID from the EXIF metadata struct.
static void exif_write_values(PutByteContext *pb, int le, const AVExifEntry *entry)
static const struct exif_makernote_data makernote_data[]
static const uint8_t panasonic_header[]
static void tput16(PutByteContext *pb, const int le, const uint16_t value)
static void tput64(PutByteContext *pb, const int le, const uint64_t value)
static const uint8_t olympus2_header[]
static int exif_get_entry(void *logctx, AVExifMetadata *ifd, uint16_t id, int depth, AVExifEntry **value)
static int exif_remove_entry(void *logctx, AVExifMetadata *ifd, uint16_t id, int depth)
static int exif_clone_entry(AVExifEntry *dst, const AVExifEntry *src)
static int exif_decode_tag(void *logctx, GetByteContext *gb, int le, int depth, AVExifEntry *entry)
static const struct exif_tag tag_list[]
static void exif_free_entry(AVExifEntry *entry)
static const uint8_t foveon_header[]
int av_exif_set_entry(void *logctx, AVExifMetadata *ifd, uint16_t id, enum AVTiffDataType type, uint32_t count, const uint8_t *ifd_lead, uint32_t ifd_offset, const void *value)
Add an entry to the provided EXIF metadata struct.
int av_exif_parse_buffer(void *logctx, const uint8_t *buf, size_t size, AVExifMetadata *ifd, enum AVExifHeaderMode header_mode)
Decodes the EXIF data provided in the buffer and writes it into the struct *ifd.
static size_t exif_get_ifd_size(const AVExifMetadata *ifd)
int av_exif_ifd_to_dict(void *logctx, const AVExifMetadata *ifd, AVDictionary **metadata)
Recursively reads all tags from the IFD and stores them in the provided metadata dictionary.
void av_exif_free(AVExifMetadata *ifd)
Frees all resources associated with the given EXIF metadata struct.
static const uint8_t aoc_header[]
int av_exif_matrix_to_orientation(const int32_t *matrix)
Convert a display matrix used by AV_FRAME_DATA_DISPLAYMATRIX into an orientation constant used by EXI...
static const uint8_t casio_header[]
static const uint8_t fuji_header[]
const char * av_exif_get_tag_name(uint16_t id)
Retrieves the tag name associated with the provided tag ID.
#define MAKERNOTE_STRUCT(h, r)
int av_exif_orientation_to_matrix(int32_t *matrix, int orientation)
Convert an orientation constant used by EXIF's orientation tag into a display matrix used by AV_FRAME...
static const uint8_t olympus1_header[]
int ff_exif_get_buffer(void *logctx, const AVFrame *frame, AVBufferRef **buffer_ptr, enum AVExifHeaderMode header_mode)
Gets all relevant side data, collects it into an IFD, and writes it into the corresponding buffer poi...
AVExifMetadata * av_exif_clone_ifd(const AVExifMetadata *ifd)
Allocates a duplicate of the provided EXIF metadata struct.
static const int rotation_lut[2][4]
static int exif_ifd_to_dict(void *logctx, const char *prefix, const AVExifMetadata *ifd, AVDictionary **metadata)
static int exif_read_values(void *logctx, GetByteContext *gb, int le, AVExifEntry *entry)
#define EXIF_COPY(fname, srcname)
static int exif_parse_ifd_list(void *logctx, GetByteContext *gb, int le, int depth, AVExifMetadata *ifd, int guess)
int ff_exif_sanitize_ifd(void *logctx, const AVFrame *frame, AVExifMetadata *ifd)
Compares values in the IFD with data in the provided AVFrame and sets the values in that IFD to match...
int av_exif_write(void *logctx, const AVExifMetadata *ifd, AVBufferRef **buffer, enum AVExifHeaderMode header_mode)
Allocates a buffer using av_malloc of an appropriate size and writes the EXIF data represented by ifd...
#define EXIF_TAG_NAME_LENGTH
static int exif_write_ifd(void *logctx, PutByteContext *pb, int le, int depth, const AVExifMetadata *ifd)
int32_t av_exif_get_tag_id(const char *name)
Retrieves the tag ID associated with the provided tag string name.
static void tput32(PutByteContext *pb, const int le, const uint32_t value)
int av_exif_remove_entry(void *logctx, AVExifMetadata *ifd, uint16_t id, int flags)
Remove an entry from the provided EXIF metadata struct.
static const uint8_t sony_header[]
static const size_t exif_sizes[]
static const uint8_t nikon_header[]
static int exif_get_makernote_offset(GetByteContext *gb)
AVTiffDataType
Data type identifiers for TIFF tags.
#define AV_EXIF_FLAG_RECURSIVE
Also check subdirectories.
@ AV_EXIF_EXIF00
The first six bytes contain "Exif\0\0", then it's AV_EXIF_TIFF_HEADER.
@ AV_EXIF_TIFF_HEADER
The TIFF header starts with 0x49492a00, or 0x4d4d002a.
@ AV_EXIF_ASSUME_BE
skip the TIFF header, assume big endian
@ AV_EXIF_ASSUME_LE
skip the TIFF header, assume little endian
@ AV_EXIF_T_OFF
The first four bytes point to the actual start, then it's AV_EXIF_TIFF_HEADER.
EXIF metadata parser - internal functions.
static int av_bprint_is_complete(const AVBPrint *buf)
Test if the print buffer is complete (not truncated).
int av_bprint_finalize(AVBPrint *buf, char **ret_str)
Finalize a print buffer.
void av_buffer_unref(AVBufferRef **buf)
Free a given reference and automatically free the buffer if there are no more references to it.
int av_buffer_realloc(AVBufferRef **pbuf, size_t size)
Reallocate a given buffer.
AVBufferRef * av_buffer_ref(const AVBufferRef *buf)
Create a new reference to an AVBuffer.
#define AV_DICT_DONT_STRDUP_VAL
Take ownership of a value that's been allocated with av_malloc() or another memory allocation functio...
int av_dict_set(AVDictionary **pm, const char *key, const char *value, int flags)
Set the given entry in *pm, overwriting an existing entry.
#define AV_DICT_DONT_STRDUP_KEY
Take ownership of a key that's been allocated with av_malloc() or another memory allocation function.
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
#define av_err2str(errnum)
Convenience macro, the return value should be used only directly in function arguments but never stan...
AVFrameSideData * av_frame_get_side_data(const AVFrame *frame, enum AVFrameSideDataType type)
@ AV_FRAME_DATA_EXIF
Exchangeable image file format metadata.
@ AV_FRAME_DATA_DISPLAYMATRIX
This side data contains a 3x3 transformation matrix describing an affine transformation that needs to...
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
#define AV_LOG_WARNING
Something somehow does not look correct.
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
static AVRational av_make_q(int num, int den)
Create an AVRational.
void av_fast_mallocz(void *ptr, unsigned int *size, size_t min_size)
Allocate and clear a buffer, reusing the given one if large enough.
void * av_fast_realloc(void *ptr, unsigned int *size, size_t min_size)
Reallocate the given buffer if it is not large enough, otherwise do nothing.
void * av_memdup(const void *p, size_t size)
Duplicate a buffer with av_malloc().
int av_size_mult(size_t a, size_t b, size_t *r)
Multiply two size_t values checking for overflow.
void av_display_rotation_set(int32_t matrix[9], double angle)
Initialize a transformation matrix describing a pure clockwise rotation by the specified angle (in de...
double av_display_rotation_get(const int32_t matrix[9])
Extract the rotation component of the transformation matrix.
void av_display_matrix_flip(int32_t matrix[9], int hflip, int vflip)
Flip the input matrix horizontally and/or vertically.
Macro definitions for various function/variable attributes.
#define MKTAG(a, b, c, d)
void * av_calloc(size_t nmemb, size_t size)
Memory handling functions.
#define FF_ARRAY_ELEMS(a)
A reference to a data buffer.
uint8_t * data
The data buffer.
size_t size
Size of data in bytes.
union AVExifEntry::@325220332140161067313112036135003363017341144014 value
Structure to hold side data for an AVFrame.
This structure describes decoded (raw) audio or video data.
const char name[EXIF_TAG_NAME_LENGTH]
int ff_tis_ifd(unsigned tag)
Returns a value > 0 if the tag is a known IFD-tag.
int ff_tdecode_header(GetByteContext *gb, int *le, int *ifd_offset)
Decodes a TIFF header from the input bytestream and sets the endianness in *le and the offset to the ...
unsigned ff_tget_short(GetByteContext *gb, int le)
Reads a short from the bytestream using given endianness.
double ff_tget_double(GetByteContext *gb, int le)
Reads a double from the bytestream using given endianness.
unsigned ff_tget_long(GetByteContext *gb, int le)
Reads a long from the bytestream using given endianness.