FFmpeg: libavcodec/exif.c Source File

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

Generated on Sat Oct 18 2025 19:22:02 for FFmpeg by   doxygen 1.8.17

AltStyle によって変換されたページ (->オリジナル) /