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