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