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