FFmpeg
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
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 
197 /* same as type_sizes but with string == 1 */
198 static const size_t exif_sizes[] = {
199  [0] = 0,
200  [AV_TIFF_BYTE] = 1,
201  [AV_TIFF_STRING] = 1,
202  [AV_TIFF_SHORT] = 2,
203  [AV_TIFF_LONG] = 4,
204  [AV_TIFF_RATIONAL] = 8,
205  [AV_TIFF_SBYTE] = 1,
206  [AV_TIFF_UNDEFINED] = 1,
207  [AV_TIFF_SSHORT] = 2,
208  [AV_TIFF_SLONG] = 4,
209  [AV_TIFF_SRATIONAL] = 8,
210  [AV_TIFF_FLOAT] = 4,
211  [AV_TIFF_DOUBLE] = 8,
212  [AV_TIFF_IFD] = 4,
213 };
214 
215 const char *av_exif_get_tag_name(uint16_t id)
216 {
217  for (size_t i = 0; i < FF_ARRAY_ELEMS(tag_list); i++) {
218  if (tag_list[i].id == id)
219  return tag_list[i].name;
220  }
221 
222  return NULL;
223 }
224 
226 {
227  if (!name)
228  return -1;
229 
230  for (size_t i = 0; i < FF_ARRAY_ELEMS(tag_list); i++) {
231  if (!strcmp(tag_list[i].name, name))
232  return tag_list[i].id;
233  }
234 
235  return -1;
236 }
237 
238 static inline void tput16(PutByteContext *pb, const int le, const uint16_t value)
239 {
240  le ? bytestream2_put_le16(pb, value) : bytestream2_put_be16(pb, value);
241 }
242 
243 static inline void tput32(PutByteContext *pb, const int le, const uint32_t value)
244 {
245  le ? bytestream2_put_le32(pb, value) : bytestream2_put_be32(pb, value);
246 }
247 
248 static inline void tput64(PutByteContext *pb, const int le, const uint64_t value)
249 {
250  le ? bytestream2_put_le64(pb, value) : bytestream2_put_be64(pb, value);
251 }
252 
253 static int exif_read_values(void *logctx, GetByteContext *gb, int le, AVExifEntry *entry)
254 {
255  switch (entry->type) {
256  case AV_TIFF_SHORT:
257  case AV_TIFF_LONG:
258  entry->value.uint = av_calloc(entry->count, sizeof(*entry->value.uint));
259  break;
260  case AV_TIFF_SSHORT:
261  case AV_TIFF_SLONG:
262  entry->value.sint = av_calloc(entry->count, sizeof(*entry->value.sint));
263  break;
264  case AV_TIFF_DOUBLE:
265  case AV_TIFF_FLOAT:
266  entry->value.dbl = av_calloc(entry->count, sizeof(*entry->value.dbl));
267  break;
268  case AV_TIFF_RATIONAL:
269  case AV_TIFF_SRATIONAL:
270  entry->value.rat = av_calloc(entry->count, sizeof(*entry->value.rat));
271  break;
272  case AV_TIFF_UNDEFINED:
273  case AV_TIFF_BYTE:
274  entry->value.ubytes = av_mallocz(entry->count);
275  break;
276  case AV_TIFF_SBYTE:
277  entry->value.sbytes = av_mallocz(entry->count);
278  break;
279  case AV_TIFF_STRING:
280  entry->value.str = av_mallocz(entry->count + 1);
281  break;
282  case AV_TIFF_IFD:
283  av_log(logctx, AV_LOG_WARNING, "Bad IFD type for non-IFD tag\n");
284  return AVERROR_INVALIDDATA;
285  }
286  if (!entry->value.ptr)
287  return AVERROR(ENOMEM);
288  switch (entry->type) {
289  case AV_TIFF_SHORT:
290  for (size_t i = 0; i < entry->count; i++)
291  entry->value.uint[i] = ff_tget_short(gb, le);
292  break;
293  case AV_TIFF_LONG:
294  for (size_t i = 0; i < entry->count; i++)
295  entry->value.uint[i] = ff_tget_long(gb, le);
296  break;
297  case AV_TIFF_SSHORT:
298  for (size_t i = 0; i < entry->count; i++)
299  entry->value.sint[i] = (int16_t) ff_tget_short(gb, le);
300  break;
301  case AV_TIFF_SLONG:
302  for (size_t i = 0; i < entry->count; i++)
303  entry->value.sint[i] = (int32_t) ff_tget_long(gb, le);
304  break;
305  case AV_TIFF_DOUBLE:
306  for (size_t i = 0; i < entry->count; i++)
307  entry->value.dbl[i] = ff_tget_double(gb, le);
308  break;
309  case AV_TIFF_FLOAT:
310  for (size_t i = 0; i < entry->count; i++) {
311  av_alias32 alias = { .u32 = ff_tget_long(gb, le) };
312  entry->value.dbl[i] = alias.f32;
313  }
314  break;
315  case AV_TIFF_RATIONAL:
316  case AV_TIFF_SRATIONAL:
317  for (size_t i = 0; i < entry->count; i++) {
318  int32_t num = ff_tget_long(gb, le);
319  int32_t den = ff_tget_long(gb, le);
320  entry->value.rat[i] = av_make_q(num, den);
321  }
322  break;
323  case AV_TIFF_UNDEFINED:
324  case AV_TIFF_BYTE:
325  bytestream2_get_buffer(gb, entry->value.ubytes, entry->count);
326  break;
327  case AV_TIFF_SBYTE:
328  bytestream2_get_buffer(gb, entry->value.sbytes, entry->count);
329  break;
330  case AV_TIFF_STRING:
331  bytestream2_get_buffer(gb, entry->value.str, entry->count);
332  break;
333  }
334 
335  return 0;
336 }
337 
338 static void exif_write_values(PutByteContext *pb, int le, const AVExifEntry *entry)
339 {
340  switch (entry->type) {
341  case AV_TIFF_SHORT:
342  for (size_t i = 0; i < entry->count; i++)
343  tput16(pb, le, entry->value.uint[i]);
344  break;
345  case AV_TIFF_LONG:
346  for (size_t i = 0; i < entry->count; i++)
347  tput32(pb, le, entry->value.uint[i]);
348  break;
349  case AV_TIFF_SSHORT:
350  for (size_t i = 0; i < entry->count; i++)
351  tput16(pb, le, entry->value.sint[i]);
352  break;
353  case AV_TIFF_SLONG:
354  for (size_t i = 0; i < entry->count; i++)
355  tput32(pb, le, entry->value.sint[i]);
356  break;
357  case AV_TIFF_DOUBLE:
358  for (size_t i = 0; i < entry->count; i++) {
359  const av_alias64 a = { .f64 = entry->value.dbl[i] };
360  tput64(pb, le, a.u64);
361  }
362  break;
363  case AV_TIFF_FLOAT:
364  for (size_t i = 0; i < entry->count; i++) {
365  const av_alias32 a = { .f32 = entry->value.dbl[i] };
366  tput32(pb, le, a.u32);
367  }
368  break;
369  case AV_TIFF_RATIONAL:
370  case AV_TIFF_SRATIONAL:
371  for (size_t i = 0; i < entry->count; i++) {
372  tput32(pb, le, entry->value.rat[i].num);
373  tput32(pb, le, entry->value.rat[i].den);
374  }
375  break;
376  case AV_TIFF_UNDEFINED:
377  case AV_TIFF_BYTE:
378  bytestream2_put_buffer(pb, entry->value.ubytes, entry->count);
379  break;
380  case AV_TIFF_SBYTE:
381  bytestream2_put_buffer(pb, entry->value.sbytes, entry->count);
382  break;
383  case AV_TIFF_STRING:
384  bytestream2_put_buffer(pb, entry->value.str, entry->count);
385  break;
386  }
387 }
388 
389 static const uint8_t aoc_header[] = { 'A', 'O', 'C', 0, };
390 static const uint8_t casio_header[] = { 'Q', 'V', 'C', 0, 0, 0, };
391 static const uint8_t foveon_header[] = { 'F', 'O', 'V', 'E', 'O', 'N', 0, 0, };
392 static const uint8_t fuji_header[] = { 'F', 'U', 'J', 'I', };
393 static const uint8_t nikon_header[] = { 'N', 'i', 'k', 'o', 'n', 0, };
394 static const uint8_t olympus1_header[] = { 'O', 'L', 'Y', 'M', 'P', 0, };
395 static const uint8_t olympus2_header[] = { 'O', 'L', 'Y', 'M', 'P', 'U', 'S', 0, 'I', 'I', };
396 static const uint8_t panasonic_header[] = { 'P', 'a', 'n', 'a', 's', 'o', 'n', 'i', 'c', 0, 0, 0, };
397 static const uint8_t sigma_header[] = { 'S', 'I', 'G', 'M', 'A', 0, 0, 0, };
398 static const uint8_t sony_header[] = { 'S', 'O', 'N', 'Y', ' ', 'D', 'S', 'C', ' ', 0, 0, 0, };
399 
401  const uint8_t *header;
402  size_t header_size;
403  int result;
404 };
405 
406 #define MAKERNOTE_STRUCT(h, r) { \
407  .header = (h), \
408  .header_size = sizeof((h)), \
409  .result = (r), \
410 }
411 
412 static const struct exif_makernote_data makernote_data[] = {
422 };
423 
424 /*
425  * derived from Exiv2 MakerNote's article
426  * https://exiv2.org/makernote.html or archived at
427  * https://web.archive.org/web/20250311155857/https://exiv2.org/makernote.html
428  */
430 {
432  return -1;
433 
434  for (int i = 0; i < FF_ARRAY_ELEMS(makernote_data); i++) {
436  return makernote_data[i].result;
437  }
438 
439  if (!memcmp(gb->buffer, nikon_header, sizeof(nikon_header))) {
440  if (bytestream2_get_bytes_left(gb) < 14)
441  return -1;
442  else if (AV_RB32(gb->buffer + 10) == EXIF_MM_LONG || AV_RB32(gb->buffer + 10) == EXIF_II_LONG)
443  return -1;
444  return 8;
445  }
446 
447  return 0;
448 }
449 
450 static int exif_parse_ifd_list(void *logctx, GetByteContext *gb, int le,
451  int depth, AVExifMetadata *ifd);
452 
453 static int exif_decode_tag(void *logctx, GetByteContext *gb, int le,
454  int depth, AVExifEntry *entry)
455 {
456  int ret = 0, makernote_offset = -1, tell, is_ifd, count;
457  enum AVTiffDataType type;
458  uint32_t payload;
459 
460  /* safety check to prevent infinite recursion on malicious IFDs */
461  if (depth > 3)
462  return AVERROR_INVALIDDATA;
463 
464  tell = bytestream2_tell(gb);
465 
466  entry->id = ff_tget_short(gb, le);
467  type = ff_tget_short(gb, le);
468  count = ff_tget_long(gb, le);
469  payload = ff_tget_long(gb, le);
470 
471  av_log(logctx, AV_LOG_DEBUG, "TIFF Tag: id: 0x%04x, type: %d, count: %u, offset: %d, "
472  "payload: %" PRIu32 "\n", entry->id, type, count, tell, payload);
473 
474  is_ifd = type == AV_TIFF_IFD || ff_tis_ifd(entry->id) || entry->id == MAKERNOTE_TAG;
475 
476  if (is_ifd) {
477  if (!payload)
478  goto end;
479  bytestream2_seek(gb, payload, SEEK_SET);
480  }
481 
482  if (entry->id == MAKERNOTE_TAG) {
483  makernote_offset = exif_get_makernote_offset(gb);
484  if (makernote_offset < 0)
485  is_ifd = 0;
486  }
487 
488  if (is_ifd) {
489  entry->type = AV_TIFF_IFD;
490  entry->count = 1;
491  entry->ifd_offset = makernote_offset > 0 ? makernote_offset : 0;
492  if (entry->ifd_offset) {
493  entry->ifd_lead = av_malloc(entry->ifd_offset);
494  if (!entry->ifd_lead)
495  return AVERROR(ENOMEM);
496  bytestream2_get_buffer(gb, entry->ifd_lead, entry->ifd_offset);
497  }
498  ret = exif_parse_ifd_list(logctx, gb, le, depth + 1, &entry->value.ifd);
499  if (ret < 0 && entry->id == MAKERNOTE_TAG) {
500  /*
501  * we guessed that MakerNote was an IFD
502  * but we were probably incorrect at this
503  * point so we try again as a binary blob
504  */
505  av_exif_free(&entry->value.ifd);
506  av_log(logctx, AV_LOG_DEBUG, "unrecognized MakerNote IFD, retrying as blob\n");
507  is_ifd = 0;
508  }
509  }
510 
511  /* inverted condition instead of else so we can fall through from above */
512  if (!is_ifd) {
514  entry->count = count;
515  bytestream2_seek(gb, count * exif_sizes[type] > 4 ? payload : tell + 8, SEEK_SET);
516  ret = exif_read_values(logctx, gb, le, entry);
517  }
518 
519 end:
520  bytestream2_seek(gb, tell + BASE_TAG_SIZE, SEEK_SET);
521 
522  return ret;
523 }
524 
525 static int exif_parse_ifd_list(void *logctx, GetByteContext *gb, int le,
526  int depth, AVExifMetadata *ifd)
527 {
528  uint32_t entries;
529  size_t required_size;
530  void *temp;
531 
532  av_log(logctx, AV_LOG_DEBUG, "parsing IFD list at offset: %d\n", bytestream2_tell(gb));
533 
534  if (bytestream2_get_bytes_left(gb) < 2) {
535  av_log(logctx, AV_LOG_ERROR, "not enough bytes remaining in EXIF buffer: 2 required\n");
536  return AVERROR_INVALIDDATA;
537  }
538 
539  entries = ff_tget_short(gb, le);
540  if (bytestream2_get_bytes_left(gb) < entries * BASE_TAG_SIZE) {
541  av_log(logctx, AV_LOG_ERROR, "not enough bytes remaining in EXIF buffer. entries: %" PRIu32 "\n", entries);
542  return AVERROR_INVALIDDATA;
543  }
544 
545  ifd->count = entries;
546  av_log(logctx, AV_LOG_DEBUG, "entry count for IFD: %u\n", ifd->count);
547 
548  if (av_size_mult(ifd->count, sizeof(*ifd->entries), &required_size) < 0)
549  return AVERROR(ENOMEM);
550  temp = av_fast_realloc(ifd->entries, &ifd->size, required_size);
551  if (!temp) {
552  av_freep(&ifd->entries);
553  return AVERROR(ENOMEM);
554  }
555  ifd->entries = temp;
556 
557  /* entries have pointers in them which can cause issues if */
558  /* they are freed or realloc'd when garbage */
559  memset(ifd->entries, 0, required_size);
560 
561  for (uint32_t i = 0; i < entries; i++) {
562  int ret = exif_decode_tag(logctx, gb, le, depth, &ifd->entries[i]);
563  if (ret < 0)
564  return ret;
565  }
566 
567  /*
568  * at the end of an IFD is an pointer to the next IFD
569  * or zero if there are no more IFDs, which is usually the case
570  */
571  return ff_tget_long(gb, le);
572 }
573 
574 /*
575  * note that this function does not free the entry pointer itself
576  * because it's probably part of a larger array that should be freed
577  * all at once
578  */
580 {
581  if (!entry)
582  return;
583  if (entry->type == AV_TIFF_IFD)
584  av_exif_free(&entry->value.ifd);
585  else
586  av_freep(&entry->value.ptr);
587  av_freep(&entry->ifd_lead);
588 }
589 
591 {
592  if (!ifd)
593  return;
594  if (!ifd->entries) {
595  ifd->count = 0;
596  ifd->size = 0;
597  return;
598  }
599  for (size_t i = 0; i < ifd->count; i++) {
600  AVExifEntry *entry = &ifd->entries[i];
602  }
603  av_freep(&ifd->entries);
604  ifd->count = 0;
605  ifd->size = 0;
606 }
607 
608 static size_t exif_get_ifd_size(const AVExifMetadata *ifd)
609 {
610  /* 6 == 4 + 2; 2-byte entry-count at the beginning */
611  /* plus 4-byte next-IFD pointer at the end */
612  size_t total_size = IFD_EXTRA_SIZE;
613  for (size_t i = 0; i < ifd->count; i++) {
614  const AVExifEntry *entry = &ifd->entries[i];
615  if (entry->type == AV_TIFF_IFD) {
616  total_size += BASE_TAG_SIZE + exif_get_ifd_size(&entry->value.ifd) + entry->ifd_offset;
617  } else {
618  size_t payload_size = entry->count * exif_sizes[entry->type];
619  total_size += BASE_TAG_SIZE + (payload_size > 4 ? payload_size : 0);
620  }
621  }
622  return total_size;
623 }
624 
625 static int exif_write_ifd(void *logctx, PutByteContext *pb, int le, int depth, const AVExifMetadata *ifd)
626 {
627  int offset, ret, tell, tell2;
628  tell = bytestream2_tell_p(pb);
629  tput16(pb, le, ifd->count);
630  offset = tell + IFD_EXTRA_SIZE + BASE_TAG_SIZE * (uint32_t) ifd->count;
631  av_log(logctx, AV_LOG_DEBUG, "writing IFD with %u entries and initial offset %d\n", ifd->count, offset);
632  for (size_t i = 0; i < ifd->count; i++) {
633  const AVExifEntry *entry = &ifd->entries[i];
634  av_log(logctx, AV_LOG_DEBUG, "writing TIFF entry: id: 0x%04" PRIx16 ", type: %d, count: %"
635  PRIu32 ", offset: %d, offset value: %d\n",
636  entry->id, entry->type, entry->count,
638  tput16(pb, le, entry->id);
639  if (entry->id == MAKERNOTE_TAG && entry->type == AV_TIFF_IFD) {
640  size_t ifd_size = exif_get_ifd_size(&entry->value.ifd);
641  tput16(pb, le, AV_TIFF_UNDEFINED);
642  tput32(pb, le, ifd_size);
643  } else {
644  tput16(pb, le, entry->type);
645  tput32(pb, le, entry->count);
646  }
647  if (entry->type == AV_TIFF_IFD) {
648  tput32(pb, le, offset);
649  tell2 = bytestream2_tell_p(pb);
650  bytestream2_seek_p(pb, offset, SEEK_SET);
651  if (entry->ifd_offset)
652  bytestream2_put_buffer(pb, entry->ifd_lead, entry->ifd_offset);
653  ret = exif_write_ifd(logctx, pb, le, depth + 1, &entry->value.ifd);
654  if (ret < 0)
655  return ret;
656  offset += ret + entry->ifd_offset;
657  bytestream2_seek_p(pb, tell2, SEEK_SET);
658  } else {
659  size_t payload_size = entry->count * exif_sizes[entry->type];
660  if (payload_size > 4) {
661  tput32(pb, le, offset);
662  tell2 = bytestream2_tell_p(pb);
663  bytestream2_seek_p(pb, offset, SEEK_SET);
664  exif_write_values(pb, le, entry);
665  offset += payload_size;
666  bytestream2_seek_p(pb, tell2, SEEK_SET);
667  } else {
668  /* zero uninitialized excess payload values */
669  AV_WN32(pb->buffer, 0);
670  exif_write_values(pb, le, entry);
671  bytestream2_seek_p(pb, 4 - payload_size, SEEK_CUR);
672  }
673  }
674  }
675 
676  /*
677  * we write 0 if this is the top-level exif IFD
678  * indicating that there are no more IFD pointers
679  */
680  tput32(pb, le, depth ? offset : 0);
681  return offset - tell;
682 }
683 
684 int av_exif_write(void *logctx, const AVExifMetadata *ifd, AVBufferRef **buffer, enum AVExifHeaderMode header_mode)
685 {
686  AVBufferRef *buf = NULL;
687  size_t size, headsize = 8;
688  PutByteContext pb;
689  int ret, off = 0;
690 
691 #if AV_HAVE_BIGENDIAN
692  int le = 0;
693 #else
694  int le = 1;
695 #endif
696 
697  if (*buffer)
698  return AVERROR(EINVAL);
699 
700  size = exif_get_ifd_size(ifd);
701  switch (header_mode) {
702  case AV_EXIF_EXIF00:
703  off = 6;
704  break;
705  case AV_EXIF_T_OFF:
706  off = 4;
707  break;
708  case AV_EXIF_ASSUME_BE:
709  le = 0;
710  headsize = 0;
711  break;
712  case AV_EXIF_ASSUME_LE:
713  le = 1;
714  headsize = 0;
715  break;
716  }
717  buf = av_buffer_alloc(size + off + headsize);
718  if (!buf)
719  return AVERROR(ENOMEM);
720 
721  if (header_mode == AV_EXIF_EXIF00) {
722  AV_WL32(buf->data, MKTAG('E','x','i','f'));
723  AV_WN16(buf->data + 4, 0);
724  } else if (header_mode == AV_EXIF_T_OFF) {
725  AV_WN32(buf->data, 0);
726  }
727 
728  bytestream2_init_writer(&pb, buf->data + off, buf->size - off);
729 
730  if (header_mode != AV_EXIF_ASSUME_BE && header_mode != AV_EXIF_ASSUME_LE) {
731  /* these constants are be32 in both cases */
732  bytestream2_put_be32(&pb, le ? EXIF_II_LONG : EXIF_MM_LONG);
733  tput32(&pb, le, 8);
734  }
735 
736  ret = exif_write_ifd(logctx, &pb, le, 0, ifd);
737  if (ret < 0) {
738  av_buffer_unref(&buf);
739  av_log(logctx, AV_LOG_ERROR, "error writing EXIF data: %s\n", av_err2str(ret));
740  return ret;
741  }
742 
743  *buffer = buf;
744 
745  return 0;
746 }
747 
748 int av_exif_parse_buffer(void *logctx, const uint8_t *buf, size_t size,
749  AVExifMetadata *ifd, enum AVExifHeaderMode header_mode)
750 {
751  int ret, le;
752  GetByteContext gbytes;
753  if (size > INT_MAX)
754  return AVERROR(EINVAL);
755  size_t off = 0;
756  switch (header_mode) {
757  case AV_EXIF_EXIF00:
758  if (size < 6)
759  return AVERROR_INVALIDDATA;
760  off = 6;
761  /* fallthrough */
762  case AV_EXIF_T_OFF:
763  if (size < 4)
764  return AVERROR_INVALIDDATA;
765  if (!off)
766  off = AV_RB32(buf) + 4;
767  /* fallthrough */
768  case AV_EXIF_TIFF_HEADER: {
769  int ifd_offset;
770  if (size <= off)
771  return AVERROR_INVALIDDATA;
772  bytestream2_init(&gbytes, buf + off, size - off);
773  // read TIFF header
774  ret = ff_tdecode_header(&gbytes, &le, &ifd_offset);
775  if (ret < 0) {
776  av_log(logctx, AV_LOG_ERROR, "invalid TIFF header in EXIF data: %s\n", av_err2str(ret));
777  return ret;
778  }
779  bytestream2_seek(&gbytes, ifd_offset, SEEK_SET);
780  break;
781  }
782  case AV_EXIF_ASSUME_LE:
783  le = 1;
784  bytestream2_init(&gbytes, buf, size);
785  break;
786  case AV_EXIF_ASSUME_BE:
787  le = 0;
788  bytestream2_init(&gbytes, buf, size);
789  break;
790  default:
791  return AVERROR(EINVAL);
792  }
793 
794  /*
795  * parse IFD0 here. If the return value is positive that tells us
796  * there is subimage metadata, but we don't parse that IFD here
797  */
798  ret = exif_parse_ifd_list(logctx, &gbytes, le, 0, ifd);
799  if (ret < 0) {
800  av_exif_free(ifd);
801  av_log(logctx, AV_LOG_ERROR, "error decoding EXIF data: %s\n", av_err2str(ret));
802  return ret;
803  }
804 
805  return bytestream2_tell(&gbytes);
806 }
807 
808 static int attach_displaymatrix(void *logctx, AVFrame *frame, int orientation)
809 {
810  AVFrameSideData *sd;
811  int32_t *matrix;
812  /* invalid orientation */
813  if (orientation < 2 || orientation > 8)
814  return AVERROR_INVALIDDATA;
816  if (!sd) {
817  av_log(logctx, AV_LOG_ERROR, "Could not allocate frame side data\n");
818  return AVERROR(ENOMEM);
819  }
820  matrix = (int32_t *) sd->data;
821 
822  return av_exif_orientation_to_matrix(matrix, orientation);
823 }
824 
825 #define COLUMN_SEP(i, c) ((i) ? ((i) % (c) ? ", " : "\n") : "")
826 
827 static int exif_ifd_to_dict(void *logctx, const char *prefix, const AVExifMetadata *ifd, AVDictionary **metadata)
828 {
829  AVBPrint bp;
830  int ret = 0;
831  char *key = NULL;
832  char *value = NULL;
833 
834  if (!prefix)
835  prefix = "";
836 
837  for (uint16_t i = 0; i < ifd->count; i++) {
838  const AVExifEntry *entry = &ifd->entries[i];
839  const char *name = av_exif_get_tag_name(entry->id);
840  av_bprint_init(&bp, entry->count * 10, AV_BPRINT_SIZE_UNLIMITED);
841  if (*prefix)
842  av_bprintf(&bp, "%s/", prefix);
843  if (name)
844  av_bprintf(&bp, "%s", name);
845  else
846  av_bprintf(&bp, "0x%04X", entry->id);
847  ret = av_bprint_finalize(&bp, &key);
848  if (ret < 0)
849  goto end;
850  av_bprint_init(&bp, entry->count * 10, AV_BPRINT_SIZE_UNLIMITED);
851  switch (entry->type) {
852  case AV_TIFF_IFD:
853  ret = exif_ifd_to_dict(logctx, key, &entry->value.ifd, metadata);
854  if (ret < 0)
855  goto end;
856  break;
857  case AV_TIFF_SHORT:
858  case AV_TIFF_LONG:
859  for (uint32_t j = 0; j < entry->count; j++)
860  av_bprintf(&bp, "%s%7" PRIu32, COLUMN_SEP(j, 8), (uint32_t)entry->value.uint[j]);
861  break;
862  case AV_TIFF_SSHORT:
863  case AV_TIFF_SLONG:
864  for (uint32_t j = 0; j < entry->count; j++)
865  av_bprintf(&bp, "%s%7" PRId32, COLUMN_SEP(j, 8), (int32_t)entry->value.sint[j]);
866  break;
867  case AV_TIFF_RATIONAL:
868  case AV_TIFF_SRATIONAL:
869  for (uint32_t j = 0; j < entry->count; j++)
870  av_bprintf(&bp, "%s%7i:%-7i", COLUMN_SEP(j, 4), entry->value.rat[j].num, entry->value.rat[j].den);
871  break;
872  case AV_TIFF_DOUBLE:
873  case AV_TIFF_FLOAT:
874  for (uint32_t j = 0; j < entry->count; j++)
875  av_bprintf(&bp, "%s%.15g", COLUMN_SEP(j, 4), entry->value.dbl[j]);
876  break;
877  case AV_TIFF_STRING:
878  av_bprintf(&bp, "%s", entry->value.str);
879  break;
880  case AV_TIFF_UNDEFINED:
881  case AV_TIFF_BYTE:
882  for (uint32_t j = 0; j < entry->count; j++)
883  av_bprintf(&bp, "%s%3i", COLUMN_SEP(j, 16), entry->value.ubytes[j]);
884  break;
885  case AV_TIFF_SBYTE:
886  for (uint32_t j = 0; j < entry->count; j++)
887  av_bprintf(&bp, "%s%3i", COLUMN_SEP(j, 16), entry->value.sbytes[j]);
888  break;
889  }
890  if (entry->type != AV_TIFF_IFD) {
891  if (!av_bprint_is_complete(&bp)) {
892  av_bprint_finalize(&bp, NULL);
893  ret = AVERROR(ENOMEM);
894  goto end;
895  }
896  ret = av_bprint_finalize(&bp, &value);
897  if (ret < 0)
898  goto end;
900  if (ret < 0)
901  goto end;
902  key = NULL;
903  value = NULL;
904  } else {
905  av_freep(&key);
906  }
907  }
908 
909 end:
910  av_freep(&key);
911  av_freep(&value);
912  return ret;
913 }
914 
915 int av_exif_ifd_to_dict(void *logctx, const AVExifMetadata *ifd, AVDictionary **metadata)
916 {
917  return exif_ifd_to_dict(logctx, "", ifd, metadata);
918 }
919 
920 #if FF_API_OLD_EXIF
921 int avpriv_exif_decode_ifd(void *logctx, const uint8_t *buf, int size,
922  int le, int depth, AVDictionary **metadata)
923 {
924  AVExifMetadata ifd = { 0 };
925  GetByteContext gb;
926  int ret;
927  bytestream2_init(&gb, buf, size);
928  ret = exif_parse_ifd_list(logctx, &gb, le, depth, &ifd);
929  if (ret < 0)
930  return ret;
931  ret = av_exif_ifd_to_dict(logctx, &ifd, metadata);
932  av_exif_free(&ifd);
933  return ret;
934 }
935 #endif /* FF_API_OLD_EXIF */
936 
937 static int exif_attach_ifd(void *logctx, AVFrame *frame, const AVExifMetadata *ifd, AVBufferRef *og)
938 {
939  const AVExifEntry *orient = NULL;
940  AVFrameSideData *sd;
941  AVExifMetadata *cloned = NULL;
942  AVBufferRef *written = NULL;
943  int ret;
944 
945  for (size_t i = 0; i < ifd->count; i++) {
946  const AVExifEntry *entry = &ifd->entries[i];
947  if (entry->id == ORIENTATION_TAG && entry->count > 0 && entry->type == AV_TIFF_SHORT) {
948  orient = entry;
949  break;
950  }
951  }
952 
953  if (orient && orient->value.uint[0] > 1) {
954  av_log(logctx, AV_LOG_DEBUG, "found nontrivial EXIF orientation: %" PRIu64 "\n", orient->value.uint[0]);
955  ret = attach_displaymatrix(logctx, frame, orient->value.uint[0]);
956  if (ret < 0) {
957  av_log(logctx, AV_LOG_WARNING, "unable to attach displaymatrix from EXIF\n");
958  } else {
959  const AVExifEntry *cloned_orient;
960  cloned = av_exif_clone_ifd(ifd);
961  if (!cloned) {
962  ret = AVERROR(ENOMEM);
963  goto end;
964  }
965  // will have the same offset in the clone as in the original
966  cloned_orient = &cloned->entries[orient - ifd->entries];
967  cloned_orient->value.uint[0] = 1;
968  }
969  }
970 
971  ret = av_exif_ifd_to_dict(logctx, cloned ? cloned : ifd, &frame->metadata);
972  if (ret < 0)
973  return ret;
974 
975  if (cloned || !og) {
976  ret = av_exif_write(logctx, cloned ? cloned : ifd, &written, AV_EXIF_TIFF_HEADER);
977  if (ret < 0)
978  goto end;
979  }
980 
981  sd = av_frame_new_side_data_from_buf(frame, AV_FRAME_DATA_EXIF, written ? written : og);
982  if (!sd) {
983  if (written)
984  av_buffer_unref(&written);
985  ret = AVERROR(ENOMEM);
986  goto end;
987  }
988 
989  ret = 0;
990 
991 end:
992  if (og && written && ret >= 0)
993  av_buffer_unref(&og); // as though we called new_side_data on og;
994  av_exif_free(cloned);
995  av_free(cloned);
996  return ret;
997 }
998 
999 #define EXIF_COPY(fname, srcname) do { \
1000  size_t sz; \
1001  if (av_size_mult(src->count, sizeof(*(fname)), &sz) < 0) { \
1002  ret = AVERROR(ENOMEM); \
1003  goto end; \
1004  } \
1005  (fname) = av_memdup((srcname), sz); \
1006  if (!(fname)) { \
1007  ret = AVERROR(ENOMEM); \
1008  goto end; \
1009  } \
1010 } while (0)
1011 
1013 {
1014  int ret = 0;
1015 
1016  dst->count = src->count;
1017  dst->id = src->id;
1018  dst->type = src->type;
1019 
1020  dst->ifd_offset = src->ifd_offset;
1021  if (src->ifd_lead) {
1022  dst->ifd_lead = av_memdup(src->ifd_lead, src->ifd_offset);
1023  if (!dst->ifd_lead) {
1024  ret = AVERROR(ENOMEM);
1025  goto end;
1026  }
1027  } else {
1028  dst->ifd_lead = NULL;
1029  }
1030 
1031  switch(src->type) {
1032  case AV_TIFF_IFD: {
1033  AVExifMetadata *cloned = av_exif_clone_ifd(&src->value.ifd);
1034  if (!cloned) {
1035  ret = AVERROR(ENOMEM);
1036  goto end;
1037  }
1038  dst->value.ifd = *cloned;
1039  av_freep(&cloned);
1040  break;
1041  }
1042  case AV_TIFF_SHORT:
1043  case AV_TIFF_LONG:
1044  EXIF_COPY(dst->value.uint, src->value.uint);
1045  break;
1046  case AV_TIFF_SLONG:
1047  case AV_TIFF_SSHORT:
1048  EXIF_COPY(dst->value.sint, src->value.sint);
1049  break;
1050  case AV_TIFF_RATIONAL:
1051  case AV_TIFF_SRATIONAL:
1052  EXIF_COPY(dst->value.rat, src->value.rat);
1053  break;
1054  case AV_TIFF_DOUBLE:
1055  case AV_TIFF_FLOAT:
1056  EXIF_COPY(dst->value.dbl, src->value.dbl);
1057  break;
1058  case AV_TIFF_BYTE:
1059  case AV_TIFF_UNDEFINED:
1060  EXIF_COPY(dst->value.ubytes, src->value.ubytes);
1061  break;
1062  case AV_TIFF_SBYTE:
1063  EXIF_COPY(dst->value.sbytes, src->value.sbytes);
1064  break;
1065  case AV_TIFF_STRING:
1066  EXIF_COPY(dst->value.str, src->value.str);
1067  break;
1068  }
1069 
1070  return 0;
1071 
1072 end:
1073  av_freep(&dst->ifd_lead);
1074  if (src->type == AV_TIFF_IFD)
1075  av_exif_free(&dst->value.ifd);
1076  else
1077  av_freep(&dst->value.ptr);
1078  memset(dst, 0, sizeof(*dst));
1079 
1080  return ret;
1081 }
1082 
1083 static int exif_get_entry(void *logctx, AVExifMetadata *ifd, uint16_t id, int depth, AVExifEntry **value)
1084 {
1085  int offset = 1;
1086 
1087  if (!ifd || ifd->entries && !ifd->count || ifd->count && !ifd->entries || !value)
1088  return AVERROR(EINVAL);
1089 
1090  for (size_t i = 0; i < ifd->count; i++) {
1091  if (ifd->entries[i].id == id) {
1092  *value = &ifd->entries[i];
1093  return i + offset;
1094  }
1095  if (ifd->entries[i].type == AV_TIFF_IFD) {
1096  if (depth < 3) {
1097  int ret = exif_get_entry(logctx, &ifd->entries[i].value.ifd, id, depth + 1, value);
1098  if (ret)
1099  return ret < 0 ? ret : ret + offset;
1100  }
1101  offset += ifd->entries[i].value.ifd.count;
1102  }
1103  }
1104 
1105  return 0;
1106 }
1107 
1108 int av_exif_get_entry(void *logctx, AVExifMetadata *ifd, uint16_t id, int recursive, AVExifEntry **value)
1109 {
1110  return exif_get_entry(logctx, ifd, id, recursive ? 0 : INT_MAX, value);
1111 }
1112 
1113 int av_exif_set_entry(void *logctx, AVExifMetadata *ifd, uint16_t id, enum AVTiffDataType type,
1114  uint32_t count, const uint8_t *ifd_lead, uint32_t ifd_offset, const void *value)
1115 {
1116  void *temp;
1117  int ret = 0;
1118  AVExifEntry *entry = NULL;
1119  AVExifEntry src = { 0 };
1120 
1121  if (!ifd || ifd->entries && !ifd->count || ifd->count && !ifd->entries
1122  || ifd_lead && !ifd_offset || !ifd_lead && ifd_offset
1123  || !value || ifd->count == 0xFFFFu)
1124  return AVERROR(EINVAL);
1125 
1126  ret = av_exif_get_entry(logctx, ifd, id, 0, &entry);
1127  if (ret < 0)
1128  return ret;
1129 
1130  if (entry) {
1132  } else {
1133  size_t required_size;
1134  ret = av_size_mult(ifd->count + 1, sizeof(*ifd->entries), &required_size);
1135  if (ret < 0)
1136  return AVERROR(ENOMEM);
1137  temp = av_fast_realloc(ifd->entries, &ifd->size, required_size);
1138  if (!temp)
1139  return AVERROR(ENOMEM);
1140  ifd->entries = temp;
1141  entry = &ifd->entries[ifd->count++];
1142  }
1143 
1144  src.count = count;
1145  src.id = id;
1146  src.type = type;
1147  src.ifd_lead = (uint8_t *) ifd_lead;
1148  src.ifd_offset = ifd_offset;
1149  if (type == AV_TIFF_IFD)
1150  src.value.ifd = * (const AVExifMetadata *) value;
1151  else
1152  src.value.ptr = (void *) value;
1153 
1155 
1156  if (ret < 0)
1157  ifd->count--;
1158 
1159  return ret;
1160 }
1161 
1162 static int exif_remove_entry(void *logctx, AVExifMetadata *ifd, uint16_t id, int depth)
1163 {
1164  int32_t index = -1;
1165  int ret = 0;
1166 
1167  if (!ifd || ifd->entries && !ifd->count || ifd->count && !ifd->entries)
1168  return AVERROR(EINVAL);
1169 
1170  for (size_t i = 0; i < ifd->count; i++) {
1171  if (ifd->entries[i].id == id) {
1172  index = i;
1173  break;
1174  }
1175  if (ifd->entries[i].type == AV_TIFF_IFD && depth < 3) {
1176  ret = exif_remove_entry(logctx, &ifd->entries[i].value.ifd, id, depth + 1);
1177  if (ret)
1178  return ret;
1179  }
1180  }
1181 
1182  if (index < 0)
1183  return 0;
1184  exif_free_entry(&ifd->entries[index]);
1185 
1186  if (index == --ifd->count) {
1187  if (!index)
1188  av_freep(&ifd->entries);
1189  return 1;
1190  }
1191 
1192  memmove(&ifd->entries[index], &ifd->entries[index + 1], (ifd->count - index) * sizeof(*ifd->entries));
1193 
1194  return 1 + (ifd->count - index);
1195 }
1196 
1197 int av_exif_remove_entry(void *logctx, AVExifMetadata *ifd, uint16_t id, int recursive)
1198 {
1199  return exif_remove_entry(logctx, ifd, id, recursive ? 0 : INT_MAX);
1200 }
1201 
1203 {
1204  AVExifMetadata *ret = av_mallocz(sizeof(*ret));
1205  if (!ret)
1206  return NULL;
1207 
1208  ret->count = ifd->count;
1209  if (ret->count) {
1210  size_t required_size;
1211  if (av_size_mult(ret->count, sizeof(*ret->entries), &required_size) < 0)
1212  goto fail;
1213  ret->entries = av_fast_realloc(NULL, &ret->size, required_size);
1214  if (!ret->entries)
1215  goto fail;
1216  }
1217 
1218  for (size_t i = 0; i < ret->count; i++) {
1219  const AVExifEntry *entry = &ifd->entries[i];
1220  AVExifEntry *ret_entry = &ret->entries[i];
1221  int status = exif_clone_entry(ret_entry, entry);
1222  if (status < 0)
1223  goto fail;
1224  }
1225 
1226  return ret;
1227 
1228 fail:
1229  av_exif_free(ret);
1230  av_free(ret);
1231  return NULL;
1232 }
1233 
1234 int ff_exif_attach_ifd(void *logctx, AVFrame *frame, const AVExifMetadata *ifd)
1235 {
1236  return exif_attach_ifd(logctx, frame, ifd, NULL);
1237 }
1238 
1239 int ff_exif_attach_buffer(void *logctx, AVFrame *frame, AVBufferRef *data, enum AVExifHeaderMode header_mode)
1240 {
1241  int ret;
1242  AVExifMetadata ifd = { 0 };
1243 
1244  ret = av_exif_parse_buffer(logctx, data->data, data->size, &ifd, header_mode);
1245  if (ret < 0)
1246  goto end;
1247 
1248  ret = exif_attach_ifd(logctx, frame, &ifd, data);
1249 
1250 end:
1251  av_exif_free(&ifd);
1252  return ret;
1253 }
1254 
1255 static const int rotation_lut[2][4] = {
1256  {1, 8, 3, 6}, {4, 7, 2, 5},
1257 };
1258 
1260 {
1261  double rotation = av_display_rotation_get(matrix);
1262  // determinant
1263  int vflip = ((int64_t)matrix[0] * (int64_t)matrix[4]
1264  - (int64_t)matrix[1] * (int64_t)matrix[3]) < 0;
1265  if (!isfinite(rotation))
1266  return 0;
1267  int rot = (int)(rotation + 0.5);
1268  rot = (((rot % 360) + 360) % 360) / 90;
1269  return rotation_lut[vflip][rot];
1270 }
1271 
1273 {
1274  switch (orientation) {
1275  case 1:
1277  break;
1278  case 2:
1281  break;
1282  case 3:
1284  break;
1285  case 4:
1288  break;
1289  case 5:
1292  break;
1293  case 6:
1295  break;
1296  case 7:
1299  break;
1300  case 8:
1302  break;
1303  default:
1304  return AVERROR(EINVAL);
1305  }
1306 
1307  return 0;
1308 }
1309 
1310 int ff_exif_sanitize_ifd(void *logctx, const AVFrame *frame, AVExifMetadata *ifd)
1311 {
1312  int ret = 0;
1313  AVFrameSideData *sd_orient = NULL;
1314  AVExifEntry *or = NULL;
1315  AVExifEntry *iw = NULL;
1316  AVExifEntry *ih = NULL;
1317  AVExifEntry *pw = NULL;
1318  AVExifEntry *ph = NULL;
1319  uint64_t orientation = 1;
1320  uint64_t w = frame->width;
1321  uint64_t h = frame->height;
1322  int rewrite = 0;
1323 
1325 
1326  if (sd_orient)
1327  orientation = av_exif_matrix_to_orientation((int32_t *) sd_orient->data);
1328  if (orientation != 1)
1329  av_log(logctx, AV_LOG_DEBUG, "matrix contains nontrivial EXIF orientation: %" PRIu64 "\n", orientation);
1330 
1331  for (size_t i = 0; i < ifd->count; i++) {
1332  AVExifEntry *entry = &ifd->entries[i];
1333  if (entry->id == ORIENTATION_TAG && entry->count > 0 && entry->type == AV_TIFF_SHORT) {
1334  or = entry;
1335  continue;
1336  }
1337  if (entry->id == IMAGE_WIDTH_TAG && entry->count > 0 && entry->type == AV_TIFF_LONG) {
1338  iw = entry;
1339  continue;
1340  }
1341  if (entry->id == IMAGE_LENGTH_TAG && entry->count > 0 && entry->type == AV_TIFF_LONG) {
1342  ih = entry;
1343  continue;
1344  }
1345  if (entry->id == EXIFIFD_TAG && entry->type == AV_TIFF_IFD) {
1346  AVExifMetadata *exif = &entry->value.ifd;
1347  for (size_t j = 0; j < exif->count; j++) {
1348  AVExifEntry *exifentry = &exif->entries[j];
1349  if (exifentry->id == PIXEL_X_TAG && exifentry->count > 0 && exifentry->type == AV_TIFF_SHORT) {
1350  pw = exifentry;
1351  continue;
1352  }
1353  if (exifentry->id == PIXEL_Y_TAG && exifentry->count > 0 && exifentry->type == AV_TIFF_SHORT) {
1354  ph = exifentry;
1355  continue;
1356  }
1357  }
1358  }
1359  }
1360 
1361  if (or && or->value.uint[0] != orientation) {
1362  rewrite = 1;
1363  or->value.uint[0] = orientation;
1364  }
1365  if (iw && iw->value.uint[0] != w) {
1366  rewrite = 1;
1367  iw->value.uint[0] = w;
1368  }
1369  if (ih && ih->value.uint[0] != h) {
1370  rewrite = 1;
1371  ih->value.uint[0] = h;
1372  }
1373  if (pw && pw->value.uint[0] != w) {
1374  rewrite = 1;
1375  pw->value.uint[0] = w;
1376  }
1377  if (ph && ph->value.uint[0] != h) {
1378  rewrite = 1;
1379  ph->value.uint[0] = h;
1380  }
1381  if (!or && orientation != 1) {
1382  rewrite = 1;
1383  ret = av_exif_set_entry(logctx, ifd, ORIENTATION_TAG, AV_TIFF_SHORT, 1, NULL, 0, &orientation);
1384  if (ret < 0)
1385  goto end;
1386  }
1387  if (!iw && w) {
1388  rewrite = 1;
1389  ret = av_exif_set_entry(logctx, ifd, IMAGE_WIDTH_TAG, AV_TIFF_LONG, 1, NULL, 0, &w);
1390  if (ret < 0)
1391  goto end;
1392  }
1393  if (!ih && h) {
1394  rewrite = 1;
1395  ret = av_exif_set_entry(logctx, ifd, IMAGE_LENGTH_TAG, AV_TIFF_LONG, 1, NULL, 0, &h);
1396  if (ret < 0)
1397  goto end;
1398  }
1399  if (!pw && w && w < 0xFFFFu || !ph && h && h < 0xFFFFu) {
1400  AVExifMetadata *exif;
1401  AVExifEntry *exif_entry;
1402  int exif_found = av_exif_get_entry(logctx, ifd, EXIFIFD_TAG, 0, &exif_entry);
1403  rewrite = 1;
1404  if (exif_found < 0)
1405  goto end;
1406  if (exif_found > 0) {
1407  exif = &exif_entry->value.ifd;
1408  } else {
1409  AVExifMetadata exif_new = { 0 };
1410  ret = av_exif_set_entry(logctx, ifd, EXIFIFD_TAG, AV_TIFF_IFD, 1, NULL, 0, &exif_new);
1411  if (ret < 0) {
1412  av_exif_free(&exif_new);
1413  goto end;
1414  }
1415  exif = &ifd->entries[ifd->count - 1].value.ifd;
1416  }
1417  if (!pw && w && w < 0xFFFFu) {
1418  ret = av_exif_set_entry(logctx, exif, PIXEL_X_TAG, AV_TIFF_SHORT, 1, NULL, 0, &w);
1419  if (ret < 0)
1420  goto end;
1421  }
1422  if (!ph && h && h < 0xFFFFu) {
1423  ret = av_exif_set_entry(logctx, exif, PIXEL_Y_TAG, AV_TIFF_SHORT, 1, NULL, 0, &h);
1424  if (ret < 0)
1425  goto end;
1426  }
1427  }
1428 
1429  return rewrite;
1430 
1431 end:
1432  return ret;
1433 }
1434 
1435 int ff_exif_get_buffer(void *logctx, const AVFrame *frame, AVBufferRef **buffer_ptr, enum AVExifHeaderMode header_mode)
1436 {
1437  AVFrameSideData *sd_exif = NULL;
1438  AVBufferRef *buffer = NULL;
1439  AVExifMetadata ifd = { 0 };
1440  int ret = 0;
1441  int rewrite = 0;
1442 
1443  if (!buffer_ptr || *buffer_ptr)
1444  return AVERROR(EINVAL);
1445 
1447  if (!sd_exif)
1448  return 0;
1449 
1450  ret = av_exif_parse_buffer(logctx, sd_exif->data, sd_exif->size, &ifd, AV_EXIF_TIFF_HEADER);
1451  if (ret < 0)
1452  goto end;
1453 
1454  rewrite = ff_exif_sanitize_ifd(logctx, frame, &ifd);
1455  if (rewrite < 0) {
1456  ret = rewrite;
1457  goto end;
1458  }
1459 
1460  if (rewrite) {
1461  ret = av_exif_write(logctx, &ifd, &buffer, header_mode);
1462  if (ret < 0)
1463  goto end;
1464 
1465  *buffer_ptr = buffer;
1466  } else {
1467  *buffer_ptr = av_buffer_ref(sd_exif->buf);
1468  if (!*buffer_ptr) {
1469  ret = AVERROR(ENOMEM);
1470  goto end;
1471  }
1472  }
1473 
1474  av_exif_free(&ifd);
1475  return rewrite;
1476 
1477 end:
1478  av_exif_free(&ifd);
1479  return ret;
1480 }
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:608
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:748
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
av_frame_new_side_data
AVFrameSideData * av_frame_new_side_data(AVFrame *frame, enum AVFrameSideDataType type, size_t size)
Add a new side data to a frame.
Definition: frame.c:645
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:684
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:198
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:915
int64_t
long long int64_t
Definition: coverity.c:34
EXIF_II_LONG
#define EXIF_II_LONG
Definition: exif.c:42
metadata
Stream codec metadata
Definition: ogg-flac-chained-meta.txt:2
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:1272
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
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
data
const char data[16]
Definition: mxf.c:149
exif_decode_tag
static int exif_decode_tag(void *logctx, GetByteContext *gb, int le, int depth, AVExifEntry *entry)
Definition: exif.c:453
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:1113
sony_header
static const uint8_t sony_header[]
Definition: exif.c:398
exif_tag::id
uint16_t id
Definition: exif.c:59
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
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
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:921
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:390
exif_read_values
static int exif_read_values(void *logctx, GetByteContext *gb, int le, AVExifEntry *entry)
Definition: exif.c:253
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:1012
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:590
exif_parse_ifd_list
static int exif_parse_ifd_list(void *logctx, GetByteContext *gb, int le, int depth, AVExifMetadata *ifd)
Definition: exif.c:525
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:401
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:402
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:827
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:1202
tput64
static void tput64(PutByteContext *pb, const int le, const uint64_t value)
Definition: exif.c:248
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:1162
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:338
attach_displaymatrix
static int attach_displaymatrix(void *logctx, AVFrame *frame, int orientation)
Definition: exif.c:808
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:225
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:392
ff_exif_attach_buffer
int ff_exif_attach_buffer(void *logctx, AVFrame *frame, AVBufferRef *data, enum AVExifHeaderMode header_mode)
Attach the data buffer to the frame.
Definition: exif.c:1239
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:394
bytestream2_get_buffer
static av_always_inline unsigned int bytestream2_get_buffer(GetByteContext *g, uint8_t *dst, unsigned int size)
Definition: bytestream.h:267
av_frame_new_side_data_from_buf
AVFrameSideData * av_frame_new_side_data_from_buf(AVFrame *frame, enum AVFrameSideDataType type, AVBufferRef *buf)
Add a new side data to a frame from an existing AVBufferRef.
Definition: frame.c:636
MAKERNOTE_STRUCT
#define MAKERNOTE_STRUCT(h, r)
Definition: exif.c:406
AVExifEntry::count
uint32_t count
Definition: exif.h:88
COLUMN_SEP
#define COLUMN_SEP(i, c)
Definition: exif.c:825
olympus2_header
static const uint8_t olympus2_header[]
Definition: exif.c:395
AV_EXIF_ASSUME_LE
@ AV_EXIF_ASSUME_LE
skip the TIFF header, assume little endian
Definition: exif.h:65
foveon_header
static const uint8_t foveon_header[]
Definition: exif.c:391
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:625
panasonic_header
static const uint8_t panasonic_header[]
Definition: exif.c:396
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:240
AV_WN32
#define AV_WN32(p, v)
Definition: intreadwrite.h:372
exif_makernote_data::result
int result
Definition: exif.c:403
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:400
PutByteContext::buffer
uint8_t * buffer
Definition: bytestream.h:38
exif_attach_ifd
static int exif_attach_ifd(void *logctx, AVFrame *frame, const AVExifMetadata *ifd, AVBufferRef *og)
Definition: exif.c:937
size
int size
Definition: twinvq_data.h:10344
sigma_header
static const uint8_t sigma_header[]
Definition: exif.c:397
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:412
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_remove_entry
int av_exif_remove_entry(void *logctx, AVExifMetadata *ifd, uint16_t id, int recursive)
Remove an entry from the provided EXIF metadata struct.
Definition: exif.c:1197
nikon_header
static const uint8_t nikon_header[]
Definition: exif.c:393
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:238
tput32
static void tput32(PutByteContext *pb, const int le, const uint32_t value)
Definition: exif.c:243
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:1083
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
ff_exif_attach_ifd
int ff_exif_attach_ifd(void *logctx, AVFrame *frame, const AVExifMetadata *ifd)
Attach an already-parsed EXIF metadata struct to the frame as a side data buffer.
Definition: exif.c:1234
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
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:429
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:99
aoc_header
static const uint8_t aoc_header[]
Definition: exif.c:389
exif_tag
Definition: exif.c:57
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:999
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: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:1310
av_exif_get_entry
int av_exif_get_entry(void *logctx, AVExifMetadata *ifd, uint16_t id, int recursive, AVExifEntry **value)
Get an entry with the tagged ID from the EXIF metadata struct.
Definition: exif.c:1108
exif_free_entry
static void exif_free_entry(AVExifEntry *entry)
Definition: exif.c:579
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
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:1435
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:215
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:1255
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:1259
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