FFmpeg
Loading...
Searching...
No Matches
exif.c
Go to the documentation of this file.
1/*
2 * EXIF metadata parser
3 * Copyright (c) 2013 Thilo Borgmann <thilo.borgmann _at_ mail.de>
4 * Copyright (c) 2024-2025 Leo Izen <leo.izen@gmail.com>
5 *
6 * This file is part of FFmpeg.
7 *
8 * FFmpeg is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
12 *
13 * FFmpeg is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with FFmpeg; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 */
22
23/**
24 * @file
25 * EXIF metadata parser
26 * @author Thilo Borgmann <thilo.borgmann _at_ mail.de>
27 * @author Leo Izen <leo.izen@gmail.com>
28 */
29
30#include <inttypes.h>
31
33#include "libavutil/avconfig.h"
34#include "libavutil/bprint.h"
35#include "libavutil/display.h"
37#include "libavutil/mem.h"
38
39#include "bytestream.h"
40#include "exif_internal.h"
41#include "tiff_common.h"
42
43#define EXIF_II_LONG 0x49492a00
44#define EXIF_MM_LONG 0x4d4d002a
45
46#define BASE_TAG_SIZE 12
47#define IFD_EXTRA_SIZE 6
48
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
57
58struct exif_tag {
60 uint16_t id;
61};
62
63static const struct exif_tag tag_list[] = { // JEITA CP-3451 EXIF specification:
64 {"GPSVersionID", 0x00}, // <- Table 12 GPS Attribute Information
65 {"GPSLatitudeRef", 0x01},
66 {"GPSLatitude", 0x02},
67 {"GPSLongitudeRef", 0x03},
68 {"GPSLongitude", 0x04},
69 {"GPSAltitudeRef", 0x05},
70 {"GPSAltitude", 0x06},
71 {"GPSTimeStamp", 0x07},
72 {"GPSSatellites", 0x08},
73 {"GPSStatus", 0x09},
74 {"GPSMeasureMode", 0x0A},
75 {"GPSDOP", 0x0B},
76 {"GPSSpeedRef", 0x0C},
77 {"GPSSpeed", 0x0D},
78 {"GPSTrackRef", 0x0E},
79 {"GPSTrack", 0x0F},
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}, // <- Table 3 TIFF Rev. 6.0 Attribute Information Used in Exif
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},
118 {"DateTime", 0x132},
119 {"ImageDescription", 0x10E},
120 {"Make", 0x10F},
121 {"Model", 0x110},
122 {"Software", 0x131},
123 {"Artist", 0x13B},
124 {"Copyright", 0x8298},
125 {"InterColorProfile", 0x8773},
126 {"ExifVersion", 0x9000}, // <- Table 4 Exif IFD Attribute Information (1)
127 {"FlashpixVersion", 0xA000},
128 {"ColorSpace", 0xA001},
129 {"ComponentsConfiguration", 0x9101},
130 {"CompressedBitsPerPixel", 0x9102},
131 {"PixelXDimension", 0xA002},
132 {"PixelYDimension", 0xA003},
133 {"MakerNote", 0x927C},
134 {"UserComment", 0x9286},
135 {"RelatedSoundFile", 0xA004},
136 {"DateTimeOriginal", 0x9003},
137 {"DateTimeDigitized", 0x9004},
138 {"SubSecTime", 0x9290},
139 {"SubSecTimeOriginal", 0x9291},
140 {"SubSecTimeDigitized", 0x9292},
141 {"ImageUniqueID", 0xA420},
142 {"ExposureTime", 0x829A}, // <- Table 5 Exif IFD Attribute Information (2)
143 {"FNumber", 0x829D},
144 {"ExposureProgram", 0x8822},
145 {"SpectralSensitivity", 0x8824},
146 {"ISOSpeedRatings", 0x8827},
147 {"OECF", 0x8828},
148 {"ShutterSpeedValue", 0x9201},
149 {"ApertureValue", 0x9202},
150 {"BrightnessValue", 0x9203},
151 {"ExposureBiasValue", 0x9204},
152 {"MaxApertureValue", 0x9205},
153 {"SubjectDistance", 0x9206},
154 {"MeteringMode", 0x9207},
155 {"LightSource", 0x9208},
156 {"Flash", 0x9209},
157 {"FocalLength", 0x920A},
158 {"SubjectArea", 0x9214},
159 {"FlashEnergy", 0xA20B},
160 {"SpatialFrequencyResponse", 0xA20C},
161 {"FocalPlaneXResolution", 0xA20E},
162 {"FocalPlaneYResolution", 0xA20F},
163 {"FocalPlaneResolutionUnit", 0xA210},
164 {"SubjectLocation", 0xA214},
165 {"ExposureIndex", 0xA215},
166 {"SensingMethod", 0xA217},
167 {"FileSource", 0xA300},
168 {"SceneType", 0xA301},
169 {"CFAPattern", 0xA302},
170 {"CustomRendered", 0xA401},
171 {"ExposureMode", 0xA402},
172 {"WhiteBalance", 0xA403},
173 {"DigitalZoomRatio", 0xA404},
174 {"FocalLengthIn35mmFilm", 0xA405},
175 {"SceneCaptureType", 0xA406},
176 {"GainControl", 0xA407},
177 {"Contrast", 0xA408},
178 {"Saturation", 0xA409},
179 {"Sharpness", 0xA40A},
180 {"DeviceSettingDescription", 0xA40B},
181 {"SubjectDistanceRange", 0xA40C},
182
183 /* InteropIFD tags */
184 {"RelatedImageFileFormat", 0x1000},
185 {"RelatedImageWidth", 0x1001},
186 {"RelatedImageLength", 0x1002},
187
188 /* private EXIF tags */
189 {"PrintImageMatching", 0xC4A5}, // <- undocumented meaning
190
191 /* IFD tags */
192 {"ExifIFD", 0x8769}, // <- An IFD pointing to standard Exif metadata
193 {"GPSInfo", 0x8825}, // <- An IFD pointing to GPS Exif Metadata
194 {"InteropIFD", 0xA005}, // <- Table 13 Interoperability IFD Attribute Information
195 {"GlobalParametersIFD", 0x0190},
196 {"ProfileIFD", 0xc6f5},
197
198 /* Extra FFmpeg tags */
199 { "IFD1", 0xFFFC},
200 { "IFD2", 0xFFFB},
201 { "IFD3", 0xFFFA},
202 { "IFD4", 0xFFF9},
203 { "IFD5", 0xFFF8},
204 { "IFD6", 0xFFF7},
205 { "IFD7", 0xFFF6},
206 { "IFD8", 0xFFF5},
207 { "IFD9", 0xFFF4},
208 { "IFD10", 0xFFF3},
209 { "IFD11", 0xFFF2},
210 { "IFD12", 0xFFF1},
211 { "IFD13", 0xFFF0},
212 { "IFD14", 0xFFEF},
213 { "IFD15", 0xFFEE},
214 { "IFD16", 0xFFED},
215};
216
217/* same as type_sizes but with string == 1 */
218static const size_t exif_sizes[] = {
219 [0] = 0,
220 [AV_TIFF_BYTE] = 1,
221 [AV_TIFF_STRING] = 1,
222 [AV_TIFF_SHORT] = 2,
223 [AV_TIFF_LONG] = 4,
224 [AV_TIFF_RATIONAL] = 8,
225 [AV_TIFF_SBYTE] = 1,
226 [AV_TIFF_UNDEFINED] = 1,
227 [AV_TIFF_SSHORT] = 2,
228 [AV_TIFF_SLONG] = 4,
229 [AV_TIFF_SRATIONAL] = 8,
230 [AV_TIFF_FLOAT] = 4,
231 [AV_TIFF_DOUBLE] = 8,
232 [AV_TIFF_IFD] = 4,
233};
234
235const char *av_exif_get_tag_name(uint16_t id)
236{
237 for (size_t i = 0; i < FF_ARRAY_ELEMS(tag_list); i++) {
238 if (tag_list[i].id == id)
239 return tag_list[i].name;
240 }
241
242 return NULL;
243}
244
246{
247 if (!name)
248 return -1;
249
250 for (size_t i = 0; i < FF_ARRAY_ELEMS(tag_list); i++) {
251 if (!strcmp(tag_list[i].name, name))
252 return tag_list[i].id;
253 }
254
255 return -1;
256}
257
258static inline void tput16(PutByteContext *pb, const int le, const uint16_t value)
259{
260 le ? bytestream2_put_le16(pb, value) : bytestream2_put_be16(pb, value);
261}
262
263static inline void tput32(PutByteContext *pb, const int le, const uint32_t value)
264{
265 le ? bytestream2_put_le32(pb, value) : bytestream2_put_be32(pb, value);
266}
267
268static inline void tput64(PutByteContext *pb, const int le, const uint64_t value)
269{
270 le ? bytestream2_put_le64(pb, value) : bytestream2_put_be64(pb, value);
271}
272
273static int exif_read_values(void *logctx, GetByteContext *gb, int le, AVExifEntry *entry)
274{
275 if (exif_sizes[entry->type] * entry->count > bytestream2_get_bytes_left(gb))
276 return AVERROR_INVALIDDATA;
277
278 switch (entry->type) {
279 case AV_TIFF_SHORT:
280 case AV_TIFF_LONG:
281 entry->value.uint = av_calloc(entry->count, sizeof(*entry->value.uint));
282 break;
283 case AV_TIFF_SSHORT:
284 case AV_TIFF_SLONG:
285 entry->value.sint = av_calloc(entry->count, sizeof(*entry->value.sint));
286 break;
287 case AV_TIFF_DOUBLE:
288 case AV_TIFF_FLOAT:
289 entry->value.dbl = av_calloc(entry->count, sizeof(*entry->value.dbl));
290 break;
291 case AV_TIFF_RATIONAL:
293 entry->value.rat = av_calloc(entry->count, sizeof(*entry->value.rat));
294 break;
296 case AV_TIFF_BYTE:
297 entry->value.ubytes = av_mallocz(entry->count);
298 break;
299 case AV_TIFF_SBYTE:
300 entry->value.sbytes = av_mallocz(entry->count);
301 break;
302 case AV_TIFF_STRING:
303 entry->value.str = av_mallocz(entry->count + 1);
304 break;
305 case AV_TIFF_IFD:
306 av_log(logctx, AV_LOG_WARNING, "Bad IFD type for non-IFD tag\n");
307 return AVERROR_INVALIDDATA;
308 }
309 if (!entry->value.ptr)
310 return AVERROR(ENOMEM);
311 switch (entry->type) {
312 case AV_TIFF_SHORT:
313 for (size_t i = 0; i < entry->count; i++)
314 entry->value.uint[i] = ff_tget_short(gb, le);
315 break;
316 case AV_TIFF_LONG:
317 for (size_t i = 0; i < entry->count; i++)
318 entry->value.uint[i] = ff_tget_long(gb, le);
319 break;
320 case AV_TIFF_SSHORT:
321 for (size_t i = 0; i < entry->count; i++)
322 entry->value.sint[i] = (int16_t) ff_tget_short(gb, le);
323 break;
324 case AV_TIFF_SLONG:
325 for (size_t i = 0; i < entry->count; i++)
326 entry->value.sint[i] = (int32_t) ff_tget_long(gb, le);
327 break;
328 case AV_TIFF_DOUBLE:
329 for (size_t i = 0; i < entry->count; i++)
330 entry->value.dbl[i] = ff_tget_double(gb, le);
331 break;
332 case AV_TIFF_FLOAT:
333 for (size_t i = 0; i < entry->count; i++) {
334 av_alias32 alias = { .u32 = ff_tget_long(gb, le) };
335 entry->value.dbl[i] = alias.f32;
336 }
337 break;
338 case AV_TIFF_RATIONAL:
340 for (size_t i = 0; i < entry->count; i++) {
341 int32_t num = ff_tget_long(gb, le);
342 int32_t den = ff_tget_long(gb, le);
343 entry->value.rat[i] = av_make_q(num, den);
344 }
345 break;
347 case AV_TIFF_BYTE:
348 /* these three fields are aliased to entry->value.ptr via a union */
349 /* and entry->value.ptr will always be nonzero here */
350 av_assert0(entry->value.ubytes);
351 bytestream2_get_buffer(gb, entry->value.ubytes, entry->count);
352 break;
353 case AV_TIFF_SBYTE:
354 av_assert0(entry->value.sbytes);
355 bytestream2_get_buffer(gb, entry->value.sbytes, entry->count);
356 break;
357 case AV_TIFF_STRING:
358 av_assert0(entry->value.str);
359 bytestream2_get_buffer(gb, entry->value.str, entry->count);
360 break;
361 }
362
363 return 0;
364}
365
366static void exif_write_values(PutByteContext *pb, int le, const AVExifEntry *entry)
367{
368 switch (entry->type) {
369 case AV_TIFF_SHORT:
370 for (size_t i = 0; i < entry->count; i++)
371 tput16(pb, le, entry->value.uint[i]);
372 break;
373 case AV_TIFF_LONG:
374 for (size_t i = 0; i < entry->count; i++)
375 tput32(pb, le, entry->value.uint[i]);
376 break;
377 case AV_TIFF_SSHORT:
378 for (size_t i = 0; i < entry->count; i++)
379 tput16(pb, le, entry->value.sint[i]);
380 break;
381 case AV_TIFF_SLONG:
382 for (size_t i = 0; i < entry->count; i++)
383 tput32(pb, le, entry->value.sint[i]);
384 break;
385 case AV_TIFF_DOUBLE:
386 for (size_t i = 0; i < entry->count; i++) {
387 const av_alias64 a = { .f64 = entry->value.dbl[i] };
388 tput64(pb, le, a.u64);
389 }
390 break;
391 case AV_TIFF_FLOAT:
392 for (size_t i = 0; i < entry->count; i++) {
393 const av_alias32 a = { .f32 = entry->value.dbl[i] };
394 tput32(pb, le, a.u32);
395 }
396 break;
397 case AV_TIFF_RATIONAL:
399 for (size_t i = 0; i < entry->count; i++) {
400 tput32(pb, le, entry->value.rat[i].num);
401 tput32(pb, le, entry->value.rat[i].den);
402 }
403 break;
405 case AV_TIFF_BYTE:
406 bytestream2_put_buffer(pb, entry->value.ubytes, entry->count);
407 break;
408 case AV_TIFF_SBYTE:
409 bytestream2_put_buffer(pb, entry->value.sbytes, entry->count);
410 break;
411 case AV_TIFF_STRING:
412 bytestream2_put_buffer(pb, entry->value.str, entry->count);
413 break;
414 }
415}
416
417static const uint8_t aoc_header[] = { 'A', 'O', 'C', 0, };
418static const uint8_t casio_header[] = { 'Q', 'V', 'C', 0, 0, 0, };
419static const uint8_t foveon_header[] = { 'F', 'O', 'V', 'E', 'O', 'N', 0, 0, };
420static const uint8_t fuji_header[] = { 'F', 'U', 'J', 'I', };
421static const uint8_t nikon_header[] = { 'N', 'i', 'k', 'o', 'n', 0, };
422static const uint8_t olympus1_header[] = { 'O', 'L', 'Y', 'M', 'P', 0, };
423static const uint8_t olympus2_header[] = { 'O', 'L', 'Y', 'M', 'P', 'U', 'S', 0, 'I', 'I', };
424static const uint8_t panasonic_header[] = { 'P', 'a', 'n', 'a', 's', 'o', 'n', 'i', 'c', 0, 0, 0, };
425static const uint8_t sigma_header[] = { 'S', 'I', 'G', 'M', 'A', 0, 0, 0, };
426static const uint8_t sony_header[] = { 'S', 'O', 'N', 'Y', ' ', 'D', 'S', 'C', ' ', 0, 0, 0, };
427
429 const uint8_t *header;
432};
433
434#define MAKERNOTE_STRUCT(h, r) { \
435 .header = (h), \
436 .header_size = sizeof((h)), \
437 .result = (r), \
438}
439
451
452/*
453 * derived from Exiv2 MakerNote's article
454 * https://exiv2.org/makernote.html or archived at
455 * https://web.archive.org/web/20250311155857/https://exiv2.org/makernote.html
456 */
458{
460 return -1;
461
462 for (int i = 0; i < FF_ARRAY_ELEMS(makernote_data); i++) {
463 if (!memcmp(gb->buffer, makernote_data[i].header, makernote_data[i].header_size))
464 return makernote_data[i].result;
465 }
466
467 if (!memcmp(gb->buffer, nikon_header, sizeof(nikon_header))) {
468 if (bytestream2_get_bytes_left(gb) < 14)
469 return -1;
470 else if (AV_RB32(gb->buffer + 10) == EXIF_MM_LONG || AV_RB32(gb->buffer + 10) == EXIF_II_LONG)
471 return -1;
472 return 8;
473 }
474
475 return 0;
476}
477
478static int exif_parse_ifd_list(void *logctx, GetByteContext *gb, int le,
479 int depth, AVExifMetadata *ifd, int guess);
480
481static int exif_decode_tag(void *logctx, GetByteContext *gb, int le,
482 int depth, AVExifEntry *entry)
483{
484 int ret = 0, makernote_offset = -1, tell, is_ifd, count;
485 enum AVTiffDataType type;
486 uint32_t payload;
487
488 /* safety check to prevent infinite recursion on malicious IFDs */
489 if (depth > 3)
490 return AVERROR_INVALIDDATA;
491
493
494 entry->id = ff_tget_short(gb, le);
495 type = ff_tget_short(gb, le);
496 count = ff_tget_long(gb, le);
497 payload = ff_tget_long(gb, le);
498
499 av_log(logctx, AV_LOG_DEBUG, "TIFF Tag: id: 0x%04x, type: %d, count: %u, offset: %d, "
500 "payload: %" PRIu32 "\n", entry->id, type, count, tell, payload);
501
502 if (!type) {
503 av_log(logctx, AV_LOG_DEBUG, "Skipping invalid TIFF tag 0\n");
504 goto end;
505 }
506
507 /* AV_TIFF_IFD is the largest, numerically */
508 if (type > AV_TIFF_IFD || count >= INT_MAX/8U)
509 return AVERROR_INVALIDDATA;
510
511 is_ifd = type == AV_TIFF_IFD || ff_tis_ifd(entry->id) || entry->id == MAKERNOTE_TAG;
512
513 if (is_ifd) {
514 if (!payload)
515 goto end;
516 bytestream2_seek(gb, payload, SEEK_SET);
517 }
518
519 if (entry->id == MAKERNOTE_TAG) {
520 makernote_offset = exif_get_makernote_offset(gb);
521 if (makernote_offset < 0)
522 is_ifd = 0;
523 }
524
525 if (is_ifd) {
526 entry->type = AV_TIFF_IFD;
527 entry->count = 1;
528 entry->ifd_offset = makernote_offset > 0 ? makernote_offset : 0;
529 if (entry->ifd_offset) {
530 entry->ifd_lead = av_malloc(entry->ifd_offset);
531 if (!entry->ifd_lead)
532 return AVERROR(ENOMEM);
533 bytestream2_get_buffer(gb, entry->ifd_lead, entry->ifd_offset);
534 }
535 ret = exif_parse_ifd_list(logctx, gb, le, depth + 1, &entry->value.ifd, entry->id == MAKERNOTE_TAG);
536 if (ret < 0 && entry->id == MAKERNOTE_TAG) {
537 /*
538 * we guessed that MakerNote was an IFD
539 * but we were probably incorrect at this
540 * point so we try again as a binary blob
541 */
542 av_log(logctx, AV_LOG_DEBUG, "unrecognized MakerNote IFD, retrying as blob\n");
543 is_ifd = 0;
544 }
545 }
546
547 /* inverted condition instead of else so we can fall through from above */
548 if (!is_ifd) {
550 entry->count = count;
551 bytestream2_seek(gb, count * exif_sizes[type] > 4 ? payload : tell + 8, SEEK_SET);
552 ret = exif_read_values(logctx, gb, le, entry);
553 }
554
555end:
556 bytestream2_seek(gb, tell + BASE_TAG_SIZE, SEEK_SET);
557
558 return ret;
559}
560
561static int exif_parse_ifd_list(void *logctx, GetByteContext *gb, int le,
562 int depth, AVExifMetadata *ifd, int guess)
563{
564 uint32_t entries;
565 size_t required_size;
566 void *temp;
567 int ret = 0;
568
569 av_log(logctx, AV_LOG_DEBUG, "parsing IFD list at offset: %d\n", bytestream2_tell(gb));
570
571 if (bytestream2_get_bytes_left(gb) < 2) {
572 av_log(logctx, guess ? AV_LOG_DEBUG : AV_LOG_ERROR,
573 "not enough bytes remaining in EXIF buffer: 2 required\n");
575 goto end;
576 }
577
578 entries = ff_tget_short(gb, le);
579 if (bytestream2_get_bytes_left(gb) < entries * BASE_TAG_SIZE) {
580 av_log(logctx, guess ? AV_LOG_DEBUG : AV_LOG_ERROR,
581 "not enough bytes remaining in EXIF buffer. entries: %" PRIu32 "\n", entries);
583 goto end;
584 }
585 if (entries > 4096) {
586 /* that is a lot of entries, probably an error */
587 av_log(logctx, guess ? AV_LOG_DEBUG : AV_LOG_ERROR,
588 "too many entries: %" PRIu32 "\n", entries);
590 goto end;
591 }
592
593 ifd->count = entries;
594 av_log(logctx, AV_LOG_DEBUG, "entry count for IFD: %u\n", ifd->count);
595
596 /* empty IFD is technically legal but equivalent to no metadata present */
597 if (!ifd->count) {
598 ret = 0;
599 goto end;
600 }
601
602 if (av_size_mult(ifd->count, sizeof(*ifd->entries), &required_size) < 0) {
603 ret = AVERROR(ENOMEM);
604 goto end;
605 }
606 temp = av_fast_realloc(ifd->entries, &ifd->size, required_size);
607 if (!temp) {
608 av_freep(&ifd->entries);
609 ret = AVERROR(ENOMEM);
610 goto end;
611 }
612 ifd->entries = temp;
613
614 /* entries have pointers in them which can cause issues if */
615 /* they are freed or realloc'd when garbage */
616 memset(ifd->entries, 0, required_size);
617
618 for (uint32_t i = 0; i < entries; i++) {
619 ret = exif_decode_tag(logctx, gb, le, depth, &ifd->entries[i]);
620 if (ret < 0)
621 goto end;
622 }
623
624end:
625 if (ret < 0) {
626 av_exif_free(ifd);
627 return ret;
628 }
629 /*
630 * at the end of an IFD is an pointer to the next IFD
631 * or zero if there are no more IFDs, which is usually the case
632 */
633 ret = ff_tget_long(gb, le);
634
635 /* overflow */
636 if (ret < 0) {
638 av_exif_free(ifd);
639 }
640
641 return ret;
642}
643
644/*
645 * note that this function does not free the entry pointer itself
646 * because it's probably part of a larger array that should be freed
647 * all at once
648 */
650{
651 if (!entry)
652 return;
653 if (entry->type == AV_TIFF_IFD)
654 av_exif_free(&entry->value.ifd);
655 else
656 av_freep(&entry->value.ptr);
657 av_freep(&entry->ifd_lead);
658}
659
661{
662 if (!ifd)
663 return;
664 if (!ifd->entries) {
665 ifd->count = 0;
666 ifd->size = 0;
667 return;
668 }
669 for (size_t i = 0; i < ifd->count; i++) {
670 AVExifEntry *entry = &ifd->entries[i];
672 }
673 av_freep(&ifd->entries);
674 ifd->count = 0;
675 ifd->size = 0;
676}
677
678static size_t exif_get_ifd_size(const AVExifMetadata *ifd)
679{
680 /* 6 == 4 + 2; 2-byte entry-count at the beginning */
681 /* plus 4-byte next-IFD pointer at the end */
682 size_t total_size = IFD_EXTRA_SIZE;
683 for (size_t i = 0; i < ifd->count; i++) {
684 const AVExifEntry *entry = &ifd->entries[i];
685 if (entry->type == AV_TIFF_IFD) {
686 total_size += BASE_TAG_SIZE + exif_get_ifd_size(&entry->value.ifd) + entry->ifd_offset;
687 } else {
688 size_t payload_size = entry->count * exif_sizes[entry->type];
689 total_size += BASE_TAG_SIZE + (payload_size > 4 ? payload_size : 0);
690 }
691 }
692 return total_size;
693}
694
695static int exif_write_ifd(void *logctx, PutByteContext *pb, int le, int depth, const AVExifMetadata *ifd)
696{
697 int offset, ret, tell, tell2;
699 tput16(pb, le, ifd->count);
700 offset = tell + IFD_EXTRA_SIZE + BASE_TAG_SIZE * (uint32_t) ifd->count;
701 av_log(logctx, AV_LOG_DEBUG, "writing IFD with %u entries and initial offset %d\n", ifd->count, offset);
702 for (size_t i = 0; i < ifd->count; i++) {
703 const AVExifEntry *entry = &ifd->entries[i];
704 av_log(logctx, AV_LOG_DEBUG, "writing TIFF entry: id: 0x%04" PRIx16 ", type: %d, count: %"
705 PRIu32 ", offset: %d, offset value: %d\n",
706 entry->id, entry->type, entry->count,
708 tput16(pb, le, entry->id);
709 if (entry->id == MAKERNOTE_TAG && entry->type == AV_TIFF_IFD) {
710 size_t ifd_size = exif_get_ifd_size(&entry->value.ifd);
711 tput16(pb, le, AV_TIFF_UNDEFINED);
712 tput32(pb, le, ifd_size);
713 } else {
714 tput16(pb, le, entry->type);
715 tput32(pb, le, entry->count);
716 }
717 if (entry->type == AV_TIFF_IFD) {
718 tput32(pb, le, offset);
719 tell2 = bytestream2_tell_p(pb);
720 bytestream2_seek_p(pb, offset, SEEK_SET);
721 if (entry->ifd_offset)
722 bytestream2_put_buffer(pb, entry->ifd_lead, entry->ifd_offset);
723 ret = exif_write_ifd(logctx, pb, le, depth + 1, &entry->value.ifd);
724 if (ret < 0)
725 return ret;
726 offset += ret + entry->ifd_offset;
727 bytestream2_seek_p(pb, tell2, SEEK_SET);
728 } else {
729 size_t payload_size = entry->count * exif_sizes[entry->type];
730 if (payload_size > 4) {
731 tput32(pb, le, offset);
732 tell2 = bytestream2_tell_p(pb);
733 bytestream2_seek_p(pb, offset, SEEK_SET);
734 exif_write_values(pb, le, entry);
735 offset += payload_size;
736 bytestream2_seek_p(pb, tell2, SEEK_SET);
737 } else {
738 /* zero uninitialized excess payload values */
739 AV_WN32(pb->buffer, 0);
740 exif_write_values(pb, le, entry);
741 bytestream2_seek_p(pb, 4 - payload_size, SEEK_CUR);
742 }
743 }
744 }
745
746 /*
747 * we write 0 if this is the top-level exif IFD
748 * indicating that there are no more IFD pointers
749 */
750 tput32(pb, le, depth ? offset : 0);
751 return offset - tell;
752}
753
754int av_exif_write(void *logctx, const AVExifMetadata *ifd, AVBufferRef **buffer, enum AVExifHeaderMode header_mode)
755{
756 AVBufferRef *buf = NULL;
757 size_t size, headsize = 8;
759 int ret = 0, off = 0, next;
760 AVExifMetadata *ifd_new = NULL;
761 AVExifMetadata extra_ifds[16] = { 0 };
762
763 int le = 1;
764
765 if (*buffer) {
766 ret = AVERROR(EINVAL);
767 goto end;
768 }
769
770 size = exif_get_ifd_size(ifd);
771 switch (header_mode) {
772 case AV_EXIF_EXIF00:
773 off = 6;
774 break;
775 case AV_EXIF_T_OFF:
776 off = 4;
777 break;
779 le = 0;
780 headsize = 0;
781 break;
783 le = 1;
784 headsize = 0;
785 break;
786 }
787
788 ret = av_buffer_realloc(&buf, size + off + headsize);
789 if (ret < 0)
790 goto end;
791
792 if (header_mode == AV_EXIF_EXIF00) {
793 AV_WL32(buf->data, MKTAG('E','x','i','f'));
794 AV_WN16(buf->data + 4, 0);
795 } else if (header_mode == AV_EXIF_T_OFF) {
796 AV_WN32(buf->data, 0);
797 }
798
799 bytestream2_init_writer(&pb, buf->data + off, buf->size - off);
800
801 if (header_mode != AV_EXIF_ASSUME_BE && header_mode != AV_EXIF_ASSUME_LE) {
802 /* these constants are be32 in both cases */
803 /* le == 1 always in this case */
804 bytestream2_put_be32(&pb, EXIF_II_LONG);
805 tput32(&pb, le, 8);
806 }
807
808 int extras = 0;
809 for (int i = 0; i < FF_ARRAY_ELEMS(extra_ifds); i++) {
810 AVExifEntry *extra_entry = NULL;
811 uint16_t extra_tag = 0xFFFCu - i;
812 ret = av_exif_get_entry(logctx, (AVExifMetadata *) ifd, extra_tag, 0, &extra_entry);
813 if (ret < 0)
814 break;
815 if (!ret)
816 continue;
817 av_log(logctx, AV_LOG_DEBUG, "found extra IFD tag: %04x\n", extra_tag);
818 if (!ifd_new) {
819 ifd_new = av_exif_clone_ifd(ifd);
820 if (!ifd_new)
821 break;
822 ifd = ifd_new;
823 }
824 /* calling remove_entry will call av_exif_free on the original */
825 AVExifMetadata *cloned = av_exif_clone_ifd(&extra_entry->value.ifd);
826 if (!cloned)
827 break;
828 extra_ifds[extras++] = *cloned;
829 /* don't use av_exif_free here, we want to preserve internals */
830 av_free(cloned);
831 ret = av_exif_remove_entry(logctx, ifd_new, extra_tag, 0);
832 if (ret < 0)
833 break;
834 }
835
836 if (ret < 0) {
837 av_log(logctx, AV_LOG_ERROR, "error popping additional IFD: %s\n", av_err2str(ret));
838 goto end;
839 }
840
841 next = bytestream2_tell_p(&pb);
842 ret = exif_write_ifd(logctx, &pb, le, 0, ifd);
843 if (ret < 0) {
844 av_log(logctx, AV_LOG_ERROR, "error writing EXIF data: %s\n", av_err2str(ret));
845 goto end;
846 }
847 next += ret;
848
849 for (int i = 0; i < extras; i++) {
850 av_log(logctx, AV_LOG_DEBUG, "writing additional ifd at: %d\n", next);
851 /* exif_write_ifd always writes 0 i.e. last ifd so we overwrite that here */
852 bytestream2_seek_p(&pb, -4, SEEK_CUR);
853 tput32(&pb, le, next);
854 bytestream2_seek_p(&pb, next, SEEK_SET);
855 ret = exif_write_ifd(logctx, &pb, le, 0, &extra_ifds[i]);
856 if (ret < 0) {
857 av_log(logctx, AV_LOG_ERROR, "error writing additional IFD: %s\n", av_err2str(ret));
858 goto end;
859 }
860 next += ret;
861 }
862
863 /* shrink the buffer to the amount of data we actually used */
864 /* extras don't contribute the initial BASE_TAG_SIZE each */
865 ret = av_buffer_realloc(&buf, buf->size - BASE_TAG_SIZE * extras);
866 if (ret < 0)
867 goto end;
868
869 *buffer = buf;
870 ret = 0;
871
872end:
873 av_exif_free(ifd_new);
874 av_freep(&ifd_new);
875 for (int i = 0; i < FF_ARRAY_ELEMS(extra_ifds); i++)
876 av_exif_free(&extra_ifds[i]);
877 if (ret < 0)
878 av_buffer_unref(&buf);
879
880 return ret;
881}
882
883int av_exif_parse_buffer(void *logctx, const uint8_t *buf, size_t size,
884 AVExifMetadata *ifd, enum AVExifHeaderMode header_mode)
885{
886 int ret, le;
887 GetByteContext gbytes;
888 if (size > INT_MAX)
889 return AVERROR(EINVAL);
890 size_t off = 0;
891 switch (header_mode) {
892 case AV_EXIF_EXIF00:
893 if (size < 6)
894 return AVERROR_INVALIDDATA;
895 off = 6;
897 case AV_EXIF_T_OFF:
898 if (size < 4)
899 return AVERROR_INVALIDDATA;
900 if (!off)
901 off = AV_RB32(buf) + 4;
903 case AV_EXIF_TIFF_HEADER: {
904 int ifd_offset;
905 if (size <= off)
906 return AVERROR_INVALIDDATA;
907 bytestream2_init(&gbytes, buf + off, size - off);
908 // read TIFF header
909 ret = ff_tdecode_header(&gbytes, &le, &ifd_offset);
910 if (ret < 0) {
911 av_log(logctx, AV_LOG_ERROR, "invalid TIFF header in EXIF data: %s\n", av_err2str(ret));
912 return ret;
913 }
914 bytestream2_seek(&gbytes, ifd_offset, SEEK_SET);
915 break;
916 }
918 le = 1;
919 bytestream2_init(&gbytes, buf, size);
920 break;
922 le = 0;
923 bytestream2_init(&gbytes, buf, size);
924 break;
925 default:
926 return AVERROR(EINVAL);
927 }
928
929 /*
930 * parse IFD0 here. If the return value is positive that tells us
931 * there is subimage metadata, but we don't parse that IFD here
932 */
933 ret = exif_parse_ifd_list(logctx, &gbytes, le, 0, ifd, 0);
934 if (ret < 0) {
935 av_log(logctx, AV_LOG_ERROR, "error decoding EXIF data: %s\n", av_err2str(ret));
936 return ret;
937 }
938 if (!ret)
939 goto finish;
940 int next = ret;
941 bytestream2_seek(&gbytes, next, SEEK_SET);
942
943 /* cap at 16 extra IFDs for sanity/parse security */
944 for (int extra_tag = 0xFFFCu; extra_tag > 0xFFECu; extra_tag--) {
945 AVExifMetadata extra_ifd = { 0 };
946 ret = exif_parse_ifd_list(logctx, &gbytes, le, 0, &extra_ifd, 1);
947 if (ret < 0) {
948 av_exif_free(&extra_ifd);
949 break;
950 }
951 next = ret;
952 av_log(logctx, AV_LOG_DEBUG, "found extra IFD: %04x with next=%d\n", extra_tag, ret);
953 bytestream2_seek(&gbytes, next, SEEK_SET);
954 ret = av_exif_set_entry(logctx, ifd, extra_tag, AV_TIFF_IFD, 1, NULL, 0, &extra_ifd);
955 av_exif_free(&extra_ifd);
956 if (ret < 0 || !next || bytestream2_get_bytes_left(&gbytes) <= 0)
957 break;
958 }
959
960finish:
961 return bytestream2_tell(&gbytes) + off;
962}
963
964#define COLUMN_SEP(i, c) ((i) ? ((i) % (c) ? ", " : "\n") : "")
965
966static int exif_ifd_to_dict(void *logctx, const char *prefix, const AVExifMetadata *ifd, AVDictionary **metadata)
967{
968 AVBPrint bp;
969 int ret = 0;
970 char *key = NULL;
971 char *value = NULL;
972
973 if (!prefix)
974 prefix = "";
975
976 for (uint16_t i = 0; i < ifd->count; i++) {
977 const AVExifEntry *entry = &ifd->entries[i];
978 const char *name = av_exif_get_tag_name(entry->id);
980 if (*prefix)
981 av_bprintf(&bp, "%s/", prefix);
982 if (name)
983 av_bprintf(&bp, "%s", name);
984 else
985 av_bprintf(&bp, "0x%04X", entry->id);
986 ret = av_bprint_finalize(&bp, &key);
987 if (ret < 0)
988 goto end;
990 switch (entry->type) {
991 case AV_TIFF_IFD:
992 ret = exif_ifd_to_dict(logctx, key, &entry->value.ifd, metadata);
993 if (ret < 0)
994 goto end;
995 break;
996 case AV_TIFF_SHORT:
997 case AV_TIFF_LONG:
998 for (uint32_t j = 0; j < entry->count; j++)
999 av_bprintf(&bp, "%s%7" PRIu32, COLUMN_SEP(j, 8), (uint32_t)entry->value.uint[j]);
1000 break;
1001 case AV_TIFF_SSHORT:
1002 case AV_TIFF_SLONG:
1003 for (uint32_t j = 0; j < entry->count; j++)
1004 av_bprintf(&bp, "%s%7" PRId32, COLUMN_SEP(j, 8), (int32_t)entry->value.sint[j]);
1005 break;
1006 case AV_TIFF_RATIONAL:
1007 case AV_TIFF_SRATIONAL:
1008 for (uint32_t j = 0; j < entry->count; j++)
1009 av_bprintf(&bp, "%s%7i:%-7i", COLUMN_SEP(j, 4), entry->value.rat[j].num, entry->value.rat[j].den);
1010 break;
1011 case AV_TIFF_DOUBLE:
1012 case AV_TIFF_FLOAT:
1013 for (uint32_t j = 0; j < entry->count; j++)
1014 av_bprintf(&bp, "%s%.15g", COLUMN_SEP(j, 4), entry->value.dbl[j]);
1015 break;
1016 case AV_TIFF_STRING:
1017 av_bprintf(&bp, "%s", entry->value.str);
1018 break;
1019 case AV_TIFF_UNDEFINED:
1020 case AV_TIFF_BYTE:
1021 for (uint32_t j = 0; j < entry->count; j++)
1022 av_bprintf(&bp, "%s%3i", COLUMN_SEP(j, 16), entry->value.ubytes[j]);
1023 break;
1024 case AV_TIFF_SBYTE:
1025 for (uint32_t j = 0; j < entry->count; j++)
1026 av_bprintf(&bp, "%s%3i", COLUMN_SEP(j, 16), entry->value.sbytes[j]);
1027 break;
1028 }
1029 if (entry->type != AV_TIFF_IFD) {
1030 if (!av_bprint_is_complete(&bp)) {
1032 ret = AVERROR(ENOMEM);
1033 goto end;
1034 }
1035 ret = av_bprint_finalize(&bp, &value);
1036 if (ret < 0)
1037 goto end;
1039 key = NULL;
1040 value = NULL;
1041 if (ret < 0)
1042 goto end;
1043 } else {
1044 av_freep(&key);
1045 }
1046 }
1047
1048end:
1049 av_freep(&key);
1050 av_freep(&value);
1051 return ret;
1052}
1053
1055{
1056 return exif_ifd_to_dict(logctx, "", ifd, metadata);
1057}
1058
1059#define EXIF_COPY(fname, srcname) do { \
1060 size_t sz; \
1061 if (av_size_mult(src->count, sizeof(*(fname)), &sz) < 0) { \
1062 ret = AVERROR(ENOMEM); \
1063 goto end; \
1064 } \
1065 (fname) = av_memdup((srcname), sz); \
1066 if (!(fname)) { \
1067 ret = AVERROR(ENOMEM); \
1068 goto end; \
1069 } \
1070} while (0)
1071
1073{
1074 int ret = 0;
1075
1076 memset(dst, 0, sizeof(*dst));
1077
1078 dst->count = src->count;
1079 dst->id = src->id;
1080 dst->type = src->type;
1081
1082 dst->ifd_offset = src->ifd_offset;
1083 if (src->ifd_lead) {
1084 dst->ifd_lead = av_memdup(src->ifd_lead, src->ifd_offset);
1085 if (!dst->ifd_lead) {
1086 ret = AVERROR(ENOMEM);
1087 goto end;
1088 }
1089 } else {
1090 dst->ifd_lead = NULL;
1091 }
1092
1093 switch(src->type) {
1094 case AV_TIFF_IFD: {
1095 AVExifMetadata *cloned = av_exif_clone_ifd(&src->value.ifd);
1096 if (!cloned) {
1097 ret = AVERROR(ENOMEM);
1098 goto end;
1099 }
1100 dst->value.ifd = *cloned;
1101 av_freep(&cloned);
1102 break;
1103 }
1104 case AV_TIFF_SHORT:
1105 case AV_TIFF_LONG:
1106 EXIF_COPY(dst->value.uint, src->value.uint);
1107 break;
1108 case AV_TIFF_SLONG:
1109 case AV_TIFF_SSHORT:
1110 EXIF_COPY(dst->value.sint, src->value.sint);
1111 break;
1112 case AV_TIFF_RATIONAL:
1113 case AV_TIFF_SRATIONAL:
1114 EXIF_COPY(dst->value.rat, src->value.rat);
1115 break;
1116 case AV_TIFF_DOUBLE:
1117 case AV_TIFF_FLOAT:
1118 EXIF_COPY(dst->value.dbl, src->value.dbl);
1119 break;
1120 case AV_TIFF_BYTE:
1121 case AV_TIFF_UNDEFINED:
1122 EXIF_COPY(dst->value.ubytes, src->value.ubytes);
1123 break;
1124 case AV_TIFF_SBYTE:
1125 EXIF_COPY(dst->value.sbytes, src->value.sbytes);
1126 break;
1127 case AV_TIFF_STRING:
1128 dst->value.str = av_memdup(src->value.str, src->count+1);
1129 if (!dst->value.str) {
1130 ret = AVERROR(ENOMEM);
1131 goto end;
1132 }
1133 break;
1134 }
1135
1136 return 0;
1137
1138end:
1139 av_freep(&dst->ifd_lead);
1140 if (src->type == AV_TIFF_IFD)
1141 av_exif_free(&dst->value.ifd);
1142 else
1143 av_freep(&dst->value.ptr);
1144 memset(dst, 0, sizeof(*dst));
1145
1146 return ret;
1147}
1148
1149static int exif_get_entry(void *logctx, AVExifMetadata *ifd, uint16_t id, int depth, AVExifEntry **value)
1150{
1151 int offset = 1;
1152
1153 if (!ifd || ifd->count && !ifd->entries || !value)
1154 return AVERROR(EINVAL);
1155
1156 for (size_t i = 0; i < ifd->count; i++) {
1157 if (ifd->entries[i].id == id) {
1158 *value = &ifd->entries[i];
1159 return i + offset;
1160 }
1161 if (ifd->entries[i].type == AV_TIFF_IFD) {
1162 if (depth < 3) {
1163 int ret = exif_get_entry(logctx, &ifd->entries[i].value.ifd, id, depth + 1, value);
1164 if (ret)
1165 return ret < 0 ? ret : ret + offset;
1166 }
1167 offset += ifd->entries[i].value.ifd.count;
1168 }
1169 }
1170
1171 return 0;
1172}
1173
1174int av_exif_get_entry(void *logctx, AVExifMetadata *ifd, uint16_t id, int flags, AVExifEntry **value)
1175{
1176 return exif_get_entry(logctx, ifd, id, (flags & AV_EXIF_FLAG_RECURSIVE) ? 0 : INT_MAX, value);
1177}
1178
1179int av_exif_set_entry(void *logctx, AVExifMetadata *ifd, uint16_t id, enum AVTiffDataType type,
1180 uint32_t count, const uint8_t *ifd_lead, uint32_t ifd_offset, const void *value)
1181{
1182 void *temp;
1183 int ret, offset;
1185 AVExifEntry src = { 0 };
1186
1187 if (!ifd || ifd->count && !ifd->entries
1188 || ifd_lead && !ifd_offset || !ifd_lead && ifd_offset
1189 || !value || ifd->count == 0xFFFFu)
1190 return AVERROR(EINVAL);
1191
1192 ret = av_exif_get_entry(logctx, ifd, id, 0, &entry);
1193 if (ret < 0)
1194 return ret;
1195 offset = ret;
1196
1197 if (entry) {
1199 } else {
1200 size_t required_size;
1201 ret = av_size_mult(ifd->count + 1, sizeof(*ifd->entries), &required_size);
1202 if (ret < 0)
1203 return AVERROR(ENOMEM);
1204 temp = av_fast_realloc(ifd->entries, &ifd->size, required_size);
1205 if (!temp)
1206 return AVERROR(ENOMEM);
1207 ifd->entries = temp;
1208 entry = &ifd->entries[ifd->count++];
1209 }
1210
1211 src.count = count;
1212 src.id = id;
1213 src.type = type;
1214 src.ifd_lead = (uint8_t *) ifd_lead;
1215 src.ifd_offset = ifd_offset;
1216 if (type == AV_TIFF_IFD)
1217 src.value.ifd = * (const AVExifMetadata *) value;
1218 else
1219 src.value.ptr = (void *) value;
1220
1221 ret = exif_clone_entry(entry, &src);
1222
1223 if (ret < 0) {
1224 /* offset is the actual offset + 1 */
1225 if (offset) {
1226 size_t remaining = ifd->count - offset;
1227 /* pop the entry off the IFD by shifting everything to the left */
1228 memmove(&ifd->entries[offset - 1], &ifd->entries[offset], sizeof(*ifd->entries) * remaining);
1229 }
1230 ifd->count--;
1231 }
1232
1233 return ret;
1234}
1235
1236static int exif_remove_entry(void *logctx, AVExifMetadata *ifd, uint16_t id, int depth)
1237{
1238 int32_t index = -1;
1239 int ret = 0;
1240
1241 if (!ifd || ifd->count && !ifd->entries)
1242 return AVERROR(EINVAL);
1243
1244 for (size_t i = 0; i < ifd->count; i++) {
1245 if (ifd->entries[i].id == id) {
1246 index = i;
1247 break;
1248 }
1249 if (ifd->entries[i].type == AV_TIFF_IFD && depth < 3) {
1250 ret = exif_remove_entry(logctx, &ifd->entries[i].value.ifd, id, depth + 1);
1251 if (ret)
1252 return ret;
1253 }
1254 }
1255
1256 if (index < 0)
1257 return 0;
1259
1260 if (index == --ifd->count) {
1261 if (!index) {
1262 av_freep(&ifd->entries);
1263 ifd->size = 0;
1264 }
1265 return 1;
1266 }
1267
1268 memmove(&ifd->entries[index], &ifd->entries[index + 1], (ifd->count - index) * sizeof(*ifd->entries));
1269
1270 return 1 + (ifd->count - index);
1271}
1272
1273int av_exif_remove_entry(void *logctx, AVExifMetadata *ifd, uint16_t id, int flags)
1274{
1275 return exif_remove_entry(logctx, ifd, id, (flags & AV_EXIF_FLAG_RECURSIVE) ? 0 : INT_MAX);
1276}
1277
1279{
1280 AVExifMetadata *ret = av_mallocz(sizeof(*ret));
1281 if (!ret)
1282 return NULL;
1283
1284 ret->count = ifd->count;
1285 if (ret->count) {
1286 size_t required_size;
1287 if (av_size_mult(ret->count, sizeof(*ret->entries), &required_size) < 0)
1288 goto fail;
1289 av_fast_mallocz(&ret->entries, &ret->size, required_size);
1290 if (!ret->entries)
1291 goto fail;
1292 }
1293
1294 for (size_t i = 0; i < ret->count; i++) {
1295 const AVExifEntry *entry = &ifd->entries[i];
1296 AVExifEntry *ret_entry = &ret->entries[i];
1297 int status = exif_clone_entry(ret_entry, entry);
1298 if (status < 0)
1299 goto fail;
1300 }
1301
1302 return ret;
1303
1304fail:
1305 av_exif_free(ret);
1306 av_free(ret);
1307 return NULL;
1308}
1309
1310static const int rotation_lut[2][4] = {
1311 {1, 8, 3, 6}, {4, 7, 2, 5},
1312};
1313
1315{
1316 double rotation = av_display_rotation_get(matrix);
1317 // determinant
1318 int vflip = ((int64_t)matrix[0] * (int64_t)matrix[4]
1319 - (int64_t)matrix[1] * (int64_t)matrix[3]) < 0;
1320 if (!isfinite(rotation))
1321 return 0;
1322 int rot = (int)(rotation + 0.5);
1323 rot = (((rot % 360) + 360) % 360) / 90;
1324 return rotation_lut[vflip][rot];
1325}
1326
1328{
1329 switch (orientation) {
1330 case 1:
1332 break;
1333 case 2:
1336 break;
1337 case 3:
1339 break;
1340 case 4:
1343 break;
1344 case 5:
1347 break;
1348 case 6:
1350 break;
1351 case 7:
1354 break;
1355 case 8:
1357 break;
1358 default:
1359 return AVERROR(EINVAL);
1360 }
1361
1362 return 0;
1363}
1364
1365int ff_exif_sanitize_ifd(void *logctx, const AVFrame *frame, AVExifMetadata *ifd)
1366{
1367 int ret = 0;
1368 AVFrameSideData *sd_orient = NULL;
1369 AVExifEntry *or = NULL;
1370 AVExifEntry *iw = NULL;
1371 AVExifEntry *ih = NULL;
1372 AVExifEntry *pw = NULL;
1373 AVExifEntry *ph = NULL;
1374 uint64_t orientation = 1;
1375 uint64_t w = frame->width;
1376 uint64_t h = frame->height;
1377 int rewrite = 0;
1378
1380
1381 if (sd_orient)
1382 orientation = av_exif_matrix_to_orientation((int32_t *) sd_orient->data);
1383 if (!orientation) {
1384 av_log(logctx, AV_LOG_WARNING, "display matrix is singular\n");
1385 orientation = 1;
1386 }
1387 if (orientation != 1)
1388 av_log(logctx, AV_LOG_DEBUG, "matrix contains nontrivial EXIF orientation: %" PRIu64 "\n", orientation);
1389
1390 for (size_t i = 0; i < ifd->count; i++) {
1391 AVExifEntry *entry = &ifd->entries[i];
1392 if (entry->id == ORIENTATION_TAG && entry->count > 0 && entry->type == AV_TIFF_SHORT) {
1393 or = entry;
1394 continue;
1395 }
1396 if (entry->id == IMAGE_WIDTH_TAG && entry->count > 0 && entry->type == AV_TIFF_LONG) {
1397 iw = entry;
1398 continue;
1399 }
1400 if (entry->id == IMAGE_LENGTH_TAG && entry->count > 0 && entry->type == AV_TIFF_LONG) {
1401 ih = entry;
1402 continue;
1403 }
1404 if (entry->id == EXIFIFD_TAG && entry->type == AV_TIFF_IFD) {
1405 AVExifMetadata *exif = &entry->value.ifd;
1406 for (size_t j = 0; j < exif->count; j++) {
1407 AVExifEntry *exifentry = &exif->entries[j];
1408 if (exifentry->id == PIXEL_X_TAG && exifentry->count > 0 && exifentry->type == AV_TIFF_SHORT) {
1409 pw = exifentry;
1410 continue;
1411 }
1412 if (exifentry->id == PIXEL_Y_TAG && exifentry->count > 0 && exifentry->type == AV_TIFF_SHORT) {
1413 ph = exifentry;
1414 continue;
1415 }
1416 }
1417 }
1418 }
1419
1420 if (or && or->value.uint[0] != orientation) {
1421 rewrite = 1;
1422 or->value.uint[0] = orientation;
1423 }
1424 if (iw && iw->value.uint[0] != w) {
1425 rewrite = 1;
1426 iw->value.uint[0] = w;
1427 }
1428 if (ih && ih->value.uint[0] != h) {
1429 rewrite = 1;
1430 ih->value.uint[0] = h;
1431 }
1432 if (pw && pw->value.uint[0] != w) {
1433 rewrite = 1;
1434 pw->value.uint[0] = w;
1435 }
1436 if (ph && ph->value.uint[0] != h) {
1437 rewrite = 1;
1438 ph->value.uint[0] = h;
1439 }
1440 if (!or && orientation != 1) {
1441 rewrite = 1;
1442 ret = av_exif_set_entry(logctx, ifd, ORIENTATION_TAG, AV_TIFF_SHORT, 1, NULL, 0, &orientation);
1443 if (ret < 0)
1444 goto end;
1445 }
1446 if (!iw && w) {
1447 rewrite = 1;
1448 ret = av_exif_set_entry(logctx, ifd, IMAGE_WIDTH_TAG, AV_TIFF_LONG, 1, NULL, 0, &w);
1449 if (ret < 0)
1450 goto end;
1451 }
1452 if (!ih && h) {
1453 rewrite = 1;
1454 ret = av_exif_set_entry(logctx, ifd, IMAGE_LENGTH_TAG, AV_TIFF_LONG, 1, NULL, 0, &h);
1455 if (ret < 0)
1456 goto end;
1457 }
1458 if (!pw && w && w <= 0xFFFFu || !ph && h && h <= 0xFFFFu) {
1459 AVExifMetadata *exif;
1460 AVExifEntry *exif_entry;
1461 int exif_found = av_exif_get_entry(logctx, ifd, EXIFIFD_TAG, 0, &exif_entry);
1462 rewrite = 1;
1463 if (exif_found < 0)
1464 goto end;
1465 if (exif_found > 0) {
1466 exif = &exif_entry->value.ifd;
1467 } else {
1468 AVExifMetadata exif_new = { 0 };
1469 ret = av_exif_set_entry(logctx, ifd, EXIFIFD_TAG, AV_TIFF_IFD, 1, NULL, 0, &exif_new);
1470 if (ret < 0) {
1471 av_exif_free(&exif_new);
1472 goto end;
1473 }
1474 exif = &ifd->entries[ifd->count - 1].value.ifd;
1475 }
1476 if (!pw && w && w <= 0xFFFFu) {
1477 ret = av_exif_set_entry(logctx, exif, PIXEL_X_TAG, AV_TIFF_SHORT, 1, NULL, 0, &w);
1478 if (ret < 0)
1479 goto end;
1480 }
1481 if (!ph && h && h <= 0xFFFFu) {
1482 ret = av_exif_set_entry(logctx, exif, PIXEL_Y_TAG, AV_TIFF_SHORT, 1, NULL, 0, &h);
1483 if (ret < 0)
1484 goto end;
1485 }
1486 }
1487
1488 return rewrite;
1489
1490end:
1491 return ret;
1492}
1493
1494int ff_exif_get_buffer(void *logctx, const AVFrame *frame, AVBufferRef **buffer_ptr, enum AVExifHeaderMode header_mode)
1495{
1496 AVFrameSideData *sd_exif = NULL;
1498 AVExifMetadata ifd = { 0 };
1499 int ret = 0;
1500 int rewrite = 0;
1501
1502 if (!buffer_ptr || *buffer_ptr)
1503 return AVERROR(EINVAL);
1504
1507 return 0;
1508
1509 if (sd_exif) {
1510 ret = av_exif_parse_buffer(logctx, sd_exif->data, sd_exif->size, &ifd, AV_EXIF_TIFF_HEADER);
1511 if (ret < 0)
1512 goto end;
1513 }
1514
1515 rewrite = ff_exif_sanitize_ifd(logctx, frame, &ifd);
1516 if (rewrite < 0) {
1517 ret = rewrite;
1518 goto end;
1519 }
1520
1521 /*
1522 * we always have to rewrite if the requested header mode
1523 * does not match the internal header mode, which is always
1524 * AV_EXIF_TIFF_HEADER inside FFmpeg.
1525 *
1526 * If ifd.count == 0 then there's no data to write at all.
1527 * This is possible if the frame width and height are zero and the orientation is 1.
1528 */
1529 rewrite = (rewrite || header_mode != AV_EXIF_TIFF_HEADER) && ifd.count;
1530
1531 if (rewrite) {
1532 ret = av_exif_write(logctx, &ifd, &buffer, header_mode);
1533 if (ret < 0)
1534 goto end;
1535
1536 *buffer_ptr = buffer;
1537 } else if (sd_exif) {
1538 *buffer_ptr = av_buffer_ref(sd_exif->buf);
1539 if (!*buffer_ptr) {
1540 ret = AVERROR(ENOMEM);
1541 goto end;
1542 }
1543 }
1544
1545 av_exif_free(&ifd);
1546
1547 return !!(rewrite || sd_exif);
1548
1549end:
1550 av_exif_free(&ifd);
1551 return ret;
1552}
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
Definition dsp.h:87
#define entry
static void finish(void)
int32_t
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition avassert.h:42
static int BS_FUNC tell(const BSCTX *bc)
Return number of bits already read.
void av_bprintf(AVBPrint *buf, const char *fmt,...)
Definition bprint.c:122
void av_bprint_init(AVBPrint *buf, unsigned size_init, unsigned size_max)
Definition bprint.c:69
AVBPrint public header.
#define AV_BPRINT_SIZE_UNLIMITED
static av_always_inline int bytestream2_tell_p(const PutByteContext *p)
Definition bytestream.h:197
static av_always_inline unsigned int bytestream2_get_buffer(GetByteContext *g, uint8_t *dst, unsigned int size)
Definition bytestream.h:267
static av_always_inline void bytestream2_init_writer(PutByteContext *p, uint8_t *buf, int buf_size)
Definition bytestream.h:147
static av_always_inline int bytestream2_get_bytes_left(const GetByteContext *g)
Definition bytestream.h:158
static av_always_inline void bytestream2_init(GetByteContext *g, const uint8_t *buf, int buf_size)
Definition bytestream.h:137
static av_always_inline int bytestream2_seek(GetByteContext *g, int offset, int whence)
Definition bytestream.h:212
static av_always_inline int bytestream2_seek_p(PutByteContext *p, int offset, int whence)
Definition bytestream.h:236
static av_always_inline int bytestream2_tell(const GetByteContext *g)
Definition bytestream.h:192
static av_always_inline unsigned int bytestream2_put_buffer(PutByteContext *p, const uint8_t *src, unsigned int size)
Definition bytestream.h:286
static int FUNC metadata(CodedBitstreamContext *ctx, RWContext *rw, APVRawMetadata *current)
#define flags(name, subs,...)
Definition cbs_h264.c:74
#define i(width, name, range_min, range_max)
Definition cbs_h264.c:63
static int FUNC ph(CodedBitstreamContext *ctx, RWContext *rw, H266RawPH *current)
#define NULL
Definition coverity.c:32
long long int64_t
Definition coverity.c:34
static AVFrame * frame
Display matrix.
enum AVCodecID id
Definition dts2pts.c:607
double value
Definition eval.c:102
#define ORIENTATION_TAG
Definition exif.c:51
static const uint8_t sigma_header[]
Definition exif.c:425
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.
Definition exif.c:1174
#define EXIFIFD_TAG
Definition exif.c:52
#define PIXEL_Y_TAG
Definition exif.c:56
#define IMAGE_LENGTH_TAG
Definition exif.c:54
static void exif_write_values(PutByteContext *pb, int le, const AVExifEntry *entry)
Definition exif.c:366
static const struct exif_makernote_data makernote_data[]
Definition exif.c:440
static const uint8_t panasonic_header[]
Definition exif.c:424
static void tput16(PutByteContext *pb, const int le, const uint16_t value)
Definition exif.c:258
static void tput64(PutByteContext *pb, const int le, const uint64_t value)
Definition exif.c:268
static const uint8_t olympus2_header[]
Definition exif.c:423
static int exif_get_entry(void *logctx, AVExifMetadata *ifd, uint16_t id, int depth, AVExifEntry **value)
Definition exif.c:1149
static int exif_remove_entry(void *logctx, AVExifMetadata *ifd, uint16_t id, int depth)
Definition exif.c:1236
static int exif_clone_entry(AVExifEntry *dst, const AVExifEntry *src)
Definition exif.c:1072
static int exif_decode_tag(void *logctx, GetByteContext *gb, int le, int depth, AVExifEntry *entry)
Definition exif.c:481
static const struct exif_tag tag_list[]
Definition exif.c:63
static void exif_free_entry(AVExifEntry *entry)
Definition exif.c:649
static const uint8_t foveon_header[]
Definition exif.c:419
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.
Definition exif.c:1179
#define BASE_TAG_SIZE
Definition exif.c:46
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.
Definition exif.c:883
static size_t exif_get_ifd_size(const AVExifMetadata *ifd)
Definition exif.c:678
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.
Definition exif.c:1054
void av_exif_free(AVExifMetadata *ifd)
Frees all resources associated with the given EXIF metadata struct.
Definition exif.c:660
static const uint8_t aoc_header[]
Definition exif.c:417
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...
Definition exif.c:1314
static const uint8_t casio_header[]
Definition exif.c:418
#define PIXEL_X_TAG
Definition exif.c:55
static const uint8_t fuji_header[]
Definition exif.c:420
const char * av_exif_get_tag_name(uint16_t id)
Retrieves the tag name associated with the provided tag ID.
Definition exif.c:235
#define MAKERNOTE_STRUCT(h, r)
Definition exif.c:434
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...
Definition exif.c:1327
static const uint8_t olympus1_header[]
Definition exif.c:422
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...
Definition exif.c:1494
#define EXIF_II_LONG
Definition exif.c:43
AVExifMetadata * av_exif_clone_ifd(const AVExifMetadata *ifd)
Allocates a duplicate of the provided EXIF metadata struct.
Definition exif.c:1278
static const int rotation_lut[2][4]
Definition exif.c:1310
#define IMAGE_WIDTH_TAG
Definition exif.c:53
static int exif_ifd_to_dict(void *logctx, const char *prefix, const AVExifMetadata *ifd, AVDictionary **metadata)
Definition exif.c:966
static int exif_read_values(void *logctx, GetByteContext *gb, int le, AVExifEntry *entry)
Definition exif.c:273
#define EXIF_COPY(fname, srcname)
Definition exif.c:1059
#define MAKERNOTE_TAG
Definition exif.c:50
static int exif_parse_ifd_list(void *logctx, GetByteContext *gb, int le, int depth, AVExifMetadata *ifd, int guess)
Definition exif.c:561
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...
Definition exif.c:1365
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...
Definition exif.c:754
#define COLUMN_SEP(i, c)
Definition exif.c:964
#define IFD_EXTRA_SIZE
Definition exif.c:47
#define EXIF_TAG_NAME_LENGTH
Definition exif.c:49
static int exif_write_ifd(void *logctx, PutByteContext *pb, int le, int depth, const AVExifMetadata *ifd)
Definition exif.c:695
int32_t av_exif_get_tag_id(const char *name)
Retrieves the tag ID associated with the provided tag string name.
Definition exif.c:245
static void tput32(PutByteContext *pb, const int le, const uint32_t value)
Definition exif.c:263
int av_exif_remove_entry(void *logctx, AVExifMetadata *ifd, uint16_t id, int flags)
Remove an entry from the provided EXIF metadata struct.
Definition exif.c:1273
#define EXIF_MM_LONG
Definition exif.c:44
static const uint8_t sony_header[]
Definition exif.c:426
static const size_t exif_sizes[]
Definition exif.c:218
static const uint8_t nikon_header[]
Definition exif.c:421
static int exif_get_makernote_offset(GetByteContext *gb)
Definition exif.c:457
AVTiffDataType
Data type identifiers for TIFF tags.
Definition exif.h:41
@ AV_TIFF_SLONG
Definition exif.h:50
@ AV_TIFF_STRING
Definition exif.h:43
@ AV_TIFF_FLOAT
Definition exif.h:52
@ AV_TIFF_SBYTE
Definition exif.h:47
@ AV_TIFF_SHORT
Definition exif.h:44
@ AV_TIFF_SRATIONAL
Definition exif.h:51
@ AV_TIFF_SSHORT
Definition exif.h:49
@ AV_TIFF_RATIONAL
Definition exif.h:46
@ AV_TIFF_LONG
Definition exif.h:45
@ AV_TIFF_IFD
Definition exif.h:54
@ AV_TIFF_DOUBLE
Definition exif.h:53
@ AV_TIFF_BYTE
Definition exif.h:42
@ AV_TIFF_UNDEFINED
Definition exif.h:48
#define AV_EXIF_FLAG_RECURSIVE
Also check subdirectories.
Definition exif.h:149
AVExifHeaderMode
Definition exif.h:57
@ AV_EXIF_EXIF00
The first six bytes contain "Exif\0\0", then it's AV_EXIF_TIFF_HEADER.
Definition exif.h:70
@ AV_EXIF_TIFF_HEADER
The TIFF header starts with 0x49492a00, or 0x4d4d002a.
Definition exif.h:62
@ AV_EXIF_ASSUME_BE
skip the TIFF header, assume big endian
Definition exif.h:66
@ AV_EXIF_ASSUME_LE
skip the TIFF header, assume little endian
Definition exif.h:64
@ AV_EXIF_T_OFF
The first four bytes point to the actual start, then it's AV_EXIF_TIFF_HEADER.
Definition exif.h:68
EXIF metadata parser - internal functions.
const char * key
#define fail
Definition test.h:479
static int av_bprint_is_complete(const AVBPrint *buf)
Test if the print buffer is complete (not truncated).
Definition bprint.h:218
int av_bprint_finalize(AVBPrint *buf, char **ret_str)
Finalize a print buffer.
Definition bprint.c:235
void av_buffer_unref(AVBufferRef **buf)
Free a given reference and automatically free the buffer if there are no more references to it.
Definition buffer.c:139
int av_buffer_realloc(AVBufferRef **pbuf, size_t size)
Reallocate a given buffer.
Definition buffer.c:183
AVBufferRef * av_buffer_ref(const AVBufferRef *buf)
Create a new reference to an AVBuffer.
Definition buffer.c:103
#define AV_DICT_DONT_STRDUP_VAL
Take ownership of a value that's been allocated with av_malloc() or another memory allocation functio...
Definition dict.h:79
int av_dict_set(AVDictionary **pm, const char *key, const char *value, int flags)
Set the given entry in *pm, overwriting an existing entry.
Definition dict.c:86
#define AV_DICT_DONT_STRDUP_KEY
Take ownership of a key that's been allocated with av_malloc() or another memory allocation function.
Definition dict.h:77
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition error.h:61
#define av_err2str(errnum)
Convenience macro, the return value should be used only directly in function arguments but never stan...
Definition error.h:122
#define AVERROR(e)
Definition error.h:45
AVFrameSideData * av_frame_get_side_data(const AVFrame *frame, enum AVFrameSideDataType type)
Definition frame.c:659
@ AV_FRAME_DATA_EXIF
Exchangeable image file format metadata.
Definition frame.h:263
@ AV_FRAME_DATA_DISPLAYMATRIX
This side data contains a 3x3 transformation matrix describing an affine transformation that needs to...
Definition frame.h:85
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition log.h:231
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition log.h:216
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition log.h:210
static AVRational av_make_q(int num, int den)
Create an AVRational.
Definition rational.h:71
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.
Definition mem.c:560
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.
Definition mem.c:495
void * av_memdup(const void *p, size_t size)
Duplicate a buffer with av_malloc().
Definition mem.c:302
int av_size_mult(size_t a, size_t b, size_t *r)
Multiply two size_t values checking for overflow.
Definition mem.c:565
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...
Definition display.c:51
double av_display_rotation_get(const int32_t matrix[9])
Extract the rotation component of the transformation matrix.
Definition display.c:35
void av_display_matrix_flip(int32_t matrix[9], int hflip, int vflip)
Flip the input matrix horizontally and/or vertically.
Definition display.c:66
int index
Definition gxfenc.c:90
int a
cl_device_type type
#define AV_WN32(p, v)
#define AV_WL32(p, v)
#define AV_RB32(p)
#define AV_WN16(p, v)
unsigned offset
Definition libaomenc.c:763
Macro definitions for various function/variable attributes.
#define av_fallthrough
Definition attributes.h:67
#define isfinite(x)
Definition libm.h:361
uint8_t w
Definition llvidencdsp.c:39
#define MKTAG(a, b, c, d)
Definition macros.h:55
void * av_calloc(size_t nmemb, size_t size)
Definition mem.c:264
Memory handling functions.
#define av_malloc(s)
Definition ops_static.c:52
const char * name
Definition qsvenc.c:142
#define FF_ARRAY_ELEMS(a)
A reference to a data buffer.
Definition buffer.h:82
uint8_t * data
The data buffer.
Definition buffer.h:90
size_t size
Size of data in bytes.
Definition buffer.h:94
AVExifMetadata ifd
Definition exif.h:114
enum AVTiffDataType type
Definition exif.h:86
uint16_t id
Definition exif.h:85
uint32_t count
Definition exif.h:87
union AVExifEntry::@325220332140161067313112036135003363017341144014 value
uint64_t * uint
Definition exif.h:108
unsigned int count
Definition exif.h:79
AVExifEntry * entries
Definition exif.h:77
unsigned int size
Definition exif.h:81
Structure to hold side data for an AVFrame.
Definition frame.h:327
size_t size
Definition frame.h:330
uint8_t * data
Definition frame.h:329
AVBufferRef * buf
Definition frame.h:332
This structure describes decoded (raw) audio or video data.
Definition frame.h:472
const uint8_t * buffer
Definition bytestream.h:34
uint8_t * buffer
Definition bytestream.h:38
Definition mccdec.c:79
size_t header_size
Definition exif.c:430
const uint8_t * header
Definition exif.c:429
const char name[EXIF_TAG_NAME_LENGTH]
Definition exif.c:59
uint16_t id
Definition exif.c:60
#define av_free(p)
#define av_mallocz(s)
#define av_freep(p)
#define av_log(a,...)
#define src
Definition vp8dsp.c:248
static char buffer[20]
Definition seek.c:32
int ff_tis_ifd(unsigned tag)
Returns a value > 0 if the tag is a known IFD-tag.
Definition tiff_common.c:33
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.
Definition tiff_common.c:45
double ff_tget_double(GetByteContext *gb, int le)
Reads a double from the bytestream using given endianness.
Definition tiff_common.c:57
unsigned ff_tget_long(GetByteContext *gb, int le)
Reads a long from the bytestream using given endianness.
Definition tiff_common.c:51
TIFF Common Routines.
int size
char prefix[8]
else temp
Definition vf_mcdeint.c:275