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 {"ExifVersion", 0x9000}, // <- Table 4 Exif IFD Attribute Information (1)
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}, // <- Table 5 Exif IFD Attribute Information (2)
142 {"FNumber", 0x829D},
143 {"ExposureProgram", 0x8822},
144 {"SpectralSensitivity", 0x8824},
145 {"ISOSpeedRatings", 0x8827},
146 {"OECF", 0x8828},
147 {"ShutterSpeedValue", 0x9201},
148 {"ApertureValue", 0x9202},
149 {"BrightnessValue", 0x9203},
150 {"ExposureBiasValue", 0x9204},
151 {"MaxApertureValue", 0x9205},
152 {"SubjectDistance", 0x9206},
153 {"MeteringMode", 0x9207},
154 {"LightSource", 0x9208},
155 {"Flash", 0x9209},
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},
181
182 /* InteropIFD tags */
183 {"RelatedImageFileFormat", 0x1000},
184 {"RelatedImageWidth", 0x1001},
185 {"RelatedImageLength", 0x1002},
186
187 /* private EXIF tags */
188 {"PrintImageMatching", 0xC4A5}, // <- undocumented meaning
189
190 /* IFD tags */
191 {"ExifIFD", 0x8769}, // <- An IFD pointing to standard Exif metadata
192 {"GPSInfo", 0x8825}, // <- An IFD pointing to GPS Exif Metadata
193 {"InteropIFD", 0xA005}, // <- Table 13 Interoperability IFD Attribute Information
194 {"GlobalParametersIFD", 0x0190},
195 {"ProfileIFD", 0xc6f5},
196
197 /* Extra FFmpeg tags */
198 { "IFD1", 0xFFFC},
199 { "IFD2", 0xFFFB},
200 { "IFD3", 0xFFFA},
201 { "IFD4", 0xFFF9},
202 { "IFD5", 0xFFF8},
203 { "IFD6", 0xFFF7},
204 { "IFD7", 0xFFF6},
205 { "IFD8", 0xFFF5},
206 { "IFD9", 0xFFF4},
207 { "IFD10", 0xFFF3},
208 { "IFD11", 0xFFF2},
209 { "IFD12", 0xFFF1},
210 { "IFD13", 0xFFF0},
211 { "IFD14", 0xFFEF},
212 { "IFD15", 0xFFEE},
213 { "IFD16", 0xFFED},
214};
215
216/* same as type_sizes but with string == 1 */
217static const size_t exif_sizes[] = {
218 [0] = 0,
219 [AV_TIFF_BYTE] = 1,
220 [AV_TIFF_STRING] = 1,
221 [AV_TIFF_SHORT] = 2,
222 [AV_TIFF_LONG] = 4,
223 [AV_TIFF_RATIONAL] = 8,
224 [AV_TIFF_SBYTE] = 1,
225 [AV_TIFF_UNDEFINED] = 1,
226 [AV_TIFF_SSHORT] = 2,
227 [AV_TIFF_SLONG] = 4,
228 [AV_TIFF_SRATIONAL] = 8,
229 [AV_TIFF_FLOAT] = 4,
230 [AV_TIFF_DOUBLE] = 8,
231 [AV_TIFF_IFD] = 4,
232};
233
234const char *av_exif_get_tag_name(uint16_t id)
235{
236 for (size_t i = 0; i < FF_ARRAY_ELEMS(tag_list); i++) {
237 if (tag_list[i].id == id)
238 return tag_list[i].name;
239 }
240
241 return NULL;
242}
243
245{
246 if (!name)
247 return -1;
248
249 for (size_t i = 0; i < FF_ARRAY_ELEMS(tag_list); i++) {
250 if (!strcmp(tag_list[i].name, name))
251 return tag_list[i].id;
252 }
253
254 return -1;
255}
256
257static inline void tput16(PutByteContext *pb, const int le, const uint16_t value)
258{
259 le ? bytestream2_put_le16(pb, value) : bytestream2_put_be16(pb, value);
260}
261
262static inline void tput32(PutByteContext *pb, const int le, const uint32_t value)
263{
264 le ? bytestream2_put_le32(pb, value) : bytestream2_put_be32(pb, value);
265}
266
267static inline void tput64(PutByteContext *pb, const int le, const uint64_t value)
268{
269 le ? bytestream2_put_le64(pb, value) : bytestream2_put_be64(pb, value);
270}
271
272static int exif_read_values(void *logctx, GetByteContext *gb, int le, AVExifEntry *entry)
273{
274 if (exif_sizes[entry->type] * entry->count > bytestream2_get_bytes_left(gb))
275 return AVERROR_INVALIDDATA;
276
277 switch (entry->type) {
278 case AV_TIFF_SHORT:
279 case AV_TIFF_LONG:
280 entry->value.uint = av_calloc(entry->count, sizeof(*entry->value.uint));
281 break;
282 case AV_TIFF_SSHORT:
283 case AV_TIFF_SLONG:
284 entry->value.sint = av_calloc(entry->count, sizeof(*entry->value.sint));
285 break;
286 case AV_TIFF_DOUBLE:
287 case AV_TIFF_FLOAT:
288 entry->value.dbl = av_calloc(entry->count, sizeof(*entry->value.dbl));
289 break;
290 case AV_TIFF_RATIONAL:
292 entry->value.rat = av_calloc(entry->count, sizeof(*entry->value.rat));
293 break;
295 case AV_TIFF_BYTE:
296 entry->value.ubytes = av_mallocz(entry->count);
297 break;
298 case AV_TIFF_SBYTE:
299 entry->value.sbytes = av_mallocz(entry->count);
300 break;
301 case AV_TIFF_STRING:
302 entry->value.str = av_mallocz(entry->count + 1);
303 break;
304 case AV_TIFF_IFD:
305 av_log(logctx, AV_LOG_WARNING, "Bad IFD type for non-IFD tag\n");
306 return AVERROR_INVALIDDATA;
307 }
308 if (!entry->value.ptr)
309 return AVERROR(ENOMEM);
310 switch (entry->type) {
311 case AV_TIFF_SHORT:
312 for (size_t i = 0; i < entry->count; i++)
313 entry->value.uint[i] = ff_tget_short(gb, le);
314 break;
315 case AV_TIFF_LONG:
316 for (size_t i = 0; i < entry->count; i++)
317 entry->value.uint[i] = ff_tget_long(gb, le);
318 break;
319 case AV_TIFF_SSHORT:
320 for (size_t i = 0; i < entry->count; i++)
321 entry->value.sint[i] = (int16_t) ff_tget_short(gb, le);
322 break;
323 case AV_TIFF_SLONG:
324 for (size_t i = 0; i < entry->count; i++)
325 entry->value.sint[i] = (int32_t) ff_tget_long(gb, le);
326 break;
327 case AV_TIFF_DOUBLE:
328 for (size_t i = 0; i < entry->count; i++)
329 entry->value.dbl[i] = ff_tget_double(gb, le);
330 break;
331 case AV_TIFF_FLOAT:
332 for (size_t i = 0; i < entry->count; i++) {
333 av_alias32 alias = { .u32 = ff_tget_long(gb, le) };
334 entry->value.dbl[i] = alias.f32;
335 }
336 break;
337 case AV_TIFF_RATIONAL:
339 for (size_t i = 0; i < entry->count; i++) {
340 int32_t num = ff_tget_long(gb, le);
341 int32_t den = ff_tget_long(gb, le);
342 entry->value.rat[i] = av_make_q(num, den);
343 }
344 break;
346 case AV_TIFF_BYTE:
347 /* these three fields are aliased to entry->value.ptr via a union */
348 /* and entry->value.ptr will always be nonzero here */
349 av_assert0(entry->value.ubytes);
350 bytestream2_get_buffer(gb, entry->value.ubytes, entry->count);
351 break;
352 case AV_TIFF_SBYTE:
353 av_assert0(entry->value.sbytes);
354 bytestream2_get_buffer(gb, entry->value.sbytes, entry->count);
355 break;
356 case AV_TIFF_STRING:
357 av_assert0(entry->value.str);
358 bytestream2_get_buffer(gb, entry->value.str, entry->count);
359 break;
360 }
361
362 return 0;
363}
364
365static void exif_write_values(PutByteContext *pb, int le, const AVExifEntry *entry)
366{
367 switch (entry->type) {
368 case AV_TIFF_SHORT:
369 for (size_t i = 0; i < entry->count; i++)
370 tput16(pb, le, entry->value.uint[i]);
371 break;
372 case AV_TIFF_LONG:
373 for (size_t i = 0; i < entry->count; i++)
374 tput32(pb, le, entry->value.uint[i]);
375 break;
376 case AV_TIFF_SSHORT:
377 for (size_t i = 0; i < entry->count; i++)
378 tput16(pb, le, entry->value.sint[i]);
379 break;
380 case AV_TIFF_SLONG:
381 for (size_t i = 0; i < entry->count; i++)
382 tput32(pb, le, entry->value.sint[i]);
383 break;
384 case AV_TIFF_DOUBLE:
385 for (size_t i = 0; i < entry->count; i++) {
386 const av_alias64 a = { .f64 = entry->value.dbl[i] };
387 tput64(pb, le, a.u64);
388 }
389 break;
390 case AV_TIFF_FLOAT:
391 for (size_t i = 0; i < entry->count; i++) {
392 const av_alias32 a = { .f32 = entry->value.dbl[i] };
393 tput32(pb, le, a.u32);
394 }
395 break;
396 case AV_TIFF_RATIONAL:
398 for (size_t i = 0; i < entry->count; i++) {
399 tput32(pb, le, entry->value.rat[i].num);
400 tput32(pb, le, entry->value.rat[i].den);
401 }
402 break;
404 case AV_TIFF_BYTE:
405 bytestream2_put_buffer(pb, entry->value.ubytes, entry->count);
406 break;
407 case AV_TIFF_SBYTE:
408 bytestream2_put_buffer(pb, entry->value.sbytes, entry->count);
409 break;
410 case AV_TIFF_STRING:
411 bytestream2_put_buffer(pb, entry->value.str, entry->count);
412 break;
413 }
414}
415
416static const uint8_t aoc_header[] = { 'A', 'O', 'C', 0, };
417static const uint8_t casio_header[] = { 'Q', 'V', 'C', 0, 0, 0, };
418static const uint8_t foveon_header[] = { 'F', 'O', 'V', 'E', 'O', 'N', 0, 0, };
419static const uint8_t fuji_header[] = { 'F', 'U', 'J', 'I', };
420static const uint8_t nikon_header[] = { 'N', 'i', 'k', 'o', 'n', 0, };
421static const uint8_t olympus1_header[] = { 'O', 'L', 'Y', 'M', 'P', 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, };
426
428 const uint8_t *header;
431};
432
433#define MAKERNOTE_STRUCT(h, r) { \
434 .header = (h), \
435 .header_size = sizeof((h)), \
436 .result = (r), \
437}
438
450
451/*
452 * derived from Exiv2 MakerNote's article
453 * https://exiv2.org/makernote.html or archived at
454 * https://web.archive.org/web/20250311155857/https://exiv2.org/makernote.html
455 */
457{
459 return -1;
460
461 for (int i = 0; i < FF_ARRAY_ELEMS(makernote_data); i++) {
462 if (!memcmp(gb->buffer, makernote_data[i].header, makernote_data[i].header_size))
463 return makernote_data[i].result;
464 }
465
466 if (!memcmp(gb->buffer, nikon_header, sizeof(nikon_header))) {
467 if (bytestream2_get_bytes_left(gb) < 14)
468 return -1;
469 else if (AV_RB32(gb->buffer + 10) == EXIF_MM_LONG || AV_RB32(gb->buffer + 10) == EXIF_II_LONG)
470 return -1;
471 return 8;
472 }
473
474 return 0;
475}
476
477static int exif_parse_ifd_list(void *logctx, GetByteContext *gb, int le,
478 int depth, AVExifMetadata *ifd, int guess);
479
480static int exif_decode_tag(void *logctx, GetByteContext *gb, int le,
481 int depth, AVExifEntry *entry)
482{
483 int ret = 0, makernote_offset = -1, tell, is_ifd, count;
484 enum AVTiffDataType type;
485 uint32_t payload;
486
487 /* safety check to prevent infinite recursion on malicious IFDs */
488 if (depth > 3)
489 return AVERROR_INVALIDDATA;
490
492
493 entry->id = ff_tget_short(gb, le);
494 type = ff_tget_short(gb, le);
495 count = ff_tget_long(gb, le);
496 payload = ff_tget_long(gb, le);
497
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);
500
501 if (!type) {
502 av_log(logctx, AV_LOG_DEBUG, "Skipping invalid TIFF tag 0\n");
503 goto end;
504 }
505
506 /* AV_TIFF_IFD is the largest, numerically */
507 if (type > AV_TIFF_IFD || count >= INT_MAX/8U)
508 return AVERROR_INVALIDDATA;
509
510 is_ifd = type == AV_TIFF_IFD || ff_tis_ifd(entry->id) || entry->id == MAKERNOTE_TAG;
511
512 if (is_ifd) {
513 if (!payload)
514 goto end;
515 bytestream2_seek(gb, payload, SEEK_SET);
516 }
517
518 if (entry->id == MAKERNOTE_TAG) {
519 makernote_offset = exif_get_makernote_offset(gb);
520 if (makernote_offset < 0)
521 is_ifd = 0;
522 }
523
524 if (is_ifd) {
525 entry->type = AV_TIFF_IFD;
526 entry->count = 1;
527 entry->ifd_offset = makernote_offset > 0 ? makernote_offset : 0;
528 if (entry->ifd_offset) {
529 entry->ifd_lead = av_malloc(entry->ifd_offset);
530 if (!entry->ifd_lead)
531 return AVERROR(ENOMEM);
532 bytestream2_get_buffer(gb, entry->ifd_lead, entry->ifd_offset);
533 }
534 ret = exif_parse_ifd_list(logctx, gb, le, depth + 1, &entry->value.ifd, entry->id == MAKERNOTE_TAG);
535 if (ret < 0 && entry->id == MAKERNOTE_TAG) {
536 /*
537 * we guessed that MakerNote was an IFD
538 * but we were probably incorrect at this
539 * point so we try again as a binary blob
540 */
541 av_log(logctx, AV_LOG_DEBUG, "unrecognized MakerNote IFD, retrying as blob\n");
542 is_ifd = 0;
543 }
544 }
545
546 /* inverted condition instead of else so we can fall through from above */
547 if (!is_ifd) {
549 entry->count = count;
550 bytestream2_seek(gb, count * exif_sizes[type] > 4 ? payload : tell + 8, SEEK_SET);
551 ret = exif_read_values(logctx, gb, le, entry);
552 }
553
554end:
555 bytestream2_seek(gb, tell + BASE_TAG_SIZE, SEEK_SET);
556
557 return ret;
558}
559
560static int exif_parse_ifd_list(void *logctx, GetByteContext *gb, int le,
561 int depth, AVExifMetadata *ifd, int guess)
562{
563 uint32_t entries;
564 size_t required_size;
565 void *temp;
566 int ret = 0;
567
568 av_log(logctx, AV_LOG_DEBUG, "parsing IFD list at offset: %d\n", bytestream2_tell(gb));
569
570 if (bytestream2_get_bytes_left(gb) < 2) {
571 av_log(logctx, guess ? AV_LOG_DEBUG : AV_LOG_ERROR,
572 "not enough bytes remaining in EXIF buffer: 2 required\n");
574 goto end;
575 }
576
577 entries = ff_tget_short(gb, le);
578 if (bytestream2_get_bytes_left(gb) < entries * BASE_TAG_SIZE) {
579 av_log(logctx, guess ? AV_LOG_DEBUG : AV_LOG_ERROR,
580 "not enough bytes remaining in EXIF buffer. entries: %" PRIu32 "\n", entries);
582 goto end;
583 }
584 if (entries > 4096) {
585 /* that is a lot of entries, probably an error */
586 av_log(logctx, guess ? AV_LOG_DEBUG : AV_LOG_ERROR,
587 "too many entries: %" PRIu32 "\n", entries);
589 goto end;
590 }
591
592 ifd->count = entries;
593 av_log(logctx, AV_LOG_DEBUG, "entry count for IFD: %u\n", ifd->count);
594
595 /* empty IFD is technically legal but equivalent to no metadata present */
596 if (!ifd->count) {
597 ret = 0;
598 goto end;
599 }
600
601 if (av_size_mult(ifd->count, sizeof(*ifd->entries), &required_size) < 0) {
602 ret = AVERROR(ENOMEM);
603 goto end;
604 }
605 temp = av_fast_realloc(ifd->entries, &ifd->size, required_size);
606 if (!temp) {
607 av_freep(&ifd->entries);
608 ret = AVERROR(ENOMEM);
609 goto end;
610 }
611 ifd->entries = temp;
612
613 /* entries have pointers in them which can cause issues if */
614 /* they are freed or realloc'd when garbage */
615 memset(ifd->entries, 0, required_size);
616
617 for (uint32_t i = 0; i < entries; i++) {
618 ret = exif_decode_tag(logctx, gb, le, depth, &ifd->entries[i]);
619 if (ret < 0)
620 goto end;
621 }
622
623end:
624 if (ret < 0) {
625 av_exif_free(ifd);
626 return ret;
627 }
628 /*
629 * at the end of an IFD is an pointer to the next IFD
630 * or zero if there are no more IFDs, which is usually the case
631 */
632 ret = ff_tget_long(gb, le);
633
634 /* overflow */
635 if (ret < 0) {
637 av_exif_free(ifd);
638 }
639
640 return ret;
641}
642
643/*
644 * note that this function does not free the entry pointer itself
645 * because it's probably part of a larger array that should be freed
646 * all at once
647 */
649{
650 if (!entry)
651 return;
652 if (entry->type == AV_TIFF_IFD)
653 av_exif_free(&entry->value.ifd);
654 else
655 av_freep(&entry->value.ptr);
656 av_freep(&entry->ifd_lead);
657}
658
660{
661 if (!ifd)
662 return;
663 if (!ifd->entries) {
664 ifd->count = 0;
665 ifd->size = 0;
666 return;
667 }
668 for (size_t i = 0; i < ifd->count; i++) {
669 AVExifEntry *entry = &ifd->entries[i];
671 }
672 av_freep(&ifd->entries);
673 ifd->count = 0;
674 ifd->size = 0;
675}
676
677static size_t exif_get_ifd_size(const AVExifMetadata *ifd)
678{
679 /* 6 == 4 + 2; 2-byte entry-count at the beginning */
680 /* plus 4-byte next-IFD pointer at the end */
681 size_t total_size = IFD_EXTRA_SIZE;
682 for (size_t i = 0; i < ifd->count; i++) {
683 const AVExifEntry *entry = &ifd->entries[i];
684 if (entry->type == AV_TIFF_IFD) {
685 total_size += BASE_TAG_SIZE + exif_get_ifd_size(&entry->value.ifd) + entry->ifd_offset;
686 } else {
687 size_t payload_size = entry->count * exif_sizes[entry->type];
688 total_size += BASE_TAG_SIZE + (payload_size > 4 ? payload_size : 0);
689 }
690 }
691 return total_size;
692}
693
694static int exif_write_ifd(void *logctx, PutByteContext *pb, int le, int depth, const AVExifMetadata *ifd)
695{
696 int offset, ret, tell, tell2;
698 tput16(pb, le, ifd->count);
699 offset = tell + IFD_EXTRA_SIZE + BASE_TAG_SIZE * (uint32_t) ifd->count;
700 av_log(logctx, AV_LOG_DEBUG, "writing IFD with %u entries and initial offset %d\n", ifd->count, offset);
701 for (size_t i = 0; i < ifd->count; i++) {
702 const AVExifEntry *entry = &ifd->entries[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",
705 entry->id, entry->type, entry->count,
707 tput16(pb, le, entry->id);
708 if (entry->id == MAKERNOTE_TAG && entry->type == AV_TIFF_IFD) {
709 size_t ifd_size = exif_get_ifd_size(&entry->value.ifd);
710 tput16(pb, le, AV_TIFF_UNDEFINED);
711 tput32(pb, le, ifd_size);
712 } else {
713 tput16(pb, le, entry->type);
714 tput32(pb, le, entry->count);
715 }
716 if (entry->type == AV_TIFF_IFD) {
717 tput32(pb, le, offset);
718 tell2 = bytestream2_tell_p(pb);
719 bytestream2_seek_p(pb, offset, SEEK_SET);
720 if (entry->ifd_offset)
721 bytestream2_put_buffer(pb, entry->ifd_lead, entry->ifd_offset);
722 ret = exif_write_ifd(logctx, pb, le, depth + 1, &entry->value.ifd);
723 if (ret < 0)
724 return ret;
725 offset += ret + entry->ifd_offset;
726 bytestream2_seek_p(pb, tell2, SEEK_SET);
727 } else {
728 size_t payload_size = entry->count * exif_sizes[entry->type];
729 if (payload_size > 4) {
730 tput32(pb, le, offset);
731 tell2 = bytestream2_tell_p(pb);
732 bytestream2_seek_p(pb, offset, SEEK_SET);
733 exif_write_values(pb, le, entry);
734 offset += payload_size;
735 bytestream2_seek_p(pb, tell2, SEEK_SET);
736 } else {
737 /* zero uninitialized excess payload values */
738 AV_WN32(pb->buffer, 0);
739 exif_write_values(pb, le, entry);
740 bytestream2_seek_p(pb, 4 - payload_size, SEEK_CUR);
741 }
742 }
743 }
744
745 /*
746 * we write 0 if this is the top-level exif IFD
747 * indicating that there are no more IFD pointers
748 */
749 tput32(pb, le, depth ? offset : 0);
750 return offset - tell;
751}
752
753int av_exif_write(void *logctx, const AVExifMetadata *ifd, AVBufferRef **buffer, enum AVExifHeaderMode header_mode)
754{
755 AVBufferRef *buf = NULL;
756 size_t size, headsize = 8;
758 int ret = 0, off = 0, next;
759 AVExifMetadata *ifd_new = NULL;
760 AVExifMetadata extra_ifds[16] = { 0 };
761
762 int le = 1;
763
764 if (*buffer) {
765 ret = AVERROR(EINVAL);
766 goto end;
767 }
768
769 size = exif_get_ifd_size(ifd);
770 switch (header_mode) {
771 case AV_EXIF_EXIF00:
772 off = 6;
773 break;
774 case AV_EXIF_T_OFF:
775 off = 4;
776 break;
778 le = 0;
779 headsize = 0;
780 break;
782 le = 1;
783 headsize = 0;
784 break;
785 }
786
787 ret = av_buffer_realloc(&buf, size + off + headsize);
788 if (ret < 0)
789 goto end;
790
791 if (header_mode == AV_EXIF_EXIF00) {
792 AV_WL32(buf->data, MKTAG('E','x','i','f'));
793 AV_WN16(buf->data + 4, 0);
794 } else if (header_mode == AV_EXIF_T_OFF) {
795 AV_WN32(buf->data, 0);
796 }
797
798 bytestream2_init_writer(&pb, buf->data + off, buf->size - off);
799
800 if (header_mode != AV_EXIF_ASSUME_BE && header_mode != AV_EXIF_ASSUME_LE) {
801 /* these constants are be32 in both cases */
802 /* le == 1 always in this case */
803 bytestream2_put_be32(&pb, EXIF_II_LONG);
804 tput32(&pb, le, 8);
805 }
806
807 int extras = 0;
808 for (int i = 0; i < FF_ARRAY_ELEMS(extra_ifds); i++) {
809 AVExifEntry *extra_entry = NULL;
810 uint16_t extra_tag = 0xFFFCu - i;
811 ret = av_exif_get_entry(logctx, (AVExifMetadata *) ifd, extra_tag, 0, &extra_entry);
812 if (ret < 0)
813 break;
814 if (!ret)
815 continue;
816 av_log(logctx, AV_LOG_DEBUG, "found extra IFD tag: %04x\n", extra_tag);
817 if (!ifd_new) {
818 ifd_new = av_exif_clone_ifd(ifd);
819 if (!ifd_new)
820 break;
821 ifd = ifd_new;
822 }
823 /* calling remove_entry will call av_exif_free on the original */
824 AVExifMetadata *cloned = av_exif_clone_ifd(&extra_entry->value.ifd);
825 if (!cloned)
826 break;
827 extra_ifds[extras++] = *cloned;
828 /* don't use av_exif_free here, we want to preserve internals */
829 av_free(cloned);
830 ret = av_exif_remove_entry(logctx, ifd_new, extra_tag, 0);
831 if (ret < 0)
832 break;
833 }
834
835 if (ret < 0) {
836 av_log(logctx, AV_LOG_ERROR, "error popping additional IFD: %s\n", av_err2str(ret));
837 goto end;
838 }
839
840 next = bytestream2_tell_p(&pb);
841 ret = exif_write_ifd(logctx, &pb, le, 0, ifd);
842 if (ret < 0) {
843 av_log(logctx, AV_LOG_ERROR, "error writing EXIF data: %s\n", av_err2str(ret));
844 goto end;
845 }
846 next += ret;
847
848 for (int i = 0; i < extras; i++) {
849 av_log(logctx, AV_LOG_DEBUG, "writing additional ifd at: %d\n", next);
850 /* exif_write_ifd always writes 0 i.e. last ifd so we overwrite that here */
851 bytestream2_seek_p(&pb, -4, SEEK_CUR);
852 tput32(&pb, le, next);
853 bytestream2_seek_p(&pb, next, SEEK_SET);
854 ret = exif_write_ifd(logctx, &pb, le, 0, &extra_ifds[i]);
855 if (ret < 0) {
856 av_log(logctx, AV_LOG_ERROR, "error writing additional IFD: %s\n", av_err2str(ret));
857 goto end;
858 }
859 next += ret;
860 }
861
862 /* shrink the buffer to the amount of data we actually used */
863 /* extras don't contribute the initial BASE_TAG_SIZE each */
864 ret = av_buffer_realloc(&buf, buf->size - BASE_TAG_SIZE * extras);
865 if (ret < 0)
866 goto end;
867
868 *buffer = buf;
869 ret = 0;
870
871end:
872 av_exif_free(ifd_new);
873 av_freep(&ifd_new);
874 for (int i = 0; i < FF_ARRAY_ELEMS(extra_ifds); i++)
875 av_exif_free(&extra_ifds[i]);
876 if (ret < 0)
877 av_buffer_unref(&buf);
878
879 return ret;
880}
881
882int av_exif_parse_buffer(void *logctx, const uint8_t *buf, size_t size,
883 AVExifMetadata *ifd, enum AVExifHeaderMode header_mode)
884{
885 int ret, le;
886 GetByteContext gbytes;
887 if (size > INT_MAX)
888 return AVERROR(EINVAL);
889 size_t off = 0;
890 switch (header_mode) {
891 case AV_EXIF_EXIF00:
892 if (size < 6)
893 return AVERROR_INVALIDDATA;
894 off = 6;
896 case AV_EXIF_T_OFF:
897 if (size < 4)
898 return AVERROR_INVALIDDATA;
899 if (!off)
900 off = AV_RB32(buf) + 4;
902 case AV_EXIF_TIFF_HEADER: {
903 int ifd_offset;
904 if (size <= off)
905 return AVERROR_INVALIDDATA;
906 bytestream2_init(&gbytes, buf + off, size - off);
907 // read TIFF header
908 ret = ff_tdecode_header(&gbytes, &le, &ifd_offset);
909 if (ret < 0) {
910 av_log(logctx, AV_LOG_ERROR, "invalid TIFF header in EXIF data: %s\n", av_err2str(ret));
911 return ret;
912 }
913 bytestream2_seek(&gbytes, ifd_offset, SEEK_SET);
914 break;
915 }
917 le = 1;
918 bytestream2_init(&gbytes, buf, size);
919 break;
921 le = 0;
922 bytestream2_init(&gbytes, buf, size);
923 break;
924 default:
925 return AVERROR(EINVAL);
926 }
927
928 /*
929 * parse IFD0 here. If the return value is positive that tells us
930 * there is subimage metadata, but we don't parse that IFD here
931 */
932 ret = exif_parse_ifd_list(logctx, &gbytes, le, 0, ifd, 0);
933 if (ret < 0) {
934 av_log(logctx, AV_LOG_ERROR, "error decoding EXIF data: %s\n", av_err2str(ret));
935 return ret;
936 }
937 if (!ret)
938 goto finish;
939 int next = ret;
940 bytestream2_seek(&gbytes, next, SEEK_SET);
941
942 /* cap at 16 extra IFDs for sanity/parse security */
943 for (int extra_tag = 0xFFFCu; extra_tag > 0xFFECu; extra_tag--) {
944 AVExifMetadata extra_ifd = { 0 };
945 ret = exif_parse_ifd_list(logctx, &gbytes, le, 0, &extra_ifd, 1);
946 if (ret < 0) {
947 av_exif_free(&extra_ifd);
948 break;
949 }
950 next = ret;
951 av_log(logctx, AV_LOG_DEBUG, "found extra IFD: %04x with next=%d\n", extra_tag, ret);
952 bytestream2_seek(&gbytes, next, SEEK_SET);
953 ret = av_exif_set_entry(logctx, ifd, extra_tag, AV_TIFF_IFD, 1, NULL, 0, &extra_ifd);
954 av_exif_free(&extra_ifd);
955 if (ret < 0 || !next || bytestream2_get_bytes_left(&gbytes) <= 0)
956 break;
957 }
958
959finish:
960 return bytestream2_tell(&gbytes) + off;
961}
962
963#define COLUMN_SEP(i, c) ((i) ? ((i) % (c) ? ", " : "\n") : "")
964
965static int exif_ifd_to_dict(void *logctx, const char *prefix, const AVExifMetadata *ifd, AVDictionary **metadata)
966{
967 AVBPrint bp;
968 int ret = 0;
969 char *key = NULL;
970 char *value = NULL;
971
972 if (!prefix)
973 prefix = "";
974
975 for (uint16_t i = 0; i < ifd->count; i++) {
976 const AVExifEntry *entry = &ifd->entries[i];
977 const char *name = av_exif_get_tag_name(entry->id);
979 if (*prefix)
980 av_bprintf(&bp, "%s/", prefix);
981 if (name)
982 av_bprintf(&bp, "%s", name);
983 else
984 av_bprintf(&bp, "0x%04X", entry->id);
985 ret = av_bprint_finalize(&bp, &key);
986 if (ret < 0)
987 goto end;
989 switch (entry->type) {
990 case AV_TIFF_IFD:
991 ret = exif_ifd_to_dict(logctx, key, &entry->value.ifd, metadata);
992 if (ret < 0)
993 goto end;
994 break;
995 case AV_TIFF_SHORT:
996 case AV_TIFF_LONG:
997 for (uint32_t j = 0; j < entry->count; j++)
998 av_bprintf(&bp, "%s%7" PRIu32, COLUMN_SEP(j, 8), (uint32_t)entry->value.uint[j]);
999 break;
1000 case AV_TIFF_SSHORT:
1001 case AV_TIFF_SLONG:
1002 for (uint32_t j = 0; j < entry->count; j++)
1003 av_bprintf(&bp, "%s%7" PRId32, COLUMN_SEP(j, 8), (int32_t)entry->value.sint[j]);
1004 break;
1005 case AV_TIFF_RATIONAL:
1006 case AV_TIFF_SRATIONAL:
1007 for (uint32_t j = 0; j < entry->count; j++)
1008 av_bprintf(&bp, "%s%7i:%-7i", COLUMN_SEP(j, 4), entry->value.rat[j].num, entry->value.rat[j].den);
1009 break;
1010 case AV_TIFF_DOUBLE:
1011 case AV_TIFF_FLOAT:
1012 for (uint32_t j = 0; j < entry->count; j++)
1013 av_bprintf(&bp, "%s%.15g", COLUMN_SEP(j, 4), entry->value.dbl[j]);
1014 break;
1015 case AV_TIFF_STRING:
1016 av_bprintf(&bp, "%s", entry->value.str);
1017 break;
1018 case AV_TIFF_UNDEFINED:
1019 case AV_TIFF_BYTE:
1020 for (uint32_t j = 0; j < entry->count; j++)
1021 av_bprintf(&bp, "%s%3i", COLUMN_SEP(j, 16), entry->value.ubytes[j]);
1022 break;
1023 case AV_TIFF_SBYTE:
1024 for (uint32_t j = 0; j < entry->count; j++)
1025 av_bprintf(&bp, "%s%3i", COLUMN_SEP(j, 16), entry->value.sbytes[j]);
1026 break;
1027 }
1028 if (entry->type != AV_TIFF_IFD) {
1029 if (!av_bprint_is_complete(&bp)) {
1031 ret = AVERROR(ENOMEM);
1032 goto end;
1033 }
1034 ret = av_bprint_finalize(&bp, &value);
1035 if (ret < 0)
1036 goto end;
1038 key = NULL;
1039 value = NULL;
1040 if (ret < 0)
1041 goto end;
1042 } else {
1043 av_freep(&key);
1044 }
1045 }
1046
1047end:
1048 av_freep(&key);
1049 av_freep(&value);
1050 return ret;
1051}
1052
1054{
1055 return exif_ifd_to_dict(logctx, "", ifd, metadata);
1056}
1057
1058#define EXIF_COPY(fname, srcname) do { \
1059 size_t sz; \
1060 if (av_size_mult(src->count, sizeof(*(fname)), &sz) < 0) { \
1061 ret = AVERROR(ENOMEM); \
1062 goto end; \
1063 } \
1064 (fname) = av_memdup((srcname), sz); \
1065 if (!(fname)) { \
1066 ret = AVERROR(ENOMEM); \
1067 goto end; \
1068 } \
1069} while (0)
1070
1072{
1073 int ret = 0;
1074
1075 memset(dst, 0, sizeof(*dst));
1076
1077 dst->count = src->count;
1078 dst->id = src->id;
1079 dst->type = src->type;
1080
1081 dst->ifd_offset = src->ifd_offset;
1082 if (src->ifd_lead) {
1083 dst->ifd_lead = av_memdup(src->ifd_lead, src->ifd_offset);
1084 if (!dst->ifd_lead) {
1085 ret = AVERROR(ENOMEM);
1086 goto end;
1087 }
1088 } else {
1089 dst->ifd_lead = NULL;
1090 }
1091
1092 switch(src->type) {
1093 case AV_TIFF_IFD: {
1094 AVExifMetadata *cloned = av_exif_clone_ifd(&src->value.ifd);
1095 if (!cloned) {
1096 ret = AVERROR(ENOMEM);
1097 goto end;
1098 }
1099 dst->value.ifd = *cloned;
1100 av_freep(&cloned);
1101 break;
1102 }
1103 case AV_TIFF_SHORT:
1104 case AV_TIFF_LONG:
1105 EXIF_COPY(dst->value.uint, src->value.uint);
1106 break;
1107 case AV_TIFF_SLONG:
1108 case AV_TIFF_SSHORT:
1109 EXIF_COPY(dst->value.sint, src->value.sint);
1110 break;
1111 case AV_TIFF_RATIONAL:
1112 case AV_TIFF_SRATIONAL:
1113 EXIF_COPY(dst->value.rat, src->value.rat);
1114 break;
1115 case AV_TIFF_DOUBLE:
1116 case AV_TIFF_FLOAT:
1117 EXIF_COPY(dst->value.dbl, src->value.dbl);
1118 break;
1119 case AV_TIFF_BYTE:
1120 case AV_TIFF_UNDEFINED:
1121 EXIF_COPY(dst->value.ubytes, src->value.ubytes);
1122 break;
1123 case AV_TIFF_SBYTE:
1124 EXIF_COPY(dst->value.sbytes, src->value.sbytes);
1125 break;
1126 case AV_TIFF_STRING:
1127 dst->value.str = av_memdup(src->value.str, src->count+1);
1128 if (!dst->value.str) {
1129 ret = AVERROR(ENOMEM);
1130 goto end;
1131 }
1132 break;
1133 }
1134
1135 return 0;
1136
1137end:
1138 av_freep(&dst->ifd_lead);
1139 if (src->type == AV_TIFF_IFD)
1140 av_exif_free(&dst->value.ifd);
1141 else
1142 av_freep(&dst->value.ptr);
1143 memset(dst, 0, sizeof(*dst));
1144
1145 return ret;
1146}
1147
1148static int exif_get_entry(void *logctx, AVExifMetadata *ifd, uint16_t id, int depth, AVExifEntry **value)
1149{
1150 int offset = 1;
1151
1152 if (!ifd || ifd->count && !ifd->entries || !value)
1153 return AVERROR(EINVAL);
1154
1155 for (size_t i = 0; i < ifd->count; i++) {
1156 if (ifd->entries[i].id == id) {
1157 *value = &ifd->entries[i];
1158 return i + offset;
1159 }
1160 if (ifd->entries[i].type == AV_TIFF_IFD) {
1161 if (depth < 3) {
1162 int ret = exif_get_entry(logctx, &ifd->entries[i].value.ifd, id, depth + 1, value);
1163 if (ret)
1164 return ret < 0 ? ret : ret + offset;
1165 }
1166 offset += ifd->entries[i].value.ifd.count;
1167 }
1168 }
1169
1170 return 0;
1171}
1172
1173int av_exif_get_entry(void *logctx, AVExifMetadata *ifd, uint16_t id, int flags, AVExifEntry **value)
1174{
1175 return exif_get_entry(logctx, ifd, id, (flags & AV_EXIF_FLAG_RECURSIVE) ? 0 : INT_MAX, value);
1176}
1177
1178int av_exif_set_entry(void *logctx, AVExifMetadata *ifd, uint16_t id, enum AVTiffDataType type,
1179 uint32_t count, const uint8_t *ifd_lead, uint32_t ifd_offset, const void *value)
1180{
1181 void *temp;
1182 int ret, offset;
1184 AVExifEntry src = { 0 };
1185
1186 if (!ifd || ifd->count && !ifd->entries
1187 || ifd_lead && !ifd_offset || !ifd_lead && ifd_offset
1188 || !value || ifd->count == 0xFFFFu)
1189 return AVERROR(EINVAL);
1190
1191 ret = av_exif_get_entry(logctx, ifd, id, 0, &entry);
1192 if (ret < 0)
1193 return ret;
1194 offset = ret;
1195
1196 if (entry) {
1198 } else {
1199 size_t required_size;
1200 ret = av_size_mult(ifd->count + 1, sizeof(*ifd->entries), &required_size);
1201 if (ret < 0)
1202 return AVERROR(ENOMEM);
1203 temp = av_fast_realloc(ifd->entries, &ifd->size, required_size);
1204 if (!temp)
1205 return AVERROR(ENOMEM);
1206 ifd->entries = temp;
1207 entry = &ifd->entries[ifd->count++];
1208 }
1209
1210 src.count = count;
1211 src.id = id;
1212 src.type = type;
1213 src.ifd_lead = (uint8_t *) ifd_lead;
1214 src.ifd_offset = ifd_offset;
1215 if (type == AV_TIFF_IFD)
1216 src.value.ifd = * (const AVExifMetadata *) value;
1217 else
1218 src.value.ptr = (void *) value;
1219
1220 ret = exif_clone_entry(entry, &src);
1221
1222 if (ret < 0) {
1223 /* offset is the actual offset + 1 */
1224 if (offset) {
1225 size_t remaining = ifd->count - offset;
1226 /* pop the entry off the IFD by shifting everything to the left */
1227 memmove(&ifd->entries[offset - 1], &ifd->entries[offset], sizeof(*ifd->entries) * remaining);
1228 }
1229 ifd->count--;
1230 }
1231
1232 return ret;
1233}
1234
1235static int exif_remove_entry(void *logctx, AVExifMetadata *ifd, uint16_t id, int depth)
1236{
1237 int32_t index = -1;
1238 int ret = 0;
1239
1240 if (!ifd || ifd->count && !ifd->entries)
1241 return AVERROR(EINVAL);
1242
1243 for (size_t i = 0; i < ifd->count; i++) {
1244 if (ifd->entries[i].id == id) {
1245 index = i;
1246 break;
1247 }
1248 if (ifd->entries[i].type == AV_TIFF_IFD && depth < 3) {
1249 ret = exif_remove_entry(logctx, &ifd->entries[i].value.ifd, id, depth + 1);
1250 if (ret)
1251 return ret;
1252 }
1253 }
1254
1255 if (index < 0)
1256 return 0;
1258
1259 if (index == --ifd->count) {
1260 if (!index) {
1261 av_freep(&ifd->entries);
1262 ifd->size = 0;
1263 }
1264 return 1;
1265 }
1266
1267 memmove(&ifd->entries[index], &ifd->entries[index + 1], (ifd->count - index) * sizeof(*ifd->entries));
1268
1269 return 1 + (ifd->count - index);
1270}
1271
1272int av_exif_remove_entry(void *logctx, AVExifMetadata *ifd, uint16_t id, int flags)
1273{
1274 return exif_remove_entry(logctx, ifd, id, (flags & AV_EXIF_FLAG_RECURSIVE) ? 0 : INT_MAX);
1275}
1276
1278{
1279 AVExifMetadata *ret = av_mallocz(sizeof(*ret));
1280 if (!ret)
1281 return NULL;
1282
1283 ret->count = ifd->count;
1284 if (ret->count) {
1285 size_t required_size;
1286 if (av_size_mult(ret->count, sizeof(*ret->entries), &required_size) < 0)
1287 goto fail;
1288 av_fast_mallocz(&ret->entries, &ret->size, required_size);
1289 if (!ret->entries)
1290 goto fail;
1291 }
1292
1293 for (size_t i = 0; i < ret->count; i++) {
1294 const AVExifEntry *entry = &ifd->entries[i];
1295 AVExifEntry *ret_entry = &ret->entries[i];
1296 int status = exif_clone_entry(ret_entry, entry);
1297 if (status < 0)
1298 goto fail;
1299 }
1300
1301 return ret;
1302
1303fail:
1304 av_exif_free(ret);
1305 av_free(ret);
1306 return NULL;
1307}
1308
1309static const int rotation_lut[2][4] = {
1310 {1, 8, 3, 6}, {4, 7, 2, 5},
1311};
1312
1314{
1315 double rotation = av_display_rotation_get(matrix);
1316 // determinant
1317 int vflip = ((int64_t)matrix[0] * (int64_t)matrix[4]
1318 - (int64_t)matrix[1] * (int64_t)matrix[3]) < 0;
1319 if (!isfinite(rotation))
1320 return 0;
1321 int rot = (int)(rotation + 0.5);
1322 rot = (((rot % 360) + 360) % 360) / 90;
1323 return rotation_lut[vflip][rot];
1324}
1325
1327{
1328 switch (orientation) {
1329 case 1:
1331 break;
1332 case 2:
1335 break;
1336 case 3:
1338 break;
1339 case 4:
1342 break;
1343 case 5:
1346 break;
1347 case 6:
1349 break;
1350 case 7:
1353 break;
1354 case 8:
1356 break;
1357 default:
1358 return AVERROR(EINVAL);
1359 }
1360
1361 return 0;
1362}
1363
1364int ff_exif_sanitize_ifd(void *logctx, const AVFrame *frame, AVExifMetadata *ifd)
1365{
1366 int ret = 0;
1367 AVFrameSideData *sd_orient = NULL;
1368 AVExifEntry *or = NULL;
1369 AVExifEntry *iw = NULL;
1370 AVExifEntry *ih = NULL;
1371 AVExifEntry *pw = NULL;
1372 AVExifEntry *ph = NULL;
1373 uint64_t orientation = 1;
1374 uint64_t w = frame->width;
1375 uint64_t h = frame->height;
1376 int rewrite = 0;
1377
1379
1380 if (sd_orient)
1381 orientation = av_exif_matrix_to_orientation((int32_t *) sd_orient->data);
1382 if (!orientation) {
1383 av_log(logctx, AV_LOG_WARNING, "display matrix is singular\n");
1384 orientation = 1;
1385 }
1386 if (orientation != 1)
1387 av_log(logctx, AV_LOG_DEBUG, "matrix contains nontrivial EXIF orientation: %" PRIu64 "\n", orientation);
1388
1389 for (size_t i = 0; i < ifd->count; i++) {
1390 AVExifEntry *entry = &ifd->entries[i];
1391 if (entry->id == ORIENTATION_TAG && entry->count > 0 && entry->type == AV_TIFF_SHORT) {
1392 or = entry;
1393 continue;
1394 }
1395 if (entry->id == IMAGE_WIDTH_TAG && entry->count > 0 && entry->type == AV_TIFF_LONG) {
1396 iw = entry;
1397 continue;
1398 }
1399 if (entry->id == IMAGE_LENGTH_TAG && entry->count > 0 && entry->type == AV_TIFF_LONG) {
1400 ih = entry;
1401 continue;
1402 }
1403 if (entry->id == EXIFIFD_TAG && entry->type == AV_TIFF_IFD) {
1404 AVExifMetadata *exif = &entry->value.ifd;
1405 for (size_t j = 0; j < exif->count; j++) {
1406 AVExifEntry *exifentry = &exif->entries[j];
1407 if (exifentry->id == PIXEL_X_TAG && exifentry->count > 0 && exifentry->type == AV_TIFF_SHORT) {
1408 pw = exifentry;
1409 continue;
1410 }
1411 if (exifentry->id == PIXEL_Y_TAG && exifentry->count > 0 && exifentry->type == AV_TIFF_SHORT) {
1412 ph = exifentry;
1413 continue;
1414 }
1415 }
1416 }
1417 }
1418
1419 if (or && or->value.uint[0] != orientation) {
1420 rewrite = 1;
1421 or->value.uint[0] = orientation;
1422 }
1423 if (iw && iw->value.uint[0] != w) {
1424 rewrite = 1;
1425 iw->value.uint[0] = w;
1426 }
1427 if (ih && ih->value.uint[0] != h) {
1428 rewrite = 1;
1429 ih->value.uint[0] = h;
1430 }
1431 if (pw && pw->value.uint[0] != w) {
1432 rewrite = 1;
1433 pw->value.uint[0] = w;
1434 }
1435 if (ph && ph->value.uint[0] != h) {
1436 rewrite = 1;
1437 ph->value.uint[0] = h;
1438 }
1439 if (!or && orientation != 1) {
1440 rewrite = 1;
1441 ret = av_exif_set_entry(logctx, ifd, ORIENTATION_TAG, AV_TIFF_SHORT, 1, NULL, 0, &orientation);
1442 if (ret < 0)
1443 goto end;
1444 }
1445 if (!iw && w) {
1446 rewrite = 1;
1447 ret = av_exif_set_entry(logctx, ifd, IMAGE_WIDTH_TAG, AV_TIFF_LONG, 1, NULL, 0, &w);
1448 if (ret < 0)
1449 goto end;
1450 }
1451 if (!ih && h) {
1452 rewrite = 1;
1453 ret = av_exif_set_entry(logctx, ifd, IMAGE_LENGTH_TAG, AV_TIFF_LONG, 1, NULL, 0, &h);
1454 if (ret < 0)
1455 goto end;
1456 }
1457 if (!pw && w && w <= 0xFFFFu || !ph && h && h <= 0xFFFFu) {
1458 AVExifMetadata *exif;
1459 AVExifEntry *exif_entry;
1460 int exif_found = av_exif_get_entry(logctx, ifd, EXIFIFD_TAG, 0, &exif_entry);
1461 rewrite = 1;
1462 if (exif_found < 0)
1463 goto end;
1464 if (exif_found > 0) {
1465 exif = &exif_entry->value.ifd;
1466 } else {
1467 AVExifMetadata exif_new = { 0 };
1468 ret = av_exif_set_entry(logctx, ifd, EXIFIFD_TAG, AV_TIFF_IFD, 1, NULL, 0, &exif_new);
1469 if (ret < 0) {
1470 av_exif_free(&exif_new);
1471 goto end;
1472 }
1473 exif = &ifd->entries[ifd->count - 1].value.ifd;
1474 }
1475 if (!pw && w && w <= 0xFFFFu) {
1476 ret = av_exif_set_entry(logctx, exif, PIXEL_X_TAG, AV_TIFF_SHORT, 1, NULL, 0, &w);
1477 if (ret < 0)
1478 goto end;
1479 }
1480 if (!ph && h && h <= 0xFFFFu) {
1481 ret = av_exif_set_entry(logctx, exif, PIXEL_Y_TAG, AV_TIFF_SHORT, 1, NULL, 0, &h);
1482 if (ret < 0)
1483 goto end;
1484 }
1485 }
1486
1487 return rewrite;
1488
1489end:
1490 return ret;
1491}
1492
1493int ff_exif_get_buffer(void *logctx, const AVFrame *frame, AVBufferRef **buffer_ptr, enum AVExifHeaderMode header_mode)
1494{
1495 AVFrameSideData *sd_exif = NULL;
1497 AVExifMetadata ifd = { 0 };
1498 int ret = 0;
1499 int rewrite = 0;
1500
1501 if (!buffer_ptr || *buffer_ptr)
1502 return AVERROR(EINVAL);
1503
1506 return 0;
1507
1508 if (sd_exif) {
1509 ret = av_exif_parse_buffer(logctx, sd_exif->data, sd_exif->size, &ifd, AV_EXIF_TIFF_HEADER);
1510 if (ret < 0)
1511 goto end;
1512 }
1513
1514 rewrite = ff_exif_sanitize_ifd(logctx, frame, &ifd);
1515 if (rewrite < 0) {
1516 ret = rewrite;
1517 goto end;
1518 }
1519
1520 /*
1521 * we always have to rewrite if the requested header mode
1522 * does not match the internal header mode, which is always
1523 * AV_EXIF_TIFF_HEADER inside FFmpeg.
1524 *
1525 * If ifd.count == 0 then there's no data to write at all.
1526 * This is possible if the frame width and height are zero and the orientation is 1.
1527 */
1528 rewrite = (rewrite || header_mode != AV_EXIF_TIFF_HEADER) && ifd.count;
1529
1530 if (rewrite) {
1531 ret = av_exif_write(logctx, &ifd, &buffer, header_mode);
1532 if (ret < 0)
1533 goto end;
1534
1535 *buffer_ptr = buffer;
1536 } else if (sd_exif) {
1537 *buffer_ptr = av_buffer_ref(sd_exif->buf);
1538 if (!*buffer_ptr) {
1539 ret = AVERROR(ENOMEM);
1540 goto end;
1541 }
1542 }
1543
1544 av_exif_free(&ifd);
1545
1546 return !!(rewrite || sd_exif);
1547
1548end:
1549 av_exif_free(&ifd);
1550 return ret;
1551}
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
Definition dsp.h:87
#define entry
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:424
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:1173
#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:365
static const struct exif_makernote_data makernote_data[]
Definition exif.c:439
static const uint8_t panasonic_header[]
Definition exif.c:423
static void tput16(PutByteContext *pb, const int le, const uint16_t value)
Definition exif.c:257
static void tput64(PutByteContext *pb, const int le, const uint64_t value)
Definition exif.c:267
static const uint8_t olympus2_header[]
Definition exif.c:422
static int exif_get_entry(void *logctx, AVExifMetadata *ifd, uint16_t id, int depth, AVExifEntry **value)
Definition exif.c:1148
static int exif_remove_entry(void *logctx, AVExifMetadata *ifd, uint16_t id, int depth)
Definition exif.c:1235
static int exif_clone_entry(AVExifEntry *dst, const AVExifEntry *src)
Definition exif.c:1071
static int exif_decode_tag(void *logctx, GetByteContext *gb, int le, int depth, AVExifEntry *entry)
Definition exif.c:480
static const struct exif_tag tag_list[]
Definition exif.c:63
static void exif_free_entry(AVExifEntry *entry)
Definition exif.c:648
static const uint8_t foveon_header[]
Definition exif.c:418
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:1178
#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:882
static size_t exif_get_ifd_size(const AVExifMetadata *ifd)
Definition exif.c:677
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:1053
void av_exif_free(AVExifMetadata *ifd)
Frees all resources associated with the given EXIF metadata struct.
Definition exif.c:659
static const uint8_t aoc_header[]
Definition exif.c:416
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:1313
static const uint8_t casio_header[]
Definition exif.c:417
#define PIXEL_X_TAG
Definition exif.c:55
static const uint8_t fuji_header[]
Definition exif.c:419
const char * av_exif_get_tag_name(uint16_t id)
Retrieves the tag name associated with the provided tag ID.
Definition exif.c:234
#define MAKERNOTE_STRUCT(h, r)
Definition exif.c:433
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:1326
static const uint8_t olympus1_header[]
Definition exif.c:421
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:1493
#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:1277
static const int rotation_lut[2][4]
Definition exif.c:1309
#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:965
static int exif_read_values(void *logctx, GetByteContext *gb, int le, AVExifEntry *entry)
Definition exif.c:272
#define EXIF_COPY(fname, srcname)
Definition exif.c:1058
#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:560
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:1364
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:753
#define COLUMN_SEP(i, c)
Definition exif.c:963
#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:694
int32_t av_exif_get_tag_id(const char *name)
Retrieves the tag ID associated with the provided tag string name.
Definition exif.c:244
static void tput32(PutByteContext *pb, const int le, const uint32_t value)
Definition exif.c:262
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:1272
#define EXIF_MM_LONG
Definition exif.c:44
static const uint8_t sony_header[]
Definition exif.c:425
static const size_t exif_sizes[]
Definition exif.c:217
static const uint8_t nikon_header[]
Definition exif.c:420
static int exif_get_makernote_offset(GetByteContext *gb)
Definition exif.c:456
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:429
const uint8_t * header
Definition exif.c:428
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 void finish(void)
Definition movenc.c:374
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