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 
50 struct exif_tag {
52  uint16_t id;
53 };
54 
55 static const struct exif_tag tag_list[] = { // JEITA CP-3451 EXIF specification:
56  {"GPSVersionID", 0x00}, // <- Table 12 GPS Attribute Information
57  {"GPSLatitudeRef", 0x01},
58  {"GPSLatitude", 0x02},
59  {"GPSLongitudeRef", 0x03},
60  {"GPSLongitude", 0x04},
61  {"GPSAltitudeRef", 0x05},
62  {"GPSAltitude", 0x06},
63  {"GPSTimeStamp", 0x07},
64  {"GPSSatellites", 0x08},
65  {"GPSStatus", 0x09},
66  {"GPSMeasureMode", 0x0A},
67  {"GPSDOP", 0x0B},
68  {"GPSSpeedRef", 0x0C},
69  {"GPSSpeed", 0x0D},
70  {"GPSTrackRef", 0x0E},
71  {"GPSTrack", 0x0F},
72  {"GPSImgDirectionRef", 0x10},
73  {"GPSImgDirection", 0x11},
74  {"GPSMapDatum", 0x12},
75  {"GPSDestLatitudeRef", 0x13},
76  {"GPSDestLatitude", 0x14},
77  {"GPSDestLongitudeRef", 0x15},
78  {"GPSDestLongitude", 0x16},
79  {"GPSDestBearingRef", 0x17},
80  {"GPSDestBearing", 0x18},
81  {"GPSDestDistanceRef", 0x19},
82  {"GPSDestDistance", 0x1A},
83  {"GPSProcessingMethod", 0x1B},
84  {"GPSAreaInformation", 0x1C},
85  {"GPSDateStamp", 0x1D},
86  {"GPSDifferential", 0x1E},
87  {"ImageWidth", 0x100}, // <- Table 3 TIFF Rev. 6.0 Attribute Information Used in Exif
88  {"ImageLength", 0x101},
89  {"BitsPerSample", 0x102},
90  {"Compression", 0x103},
91  {"PhotometricInterpretation", 0x106},
92  {"Orientation", 0x112},
93  {"SamplesPerPixel", 0x115},
94  {"PlanarConfiguration", 0x11C},
95  {"YCbCrSubSampling", 0x212},
96  {"YCbCrPositioning", 0x213},
97  {"XResolution", 0x11A},
98  {"YResolution", 0x11B},
99  {"ResolutionUnit", 0x128},
100  {"StripOffsets", 0x111},
101  {"RowsPerStrip", 0x116},
102  {"StripByteCounts", 0x117},
103  {"JPEGInterchangeFormat", 0x201},
104  {"JPEGInterchangeFormatLength",0x202},
105  {"TransferFunction", 0x12D},
106  {"WhitePoint", 0x13E},
107  {"PrimaryChromaticities", 0x13F},
108  {"YCbCrCoefficients", 0x211},
109  {"ReferenceBlackWhite", 0x214},
110  {"DateTime", 0x132},
111  {"ImageDescription", 0x10E},
112  {"Make", 0x10F},
113  {"Model", 0x110},
114  {"Software", 0x131},
115  {"Artist", 0x13B},
116  {"Copyright", 0x8298},
117  {"ExifVersion", 0x9000}, // <- Table 4 Exif IFD Attribute Information (1)
118  {"FlashpixVersion", 0xA000},
119  {"ColorSpace", 0xA001},
120  {"ComponentsConfiguration", 0x9101},
121  {"CompressedBitsPerPixel", 0x9102},
122  {"PixelXDimension", 0xA002},
123  {"PixelYDimension", 0xA003},
124  {"MakerNote", 0x927C},
125  {"UserComment", 0x9286},
126  {"RelatedSoundFile", 0xA004},
127  {"DateTimeOriginal", 0x9003},
128  {"DateTimeDigitized", 0x9004},
129  {"SubSecTime", 0x9290},
130  {"SubSecTimeOriginal", 0x9291},
131  {"SubSecTimeDigitized", 0x9292},
132  {"ImageUniqueID", 0xA420},
133  {"ExposureTime", 0x829A}, // <- Table 5 Exif IFD Attribute Information (2)
134  {"FNumber", 0x829D},
135  {"ExposureProgram", 0x8822},
136  {"SpectralSensitivity", 0x8824},
137  {"ISOSpeedRatings", 0x8827},
138  {"OECF", 0x8828},
139  {"ShutterSpeedValue", 0x9201},
140  {"ApertureValue", 0x9202},
141  {"BrightnessValue", 0x9203},
142  {"ExposureBiasValue", 0x9204},
143  {"MaxApertureValue", 0x9205},
144  {"SubjectDistance", 0x9206},
145  {"MeteringMode", 0x9207},
146  {"LightSource", 0x9208},
147  {"Flash", 0x9209},
148  {"FocalLength", 0x920A},
149  {"SubjectArea", 0x9214},
150  {"FlashEnergy", 0xA20B},
151  {"SpatialFrequencyResponse", 0xA20C},
152  {"FocalPlaneXResolution", 0xA20E},
153  {"FocalPlaneYResolution", 0xA20F},
154  {"FocalPlaneResolutionUnit", 0xA210},
155  {"SubjectLocation", 0xA214},
156  {"ExposureIndex", 0xA215},
157  {"SensingMethod", 0xA217},
158  {"FileSource", 0xA300},
159  {"SceneType", 0xA301},
160  {"CFAPattern", 0xA302},
161  {"CustomRendered", 0xA401},
162  {"ExposureMode", 0xA402},
163  {"WhiteBalance", 0xA403},
164  {"DigitalZoomRatio", 0xA404},
165  {"FocalLengthIn35mmFilm", 0xA405},
166  {"SceneCaptureType", 0xA406},
167  {"GainControl", 0xA407},
168  {"Contrast", 0xA408},
169  {"Saturation", 0xA409},
170  {"Sharpness", 0xA40A},
171  {"DeviceSettingDescription", 0xA40B},
172  {"SubjectDistanceRange", 0xA40C},
173 
174  /* InteropIFD tags */
175  {"RelatedImageFileFormat", 0x1000},
176  {"RelatedImageWidth", 0x1001},
177  {"RelatedImageLength", 0x1002},
178 
179  /* private EXIF tags */
180  {"PrintImageMatching", 0xC4A5}, // <- undocumented meaning
181 
182  /* IFD tags */
183  {"ExifIFD", 0x8769}, // <- An IFD pointing to standard Exif metadata
184  {"GPSInfo", 0x8825}, // <- An IFD pointing to GPS Exif Metadata
185  {"InteropIFD", 0xA005}, // <- Table 13 Interoperability IFD Attribute Information
186  {"GlobalParametersIFD", 0x0190},
187  {"ProfileIFD", 0xc6f5},
188 };
189 
190 /* same as type_sizes but with string == 1 */
191 static const size_t exif_sizes[] = {
192  [0] = 0,
193  [AV_TIFF_BYTE] = 1,
194  [AV_TIFF_STRING] = 1,
195  [AV_TIFF_SHORT] = 2,
196  [AV_TIFF_LONG] = 4,
197  [AV_TIFF_RATIONAL] = 8,
198  [AV_TIFF_SBYTE] = 1,
199  [AV_TIFF_UNDEFINED] = 1,
200  [AV_TIFF_SSHORT] = 2,
201  [AV_TIFF_SLONG] = 4,
202  [AV_TIFF_SRATIONAL] = 8,
203  [AV_TIFF_FLOAT] = 4,
204  [AV_TIFF_DOUBLE] = 8,
205  [AV_TIFF_IFD] = 4,
206 };
207 
208 const char *av_exif_get_tag_name(uint16_t id)
209 {
210  for (size_t i = 0; i < FF_ARRAY_ELEMS(tag_list); i++) {
211  if (tag_list[i].id == id)
212  return tag_list[i].name;
213  }
214 
215  return NULL;
216 }
217 
219 {
220  if (!name)
221  return -1;
222 
223  for (size_t i = 0; i < FF_ARRAY_ELEMS(tag_list); i++) {
224  if (!strcmp(tag_list[i].name, name))
225  return tag_list[i].id;
226  }
227 
228  return -1;
229 }
230 
231 static inline void tput16(PutByteContext *pb, const int le, const uint16_t value)
232 {
233  le ? bytestream2_put_le16(pb, value) : bytestream2_put_be16(pb, value);
234 }
235 
236 static inline void tput32(PutByteContext *pb, const int le, const uint32_t value)
237 {
238  le ? bytestream2_put_le32(pb, value) : bytestream2_put_be32(pb, value);
239 }
240 
241 static inline void tput64(PutByteContext *pb, const int le, const uint64_t value)
242 {
243  le ? bytestream2_put_le64(pb, value) : bytestream2_put_be64(pb, value);
244 }
245 
246 static int exif_read_values(void *logctx, GetByteContext *gb, int le, AVExifEntry *entry)
247 {
248  switch (entry->type) {
249  case AV_TIFF_SHORT:
250  case AV_TIFF_LONG:
251  entry->value.uint = av_calloc(entry->count, sizeof(*entry->value.uint));
252  break;
253  case AV_TIFF_SSHORT:
254  case AV_TIFF_SLONG:
255  entry->value.sint = av_calloc(entry->count, sizeof(*entry->value.sint));
256  break;
257  case AV_TIFF_DOUBLE:
258  case AV_TIFF_FLOAT:
259  entry->value.dbl = av_calloc(entry->count, sizeof(*entry->value.dbl));
260  break;
261  case AV_TIFF_RATIONAL:
262  case AV_TIFF_SRATIONAL:
263  entry->value.rat = av_calloc(entry->count, sizeof(*entry->value.rat));
264  break;
265  case AV_TIFF_UNDEFINED:
266  case AV_TIFF_BYTE:
267  entry->value.ubytes = av_mallocz(entry->count);
268  break;
269  case AV_TIFF_SBYTE:
270  entry->value.sbytes = av_mallocz(entry->count);
271  break;
272  case AV_TIFF_STRING:
273  entry->value.str = av_mallocz(entry->count + 1);
274  break;
275  case AV_TIFF_IFD:
276  av_log(logctx, AV_LOG_WARNING, "Bad IFD type for non-IFD tag\n");
277  return AVERROR_INVALIDDATA;
278  }
279  if (!entry->value.ptr)
280  return AVERROR(ENOMEM);
281  switch (entry->type) {
282  case AV_TIFF_SHORT:
283  for (size_t i = 0; i < entry->count; i++)
284  entry->value.uint[i] = ff_tget_short(gb, le);
285  break;
286  case AV_TIFF_LONG:
287  for (size_t i = 0; i < entry->count; i++)
288  entry->value.uint[i] = ff_tget_long(gb, le);
289  break;
290  case AV_TIFF_SSHORT:
291  for (size_t i = 0; i < entry->count; i++)
292  entry->value.sint[i] = (int16_t) ff_tget_short(gb, le);
293  break;
294  case AV_TIFF_SLONG:
295  for (size_t i = 0; i < entry->count; i++)
296  entry->value.sint[i] = (int32_t) ff_tget_long(gb, le);
297  break;
298  case AV_TIFF_DOUBLE:
299  for (size_t i = 0; i < entry->count; i++)
300  entry->value.dbl[i] = ff_tget_double(gb, le);
301  break;
302  case AV_TIFF_FLOAT:
303  for (size_t i = 0; i < entry->count; i++) {
304  av_alias32 alias = { .u32 = ff_tget_long(gb, le) };
305  entry->value.dbl[i] = alias.f32;
306  }
307  break;
308  case AV_TIFF_RATIONAL:
309  case AV_TIFF_SRATIONAL:
310  for (size_t i = 0; i < entry->count; i++) {
311  int32_t num = ff_tget_long(gb, le);
312  int32_t den = ff_tget_long(gb, le);
313  entry->value.rat[i] = av_make_q(num, den);
314  }
315  break;
316  case AV_TIFF_UNDEFINED:
317  case AV_TIFF_BYTE:
318  /* these three fields are aliased to entry->value.ptr via a union */
319  /* and entry->value.ptr will always be nonzero here */
320  av_assert0(entry->value.ubytes);
321  bytestream2_get_buffer(gb, entry->value.ubytes, entry->count);
322  break;
323  case AV_TIFF_SBYTE:
324  av_assert0(entry->value.sbytes);
325  bytestream2_get_buffer(gb, entry->value.sbytes, entry->count);
326  break;
327  case AV_TIFF_STRING:
328  av_assert0(entry->value.str);
329  bytestream2_get_buffer(gb, entry->value.str, entry->count);
330  break;
331  }
332 
333  return 0;
334 }
335 
336 static void exif_write_values(PutByteContext *pb, int le, const AVExifEntry *entry)
337 {
338  switch (entry->type) {
339  case AV_TIFF_SHORT:
340  for (size_t i = 0; i < entry->count; i++)
341  tput16(pb, le, entry->value.uint[i]);
342  break;
343  case AV_TIFF_LONG:
344  for (size_t i = 0; i < entry->count; i++)
345  tput32(pb, le, entry->value.uint[i]);
346  break;
347  case AV_TIFF_SSHORT:
348  for (size_t i = 0; i < entry->count; i++)
349  tput16(pb, le, entry->value.sint[i]);
350  break;
351  case AV_TIFF_SLONG:
352  for (size_t i = 0; i < entry->count; i++)
353  tput32(pb, le, entry->value.sint[i]);
354  break;
355  case AV_TIFF_DOUBLE:
356  for (size_t i = 0; i < entry->count; i++) {
357  const av_alias64 a = { .f64 = entry->value.dbl[i] };
358  tput64(pb, le, a.u64);
359  }
360  break;
361  case AV_TIFF_FLOAT:
362  for (size_t i = 0; i < entry->count; i++) {
363  const av_alias32 a = { .f32 = entry->value.dbl[i] };
364  tput32(pb, le, a.u32);
365  }
366  break;
367  case AV_TIFF_RATIONAL:
368  case AV_TIFF_SRATIONAL:
369  for (size_t i = 0; i < entry->count; i++) {
370  tput32(pb, le, entry->value.rat[i].num);
371  tput32(pb, le, entry->value.rat[i].den);
372  }
373  break;
374  case AV_TIFF_UNDEFINED:
375  case AV_TIFF_BYTE:
376  bytestream2_put_buffer(pb, entry->value.ubytes, entry->count);
377  break;
378  case AV_TIFF_SBYTE:
379  bytestream2_put_buffer(pb, entry->value.sbytes, entry->count);
380  break;
381  case AV_TIFF_STRING:
382  bytestream2_put_buffer(pb, entry->value.str, entry->count);
383  break;
384  }
385 }
386 
387 static const uint8_t aoc_header[] = { 'A', 'O', 'C', 0, };
388 static const uint8_t casio_header[] = { 'Q', 'V', 'C', 0, 0, 0, };
389 static const uint8_t foveon_header[] = { 'F', 'O', 'V', 'E', 'O', 'N', 0, 0, };
390 static const uint8_t fuji_header[] = { 'F', 'U', 'J', 'I', };
391 static const uint8_t nikon_header[] = { 'N', 'i', 'k', 'o', 'n', 0, };
392 static const uint8_t olympus1_header[] = { 'O', 'L', 'Y', 'M', 'P', 0, };
393 static const uint8_t olympus2_header[] = { 'O', 'L', 'Y', 'M', 'P', 'U', 'S', 0, 'I', 'I', };
394 static const uint8_t panasonic_header[] = { 'P', 'a', 'n', 'a', 's', 'o', 'n', 'i', 'c', 0, 0, 0, };
395 static const uint8_t sigma_header[] = { 'S', 'I', 'G', 'M', 'A', 0, 0, 0, };
396 static const uint8_t sony_header[] = { 'S', 'O', 'N', 'Y', ' ', 'D', 'S', 'C', ' ', 0, 0, 0, };
397 
399  const uint8_t *header;
400  size_t header_size;
401  int result;
402 };
403 
404 #define MAKERNOTE_STRUCT(h, r) { \
405  .header = (h), \
406  .header_size = sizeof((h)), \
407  .result = (r), \
408 }
409 
410 static const struct exif_makernote_data makernote_data[] = {
420 };
421 
422 /*
423  * derived from Exiv2 MakerNote's article
424  * https://exiv2.org/makernote.html or archived at
425  * https://web.archive.org/web/20250311155857/https://exiv2.org/makernote.html
426  */
428 {
430  return -1;
431 
432  for (int i = 0; i < FF_ARRAY_ELEMS(makernote_data); i++) {
434  return makernote_data[i].result;
435  }
436 
437  if (!memcmp(gb->buffer, nikon_header, sizeof(nikon_header))) {
438  if (bytestream2_get_bytes_left(gb) < 14)
439  return -1;
440  else if (AV_RB32(gb->buffer + 10) == EXIF_MM_LONG || AV_RB32(gb->buffer + 10) == EXIF_II_LONG)
441  return -1;
442  return 8;
443  }
444 
445  return 0;
446 }
447 
448 static int exif_parse_ifd_list(void *logctx, GetByteContext *gb, int le,
449  int depth, AVExifMetadata *ifd);
450 
451 static int exif_decode_tag(void *logctx, GetByteContext *gb, int le,
452  int depth, AVExifEntry *entry)
453 {
454  int ret = 0, makernote_offset = -1, tell, is_ifd, count;
455  enum AVTiffDataType type;
456  uint32_t payload;
457 
458  /* safety check to prevent infinite recursion on malicious IFDs */
459  if (depth > 3)
460  return AVERROR_INVALIDDATA;
461 
462  tell = bytestream2_tell(gb);
463 
464  entry->id = ff_tget_short(gb, le);
465  type = ff_tget_short(gb, le);
466  count = ff_tget_long(gb, le);
467  payload = ff_tget_long(gb, le);
468 
469  av_log(logctx, AV_LOG_DEBUG, "TIFF Tag: id: 0x%04x, type: %d, count: %u, offset: %d, "
470  "payload: %" PRIu32 "\n", entry->id, type, count, tell, payload);
471 
472  /* AV_TIFF_IFD is the largest, numerically */
473  if (type > AV_TIFF_IFD)
474  return AVERROR_INVALIDDATA;
475 
476  is_ifd = type == AV_TIFF_IFD || ff_tis_ifd(entry->id) || entry->id == MAKERNOTE_TAG;
477 
478  if (is_ifd) {
479  if (!payload)
480  goto end;
481  bytestream2_seek(gb, payload, SEEK_SET);
482  }
483 
484  if (entry->id == MAKERNOTE_TAG) {
485  makernote_offset = exif_get_makernote_offset(gb);
486  if (makernote_offset < 0)
487  is_ifd = 0;
488  }
489 
490  if (is_ifd) {
491  entry->type = AV_TIFF_IFD;
492  entry->count = 1;
493  entry->ifd_offset = makernote_offset > 0 ? makernote_offset : 0;
494  if (entry->ifd_offset) {
495  entry->ifd_lead = av_malloc(entry->ifd_offset);
496  if (!entry->ifd_lead)
497  return AVERROR(ENOMEM);
498  bytestream2_get_buffer(gb, entry->ifd_lead, entry->ifd_offset);
499  }
500  ret = exif_parse_ifd_list(logctx, gb, le, depth + 1, &entry->value.ifd);
501  if (ret < 0 && entry->id == MAKERNOTE_TAG) {
502  /*
503  * we guessed that MakerNote was an IFD
504  * but we were probably incorrect at this
505  * point so we try again as a binary blob
506  */
507  av_exif_free(&entry->value.ifd);
508  av_log(logctx, AV_LOG_DEBUG, "unrecognized MakerNote IFD, retrying as blob\n");
509  is_ifd = 0;
510  }
511  }
512 
513  /* inverted condition instead of else so we can fall through from above */
514  if (!is_ifd) {
516  entry->count = count;
517  bytestream2_seek(gb, count * exif_sizes[type] > 4 ? payload : tell + 8, SEEK_SET);
518  ret = exif_read_values(logctx, gb, le, entry);
519  }
520 
521 end:
522  bytestream2_seek(gb, tell + BASE_TAG_SIZE, SEEK_SET);
523 
524  return ret;
525 }
526 
527 static int exif_parse_ifd_list(void *logctx, GetByteContext *gb, int le,
528  int depth, AVExifMetadata *ifd)
529 {
530  uint32_t entries;
531  size_t required_size;
532  void *temp;
533 
534  av_log(logctx, AV_LOG_DEBUG, "parsing IFD list at offset: %d\n", bytestream2_tell(gb));
535 
536  if (bytestream2_get_bytes_left(gb) < 2) {
537  av_log(logctx, AV_LOG_ERROR, "not enough bytes remaining in EXIF buffer: 2 required\n");
538  return AVERROR_INVALIDDATA;
539  }
540 
541  entries = ff_tget_short(gb, le);
542  if (bytestream2_get_bytes_left(gb) < entries * BASE_TAG_SIZE) {
543  av_log(logctx, AV_LOG_ERROR, "not enough bytes remaining in EXIF buffer. entries: %" PRIu32 "\n", entries);
544  return AVERROR_INVALIDDATA;
545  }
546  if (entries > 4096) {
547  /* that is a lot of entries, probably an error */
548  av_log(logctx, AV_LOG_ERROR, "too many entries: %" PRIu32 "\n", entries);
549  return AVERROR_INVALIDDATA;
550  }
551 
552  ifd->count = entries;
553  av_log(logctx, AV_LOG_DEBUG, "entry count for IFD: %u\n", ifd->count);
554 
555  /* empty IFD is technically legal but equivalent to no metadata present */
556  if (!ifd->count)
557  goto end;
558 
559  if (av_size_mult(ifd->count, sizeof(*ifd->entries), &required_size) < 0)
560  return AVERROR(ENOMEM);
561  temp = av_fast_realloc(ifd->entries, &ifd->size, required_size);
562  if (!temp) {
563  av_freep(&ifd->entries);
564  return AVERROR(ENOMEM);
565  }
566  ifd->entries = temp;
567 
568  /* entries have pointers in them which can cause issues if */
569  /* they are freed or realloc'd when garbage */
570  memset(ifd->entries, 0, required_size);
571 
572  for (uint32_t i = 0; i < entries; i++) {
573  int ret = exif_decode_tag(logctx, gb, le, depth, &ifd->entries[i]);
574  if (ret < 0)
575  return ret;
576  }
577 
578 end:
579  /*
580  * at the end of an IFD is an pointer to the next IFD
581  * or zero if there are no more IFDs, which is usually the case
582  */
583  return ff_tget_long(gb, le);
584 }
585 
586 /*
587  * note that this function does not free the entry pointer itself
588  * because it's probably part of a larger array that should be freed
589  * all at once
590  */
592 {
593  if (!entry)
594  return;
595  if (entry->type == AV_TIFF_IFD)
596  av_exif_free(&entry->value.ifd);
597  else
598  av_freep(&entry->value.ptr);
599  av_freep(&entry->ifd_lead);
600 }
601 
603 {
604  if (!ifd)
605  return;
606  if (!ifd->entries) {
607  ifd->count = 0;
608  ifd->size = 0;
609  return;
610  }
611  for (size_t i = 0; i < ifd->count; i++) {
612  AVExifEntry *entry = &ifd->entries[i];
614  }
615  av_freep(&ifd->entries);
616  ifd->count = 0;
617  ifd->size = 0;
618 }
619 
620 static size_t exif_get_ifd_size(const AVExifMetadata *ifd)
621 {
622  /* 6 == 4 + 2; 2-byte entry-count at the beginning */
623  /* plus 4-byte next-IFD pointer at the end */
624  size_t total_size = IFD_EXTRA_SIZE;
625  for (size_t i = 0; i < ifd->count; i++) {
626  const AVExifEntry *entry = &ifd->entries[i];
627  if (entry->type == AV_TIFF_IFD) {
628  total_size += BASE_TAG_SIZE + exif_get_ifd_size(&entry->value.ifd) + entry->ifd_offset;
629  } else {
630  size_t payload_size = entry->count * exif_sizes[entry->type];
631  total_size += BASE_TAG_SIZE + (payload_size > 4 ? payload_size : 0);
632  }
633  }
634  return total_size;
635 }
636 
637 static int exif_write_ifd(void *logctx, PutByteContext *pb, int le, int depth, const AVExifMetadata *ifd)
638 {
639  int offset, ret, tell, tell2;
640  tell = bytestream2_tell_p(pb);
641  tput16(pb, le, ifd->count);
642  offset = tell + IFD_EXTRA_SIZE + BASE_TAG_SIZE * (uint32_t) ifd->count;
643  av_log(logctx, AV_LOG_DEBUG, "writing IFD with %u entries and initial offset %d\n", ifd->count, offset);
644  for (size_t i = 0; i < ifd->count; i++) {
645  const AVExifEntry *entry = &ifd->entries[i];
646  av_log(logctx, AV_LOG_DEBUG, "writing TIFF entry: id: 0x%04" PRIx16 ", type: %d, count: %"
647  PRIu32 ", offset: %d, offset value: %d\n",
648  entry->id, entry->type, entry->count,
650  tput16(pb, le, entry->id);
651  if (entry->id == MAKERNOTE_TAG && entry->type == AV_TIFF_IFD) {
652  size_t ifd_size = exif_get_ifd_size(&entry->value.ifd);
653  tput16(pb, le, AV_TIFF_UNDEFINED);
654  tput32(pb, le, ifd_size);
655  } else {
656  tput16(pb, le, entry->type);
657  tput32(pb, le, entry->count);
658  }
659  if (entry->type == AV_TIFF_IFD) {
660  tput32(pb, le, offset);
661  tell2 = bytestream2_tell_p(pb);
662  bytestream2_seek_p(pb, offset, SEEK_SET);
663  if (entry->ifd_offset)
664  bytestream2_put_buffer(pb, entry->ifd_lead, entry->ifd_offset);
665  ret = exif_write_ifd(logctx, pb, le, depth + 1, &entry->value.ifd);
666  if (ret < 0)
667  return ret;
668  offset += ret + entry->ifd_offset;
669  bytestream2_seek_p(pb, tell2, SEEK_SET);
670  } else {
671  size_t payload_size = entry->count * exif_sizes[entry->type];
672  if (payload_size > 4) {
673  tput32(pb, le, offset);
674  tell2 = bytestream2_tell_p(pb);
675  bytestream2_seek_p(pb, offset, SEEK_SET);
676  exif_write_values(pb, le, entry);
677  offset += payload_size;
678  bytestream2_seek_p(pb, tell2, SEEK_SET);
679  } else {
680  /* zero uninitialized excess payload values */
681  AV_WN32(pb->buffer, 0);
682  exif_write_values(pb, le, entry);
683  bytestream2_seek_p(pb, 4 - payload_size, SEEK_CUR);
684  }
685  }
686  }
687 
688  /*
689  * we write 0 if this is the top-level exif IFD
690  * indicating that there are no more IFD pointers
691  */
692  tput32(pb, le, depth ? offset : 0);
693  return offset - tell;
694 }
695 
696 int av_exif_write(void *logctx, const AVExifMetadata *ifd, AVBufferRef **buffer, enum AVExifHeaderMode header_mode)
697 {
698  AVBufferRef *buf = NULL;
699  size_t size, headsize = 8;
700  PutByteContext pb;
701  int ret, off = 0;
702 
703  int le = 1;
704 
705  if (*buffer)
706  return AVERROR(EINVAL);
707 
708  size = exif_get_ifd_size(ifd);
709  switch (header_mode) {
710  case AV_EXIF_EXIF00:
711  off = 6;
712  break;
713  case AV_EXIF_T_OFF:
714  off = 4;
715  break;
716  case AV_EXIF_ASSUME_BE:
717  le = 0;
718  headsize = 0;
719  break;
720  case AV_EXIF_ASSUME_LE:
721  le = 1;
722  headsize = 0;
723  break;
724  }
725  buf = av_buffer_alloc(size + off + headsize);
726  if (!buf)
727  return AVERROR(ENOMEM);
728 
729  if (header_mode == AV_EXIF_EXIF00) {
730  AV_WL32(buf->data, MKTAG('E','x','i','f'));
731  AV_WN16(buf->data + 4, 0);
732  } else if (header_mode == AV_EXIF_T_OFF) {
733  AV_WN32(buf->data, 0);
734  }
735 
736  bytestream2_init_writer(&pb, buf->data + off, buf->size - off);
737 
738  if (header_mode != AV_EXIF_ASSUME_BE && header_mode != AV_EXIF_ASSUME_LE) {
739  /* these constants are be32 in both cases */
740  /* le == 1 always in this case */
741  bytestream2_put_be32(&pb, EXIF_II_LONG);
742  tput32(&pb, le, 8);
743  }
744 
745  ret = exif_write_ifd(logctx, &pb, le, 0, ifd);
746  if (ret < 0) {
747  av_buffer_unref(&buf);
748  av_log(logctx, AV_LOG_ERROR, "error writing EXIF data: %s\n", av_err2str(ret));
749  return ret;
750  }
751 
752  *buffer = buf;
753 
754  return 0;
755 }
756 
757 int av_exif_parse_buffer(void *logctx, const uint8_t *buf, size_t size,
758  AVExifMetadata *ifd, enum AVExifHeaderMode header_mode)
759 {
760  int ret, le;
761  GetByteContext gbytes;
762  if (size > INT_MAX)
763  return AVERROR(EINVAL);
764  size_t off = 0;
765  switch (header_mode) {
766  case AV_EXIF_EXIF00:
767  if (size < 6)
768  return AVERROR_INVALIDDATA;
769  off = 6;
770  /* fallthrough */
771  case AV_EXIF_T_OFF:
772  if (size < 4)
773  return AVERROR_INVALIDDATA;
774  if (!off)
775  off = AV_RB32(buf) + 4;
776  /* fallthrough */
777  case AV_EXIF_TIFF_HEADER: {
778  int ifd_offset;
779  if (size <= off)
780  return AVERROR_INVALIDDATA;
781  bytestream2_init(&gbytes, buf + off, size - off);
782  // read TIFF header
783  ret = ff_tdecode_header(&gbytes, &le, &ifd_offset);
784  if (ret < 0) {
785  av_log(logctx, AV_LOG_ERROR, "invalid TIFF header in EXIF data: %s\n", av_err2str(ret));
786  return ret;
787  }
788  bytestream2_seek(&gbytes, ifd_offset, SEEK_SET);
789  break;
790  }
791  case AV_EXIF_ASSUME_LE:
792  le = 1;
793  bytestream2_init(&gbytes, buf, size);
794  break;
795  case AV_EXIF_ASSUME_BE:
796  le = 0;
797  bytestream2_init(&gbytes, buf, size);
798  break;
799  default:
800  return AVERROR(EINVAL);
801  }
802 
803  /*
804  * parse IFD0 here. If the return value is positive that tells us
805  * there is subimage metadata, but we don't parse that IFD here
806  */
807  ret = exif_parse_ifd_list(logctx, &gbytes, le, 0, ifd);
808  if (ret < 0) {
809  av_exif_free(ifd);
810  av_log(logctx, AV_LOG_ERROR, "error decoding EXIF data: %s\n", av_err2str(ret));
811  return ret;
812  }
813 
814  return bytestream2_tell(&gbytes);
815 }
816 
817 #define COLUMN_SEP(i, c) ((i) ? ((i) % (c) ? ", " : "\n") : "")
818 
819 static int exif_ifd_to_dict(void *logctx, const char *prefix, const AVExifMetadata *ifd, AVDictionary **metadata)
820 {
821  AVBPrint bp;
822  int ret = 0;
823  char *key = NULL;
824  char *value = NULL;
825 
826  if (!prefix)
827  prefix = "";
828 
829  for (uint16_t i = 0; i < ifd->count; i++) {
830  const AVExifEntry *entry = &ifd->entries[i];
831  const char *name = av_exif_get_tag_name(entry->id);
832  av_bprint_init(&bp, entry->count * 10, AV_BPRINT_SIZE_UNLIMITED);
833  if (*prefix)
834  av_bprintf(&bp, "%s/", prefix);
835  if (name)
836  av_bprintf(&bp, "%s", name);
837  else
838  av_bprintf(&bp, "0x%04X", entry->id);
839  ret = av_bprint_finalize(&bp, &key);
840  if (ret < 0)
841  goto end;
842  av_bprint_init(&bp, entry->count * 10, AV_BPRINT_SIZE_UNLIMITED);
843  switch (entry->type) {
844  case AV_TIFF_IFD:
845  ret = exif_ifd_to_dict(logctx, key, &entry->value.ifd, metadata);
846  if (ret < 0)
847  goto end;
848  break;
849  case AV_TIFF_SHORT:
850  case AV_TIFF_LONG:
851  for (uint32_t j = 0; j < entry->count; j++)
852  av_bprintf(&bp, "%s%7" PRIu32, COLUMN_SEP(j, 8), (uint32_t)entry->value.uint[j]);
853  break;
854  case AV_TIFF_SSHORT:
855  case AV_TIFF_SLONG:
856  for (uint32_t j = 0; j < entry->count; j++)
857  av_bprintf(&bp, "%s%7" PRId32, COLUMN_SEP(j, 8), (int32_t)entry->value.sint[j]);
858  break;
859  case AV_TIFF_RATIONAL:
860  case AV_TIFF_SRATIONAL:
861  for (uint32_t j = 0; j < entry->count; j++)
862  av_bprintf(&bp, "%s%7i:%-7i", COLUMN_SEP(j, 4), entry->value.rat[j].num, entry->value.rat[j].den);
863  break;
864  case AV_TIFF_DOUBLE:
865  case AV_TIFF_FLOAT:
866  for (uint32_t j = 0; j < entry->count; j++)
867  av_bprintf(&bp, "%s%.15g", COLUMN_SEP(j, 4), entry->value.dbl[j]);
868  break;
869  case AV_TIFF_STRING:
870  av_bprintf(&bp, "%s", entry->value.str);
871  break;
872  case AV_TIFF_UNDEFINED:
873  case AV_TIFF_BYTE:
874  for (uint32_t j = 0; j < entry->count; j++)
875  av_bprintf(&bp, "%s%3i", COLUMN_SEP(j, 16), entry->value.ubytes[j]);
876  break;
877  case AV_TIFF_SBYTE:
878  for (uint32_t j = 0; j < entry->count; j++)
879  av_bprintf(&bp, "%s%3i", COLUMN_SEP(j, 16), entry->value.sbytes[j]);
880  break;
881  }
882  if (entry->type != AV_TIFF_IFD) {
883  if (!av_bprint_is_complete(&bp)) {
884  av_bprint_finalize(&bp, NULL);
885  ret = AVERROR(ENOMEM);
886  goto end;
887  }
888  ret = av_bprint_finalize(&bp, &value);
889  if (ret < 0)
890  goto end;
892  key = NULL;
893  value = NULL;
894  if (ret < 0)
895  goto end;
896  } else {
897  av_freep(&key);
898  }
899  }
900 
901 end:
902  av_freep(&key);
903  av_freep(&value);
904  return ret;
905 }
906 
907 int av_exif_ifd_to_dict(void *logctx, const AVExifMetadata *ifd, AVDictionary **metadata)
908 {
909  return exif_ifd_to_dict(logctx, "", ifd, metadata);
910 }
911 
912 #if FF_API_OLD_EXIF
913 int avpriv_exif_decode_ifd(void *logctx, const uint8_t *buf, int size,
914  int le, int depth, AVDictionary **metadata)
915 {
916  AVExifMetadata ifd = { 0 };
917  GetByteContext gb;
918  int ret;
919  bytestream2_init(&gb, buf, size);
920  ret = exif_parse_ifd_list(logctx, &gb, le, depth, &ifd);
921  if (ret < 0)
922  return ret;
923  ret = av_exif_ifd_to_dict(logctx, &ifd, metadata);
924  av_exif_free(&ifd);
925  return ret;
926 }
927 #endif /* FF_API_OLD_EXIF */
928 
929 #define EXIF_COPY(fname, srcname) do { \
930  size_t sz; \
931  if (av_size_mult(src->count, sizeof(*(fname)), &sz) < 0) { \
932  ret = AVERROR(ENOMEM); \
933  goto end; \
934  } \
935  (fname) = av_memdup((srcname), sz); \
936  if (!(fname)) { \
937  ret = AVERROR(ENOMEM); \
938  goto end; \
939  } \
940 } while (0)
941 
943 {
944  int ret = 0;
945 
946  dst->count = src->count;
947  dst->id = src->id;
948  dst->type = src->type;
949 
950  dst->ifd_offset = src->ifd_offset;
951  if (src->ifd_lead) {
952  dst->ifd_lead = av_memdup(src->ifd_lead, src->ifd_offset);
953  if (!dst->ifd_lead) {
954  ret = AVERROR(ENOMEM);
955  goto end;
956  }
957  } else {
958  dst->ifd_lead = NULL;
959  }
960 
961  switch(src->type) {
962  case AV_TIFF_IFD: {
963  AVExifMetadata *cloned = av_exif_clone_ifd(&src->value.ifd);
964  if (!cloned) {
965  ret = AVERROR(ENOMEM);
966  goto end;
967  }
968  dst->value.ifd = *cloned;
969  av_freep(&cloned);
970  break;
971  }
972  case AV_TIFF_SHORT:
973  case AV_TIFF_LONG:
974  EXIF_COPY(dst->value.uint, src->value.uint);
975  break;
976  case AV_TIFF_SLONG:
977  case AV_TIFF_SSHORT:
978  EXIF_COPY(dst->value.sint, src->value.sint);
979  break;
980  case AV_TIFF_RATIONAL:
981  case AV_TIFF_SRATIONAL:
982  EXIF_COPY(dst->value.rat, src->value.rat);
983  break;
984  case AV_TIFF_DOUBLE:
985  case AV_TIFF_FLOAT:
986  EXIF_COPY(dst->value.dbl, src->value.dbl);
987  break;
988  case AV_TIFF_BYTE:
989  case AV_TIFF_UNDEFINED:
990  EXIF_COPY(dst->value.ubytes, src->value.ubytes);
991  break;
992  case AV_TIFF_SBYTE:
993  EXIF_COPY(dst->value.sbytes, src->value.sbytes);
994  break;
995  case AV_TIFF_STRING:
996  dst->value.str = av_memdup(src->value.str, src->count+1);
997  if (!dst->value.str) {
998  ret = AVERROR(ENOMEM);
999  goto end;
1000  }
1001  break;
1002  }
1003 
1004  return 0;
1005 
1006 end:
1007  av_freep(&dst->ifd_lead);
1008  if (src->type == AV_TIFF_IFD)
1009  av_exif_free(&dst->value.ifd);
1010  else
1011  av_freep(&dst->value.ptr);
1012  memset(dst, 0, sizeof(*dst));
1013 
1014  return ret;
1015 }
1016 
1017 static int exif_get_entry(void *logctx, AVExifMetadata *ifd, uint16_t id, int depth, AVExifEntry **value)
1018 {
1019  int offset = 1;
1020 
1021  if (!ifd || ifd->count && !ifd->entries || !value)
1022  return AVERROR(EINVAL);
1023 
1024  for (size_t i = 0; i < ifd->count; i++) {
1025  if (ifd->entries[i].id == id) {
1026  *value = &ifd->entries[i];
1027  return i + offset;
1028  }
1029  if (ifd->entries[i].type == AV_TIFF_IFD) {
1030  if (depth < 3) {
1031  int ret = exif_get_entry(logctx, &ifd->entries[i].value.ifd, id, depth + 1, value);
1032  if (ret)
1033  return ret < 0 ? ret : ret + offset;
1034  }
1035  offset += ifd->entries[i].value.ifd.count;
1036  }
1037  }
1038 
1039  return 0;
1040 }
1041 
1042 int av_exif_get_entry(void *logctx, AVExifMetadata *ifd, uint16_t id, int flags, AVExifEntry **value)
1043 {
1044  return exif_get_entry(logctx, ifd, id, (flags & AV_EXIF_FLAG_RECURSIVE) ? 0 : INT_MAX, value);
1045 }
1046 
1047 int av_exif_set_entry(void *logctx, AVExifMetadata *ifd, uint16_t id, enum AVTiffDataType type,
1048  uint32_t count, const uint8_t *ifd_lead, uint32_t ifd_offset, const void *value)
1049 {
1050  void *temp;
1051  int ret = 0;
1052  AVExifEntry *entry = NULL;
1053  AVExifEntry src = { 0 };
1054 
1055  if (!ifd || ifd->count && !ifd->entries
1056  || ifd_lead && !ifd_offset || !ifd_lead && ifd_offset
1057  || !value || ifd->count == 0xFFFFu)
1058  return AVERROR(EINVAL);
1059 
1060  ret = av_exif_get_entry(logctx, ifd, id, 0, &entry);
1061  if (ret < 0)
1062  return ret;
1063 
1064  if (entry) {
1066  } else {
1067  size_t required_size;
1068  ret = av_size_mult(ifd->count + 1, sizeof(*ifd->entries), &required_size);
1069  if (ret < 0)
1070  return AVERROR(ENOMEM);
1071  temp = av_fast_realloc(ifd->entries, &ifd->size, required_size);
1072  if (!temp)
1073  return AVERROR(ENOMEM);
1074  ifd->entries = temp;
1075  entry = &ifd->entries[ifd->count++];
1076  }
1077 
1078  src.count = count;
1079  src.id = id;
1080  src.type = type;
1081  src.ifd_lead = (uint8_t *) ifd_lead;
1082  src.ifd_offset = ifd_offset;
1083  if (type == AV_TIFF_IFD)
1084  src.value.ifd = * (const AVExifMetadata *) value;
1085  else
1086  src.value.ptr = (void *) value;
1087 
1089 
1090  if (ret < 0)
1091  ifd->count--;
1092 
1093  return ret;
1094 }
1095 
1096 static int exif_remove_entry(void *logctx, AVExifMetadata *ifd, uint16_t id, int depth)
1097 {
1098  int32_t index = -1;
1099  int ret = 0;
1100 
1101  if (!ifd || ifd->count && !ifd->entries)
1102  return AVERROR(EINVAL);
1103 
1104  for (size_t i = 0; i < ifd->count; i++) {
1105  if (ifd->entries[i].id == id) {
1106  index = i;
1107  break;
1108  }
1109  if (ifd->entries[i].type == AV_TIFF_IFD && depth < 3) {
1110  ret = exif_remove_entry(logctx, &ifd->entries[i].value.ifd, id, depth + 1);
1111  if (ret)
1112  return ret;
1113  }
1114  }
1115 
1116  if (index < 0)
1117  return 0;
1118  exif_free_entry(&ifd->entries[index]);
1119 
1120  if (index == --ifd->count) {
1121  if (!index)
1122  av_freep(&ifd->entries);
1123  return 1;
1124  }
1125 
1126  memmove(&ifd->entries[index], &ifd->entries[index + 1], (ifd->count - index) * sizeof(*ifd->entries));
1127 
1128  return 1 + (ifd->count - index);
1129 }
1130 
1131 int av_exif_remove_entry(void *logctx, AVExifMetadata *ifd, uint16_t id, int flags)
1132 {
1133  return exif_remove_entry(logctx, ifd, id, (flags & AV_EXIF_FLAG_RECURSIVE) ? 0 : INT_MAX);
1134 }
1135 
1137 {
1138  AVExifMetadata *ret = av_mallocz(sizeof(*ret));
1139  if (!ret)
1140  return NULL;
1141 
1142  ret->count = ifd->count;
1143  if (ret->count) {
1144  size_t required_size;
1145  if (av_size_mult(ret->count, sizeof(*ret->entries), &required_size) < 0)
1146  goto fail;
1147  ret->entries = av_fast_realloc(NULL, &ret->size, required_size);
1148  if (!ret->entries)
1149  goto fail;
1150  }
1151 
1152  for (size_t i = 0; i < ret->count; i++) {
1153  const AVExifEntry *entry = &ifd->entries[i];
1154  AVExifEntry *ret_entry = &ret->entries[i];
1155  int status = exif_clone_entry(ret_entry, entry);
1156  if (status < 0)
1157  goto fail;
1158  }
1159 
1160  return ret;
1161 
1162 fail:
1163  av_exif_free(ret);
1164  av_free(ret);
1165  return NULL;
1166 }
1167 
1168 static const int rotation_lut[2][4] = {
1169  {1, 8, 3, 6}, {4, 7, 2, 5},
1170 };
1171 
1173 {
1174  double rotation = av_display_rotation_get(matrix);
1175  // determinant
1176  int vflip = ((int64_t)matrix[0] * (int64_t)matrix[4]
1177  - (int64_t)matrix[1] * (int64_t)matrix[3]) < 0;
1178  if (!isfinite(rotation))
1179  return 0;
1180  int rot = (int)(rotation + 0.5);
1181  rot = (((rot % 360) + 360) % 360) / 90;
1182  return rotation_lut[vflip][rot];
1183 }
1184 
1186 {
1187  switch (orientation) {
1188  case 1:
1190  break;
1191  case 2:
1194  break;
1195  case 3:
1197  break;
1198  case 4:
1201  break;
1202  case 5:
1205  break;
1206  case 6:
1208  break;
1209  case 7:
1212  break;
1213  case 8:
1215  break;
1216  default:
1217  return AVERROR(EINVAL);
1218  }
1219 
1220  return 0;
1221 }
1222 
1223 int ff_exif_sanitize_ifd(void *logctx, const AVFrame *frame, AVExifMetadata *ifd)
1224 {
1225  int ret = 0;
1226  AVFrameSideData *sd_orient = NULL;
1227  AVExifEntry *or = NULL;
1228  AVExifEntry *iw = NULL;
1229  AVExifEntry *ih = NULL;
1230  AVExifEntry *pw = NULL;
1231  AVExifEntry *ph = NULL;
1232  uint64_t orientation = 1;
1233  uint64_t w = frame->width;
1234  uint64_t h = frame->height;
1235  int rewrite = 0;
1236 
1238 
1239  if (sd_orient)
1240  orientation = av_exif_matrix_to_orientation((int32_t *) sd_orient->data);
1241  if (orientation != 1)
1242  av_log(logctx, AV_LOG_DEBUG, "matrix contains nontrivial EXIF orientation: %" PRIu64 "\n", orientation);
1243 
1244  for (size_t i = 0; i < ifd->count; i++) {
1245  AVExifEntry *entry = &ifd->entries[i];
1246  if (entry->id == ORIENTATION_TAG && entry->count > 0 && entry->type == AV_TIFF_SHORT) {
1247  or = entry;
1248  continue;
1249  }
1250  if (entry->id == IMAGE_WIDTH_TAG && entry->count > 0 && entry->type == AV_TIFF_LONG) {
1251  iw = entry;
1252  continue;
1253  }
1254  if (entry->id == IMAGE_LENGTH_TAG && entry->count > 0 && entry->type == AV_TIFF_LONG) {
1255  ih = entry;
1256  continue;
1257  }
1258  if (entry->id == EXIFIFD_TAG && entry->type == AV_TIFF_IFD) {
1259  AVExifMetadata *exif = &entry->value.ifd;
1260  for (size_t j = 0; j < exif->count; j++) {
1261  AVExifEntry *exifentry = &exif->entries[j];
1262  if (exifentry->id == PIXEL_X_TAG && exifentry->count > 0 && exifentry->type == AV_TIFF_SHORT) {
1263  pw = exifentry;
1264  continue;
1265  }
1266  if (exifentry->id == PIXEL_Y_TAG && exifentry->count > 0 && exifentry->type == AV_TIFF_SHORT) {
1267  ph = exifentry;
1268  continue;
1269  }
1270  }
1271  }
1272  }
1273 
1274  if (or && or->value.uint[0] != orientation) {
1275  rewrite = 1;
1276  or->value.uint[0] = orientation;
1277  }
1278  if (iw && iw->value.uint[0] != w) {
1279  rewrite = 1;
1280  iw->value.uint[0] = w;
1281  }
1282  if (ih && ih->value.uint[0] != h) {
1283  rewrite = 1;
1284  ih->value.uint[0] = h;
1285  }
1286  if (pw && pw->value.uint[0] != w) {
1287  rewrite = 1;
1288  pw->value.uint[0] = w;
1289  }
1290  if (ph && ph->value.uint[0] != h) {
1291  rewrite = 1;
1292  ph->value.uint[0] = h;
1293  }
1294  if (!or && orientation != 1) {
1295  rewrite = 1;
1296  ret = av_exif_set_entry(logctx, ifd, ORIENTATION_TAG, AV_TIFF_SHORT, 1, NULL, 0, &orientation);
1297  if (ret < 0)
1298  goto end;
1299  }
1300  if (!iw && w) {
1301  rewrite = 1;
1302  ret = av_exif_set_entry(logctx, ifd, IMAGE_WIDTH_TAG, AV_TIFF_LONG, 1, NULL, 0, &w);
1303  if (ret < 0)
1304  goto end;
1305  }
1306  if (!ih && h) {
1307  rewrite = 1;
1308  ret = av_exif_set_entry(logctx, ifd, IMAGE_LENGTH_TAG, AV_TIFF_LONG, 1, NULL, 0, &h);
1309  if (ret < 0)
1310  goto end;
1311  }
1312  if (!pw && w && w < 0xFFFFu || !ph && h && h < 0xFFFFu) {
1313  AVExifMetadata *exif;
1314  AVExifEntry *exif_entry;
1315  int exif_found = av_exif_get_entry(logctx, ifd, EXIFIFD_TAG, 0, &exif_entry);
1316  rewrite = 1;
1317  if (exif_found < 0)
1318  goto end;
1319  if (exif_found > 0) {
1320  exif = &exif_entry->value.ifd;
1321  } else {
1322  AVExifMetadata exif_new = { 0 };
1323  ret = av_exif_set_entry(logctx, ifd, EXIFIFD_TAG, AV_TIFF_IFD, 1, NULL, 0, &exif_new);
1324  if (ret < 0) {
1325  av_exif_free(&exif_new);
1326  goto end;
1327  }
1328  exif = &ifd->entries[ifd->count - 1].value.ifd;
1329  }
1330  if (!pw && w && w < 0xFFFFu) {
1331  ret = av_exif_set_entry(logctx, exif, PIXEL_X_TAG, AV_TIFF_SHORT, 1, NULL, 0, &w);
1332  if (ret < 0)
1333  goto end;
1334  }
1335  if (!ph && h && h < 0xFFFFu) {
1336  ret = av_exif_set_entry(logctx, exif, PIXEL_Y_TAG, AV_TIFF_SHORT, 1, NULL, 0, &h);
1337  if (ret < 0)
1338  goto end;
1339  }
1340  }
1341 
1342  return rewrite;
1343 
1344 end:
1345  return ret;
1346 }
1347 
1348 int ff_exif_get_buffer(void *logctx, const AVFrame *frame, AVBufferRef **buffer_ptr, enum AVExifHeaderMode header_mode)
1349 {
1350  AVFrameSideData *sd_exif = NULL;
1351  AVBufferRef *buffer = NULL;
1352  AVExifMetadata ifd = { 0 };
1353  int ret = 0;
1354  int rewrite = 0;
1355 
1356  if (!buffer_ptr || *buffer_ptr)
1357  return AVERROR(EINVAL);
1358 
1360  if (!sd_exif)
1361  return 0;
1362 
1363  ret = av_exif_parse_buffer(logctx, sd_exif->data, sd_exif->size, &ifd, AV_EXIF_TIFF_HEADER);
1364  if (ret < 0)
1365  goto end;
1366 
1367  rewrite = ff_exif_sanitize_ifd(logctx, frame, &ifd);
1368  if (rewrite < 0) {
1369  ret = rewrite;
1370  goto end;
1371  }
1372 
1373  if (rewrite) {
1374  ret = av_exif_write(logctx, &ifd, &buffer, header_mode);
1375  if (ret < 0)
1376  goto end;
1377 
1378  *buffer_ptr = buffer;
1379  } else {
1380  *buffer_ptr = av_buffer_ref(sd_exif->buf);
1381  if (!*buffer_ptr) {
1382  ret = AVERROR(ENOMEM);
1383  goto end;
1384  }
1385  }
1386 
1387  av_exif_free(&ifd);
1388  return rewrite;
1389 
1390 end:
1391  av_exif_free(&ifd);
1392  return ret;
1393 }
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:51
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:620
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:757
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:657
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:696
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:191
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:907
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:1185
metadata
Stream codec metadata
Definition: ogg-flac-chained-meta.txt:2
AVExifHeaderMode
AVExifHeaderMode
Definition: exif.h:58
ph
static int FUNC() ph(CodedBitstreamContext *ctx, RWContext *rw, H266RawPH *current)
Definition: cbs_h266_syntax_template.c:3037
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
w
uint8_t w
Definition: llviddspenc.c:38
IMAGE_LENGTH_TAG
#define IMAGE_LENGTH_TAG
Definition: exif_internal.h:49
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:451
EXIFIFD_TAG
#define EXIFIFD_TAG
Definition: exif_internal.h:47
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:1047
sony_header
static const uint8_t sony_header[]
Definition: exif.c:396
exif_tag::id
uint16_t id
Definition: exif.c:52
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:913
av_buffer_ref
AVBufferRef * av_buffer_ref(const AVBufferRef *buf)
Create a new reference to an AVBuffer.
Definition: buffer.c:103
av_malloc
#define av_malloc(s)
Definition: tableprint_vlc.h:31
casio_header
static const uint8_t casio_header[]
Definition: exif.c:388
exif_read_values
static int exif_read_values(void *logctx, GetByteContext *gb, int le, AVExifEntry *entry)
Definition: exif.c:246
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:942
AV_TIFF_SHORT
@ AV_TIFF_SHORT
Definition: exif.h:45
fail
#define fail()
Definition: checkasm.h:199
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:602
exif_parse_ifd_list
static int exif_parse_ifd_list(void *logctx, GetByteContext *gb, int le, int depth, AVExifMetadata *ifd)
Definition: exif.c:527
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
MAKERNOTE_TAG
#define MAKERNOTE_TAG
Definition: exif_internal.h:45
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:399
bytestream2_init_writer
static av_always_inline void bytestream2_init_writer(PutByteContext *p, uint8_t *buf, int buf_size)
Definition: bytestream.h:147
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:400
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
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:819
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:1136
tput64
static void tput64(PutByteContext *pb, const int le, const uint64_t value)
Definition: exif.c:241
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:1096
key
const char * key
Definition: hwcontext_opencl.c:189
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:336
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:218
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
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:390
tell
static int BS_FUNC() tell(const BSCTX *bc)
Return number of bits already read.
Definition: bitstream_template.h:146
tiff_common.h
olympus1_header
static const uint8_t olympus1_header[]
Definition: exif.c:392
PIXEL_Y_TAG
#define PIXEL_Y_TAG
Definition: exif_internal.h:51
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:404
AVExifEntry::count
uint32_t count
Definition: exif.h:88
COLUMN_SEP
#define COLUMN_SEP(i, c)
Definition: exif.c:817
olympus2_header
static const uint8_t olympus2_header[]
Definition: exif.c:393
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:1131
IMAGE_WIDTH_TAG
#define IMAGE_WIDTH_TAG
Definition: exif_internal.h:48
foveon_header
static const uint8_t foveon_header[]
Definition: exif.c:389
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:637
panasonic_header
static const uint8_t panasonic_header[]
Definition: exif.c:394
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:401
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:398
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:395
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:410
AV_TIFF_STRING
@ AV_TIFF_STRING
Definition: exif.h:44
av_buffer_alloc
AVBufferRef * av_buffer_alloc(size_t size)
Allocate an AVBuffer of the given size using av_malloc().
Definition: buffer.c:77
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:391
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:231
tput32
static void tput32(PutByteContext *pb, const int le, const uint32_t value)
Definition: exif.c:236
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
exif_get_entry
static int exif_get_entry(void *logctx, AVExifMetadata *ifd, uint16_t id, int depth, AVExifEntry **value)
Definition: exif.c:1017
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
av_mallocz
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
Definition: mem.c:256
AVExifMetadata::count
unsigned int count
Definition: exif.h:80
AVExifEntry::uint
uint64_t * uint
Definition: exif.h:109
exif_get_makernote_offset
static int exif_get_makernote_offset(GetByteContext *gb)
Definition: exif.c:427
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_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:387
exif_tag
Definition: exif.c:50
id
enum AVCodecID id
Definition: dts2pts.c:367
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:929
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:229
tag_list
static const struct exif_tag tag_list[]
Definition: exif.c:55
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:1223
exif_free_entry
static void exif_free_entry(AVExifEntry *entry)
Definition: exif.c:591
mem.h
AVBufferRef
A reference to a data buffer.
Definition: buffer.h:82
ORIENTATION_TAG
#define ORIENTATION_TAG
Definition: exif_internal.h:46
AVFrameSideData
Structure to hold side data for an AVFrame.
Definition: frame.h:282
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:1348
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:1042
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:208
bytestream2_init
static av_always_inline void bytestream2_init(GetByteContext *g, const uint8_t *buf, int buf_size)
Definition: bytestream.h:137
rotation_lut
static const int rotation_lut[2][4]
Definition: exif.c:1168
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:1172
AV_TIFF_LONG
@ AV_TIFF_LONG
Definition: exif.h:46
PIXEL_X_TAG
#define PIXEL_X_TAG
Definition: exif_internal.h:50
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