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  *
5  * This file is part of FFmpeg.
6  *
7  * FFmpeg is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * FFmpeg is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with FFmpeg; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 
22 /**
23  * @file
24  * EXIF metadata parser
25  * @author Thilo Borgmann <thilo.borgmann _at_ mail.de>
26  */
27 
28 #include "exif.h"
29 
30 
31 static const char *exif_get_tag_name(uint16_t id)
32 {
33  int i;
34 
35  for (i = 0; i < FF_ARRAY_ELEMS(tag_list); i++) {
36  if (tag_list[i].id == id)
37  return tag_list[i].name;
38  }
39 
40  return NULL;
41 }
42 
43 
44 static int exif_add_metadata(void *logctx, int count, int type,
45  const char *name, const char *sep,
46  GetByteContext *gb, int le,
47  AVDictionary **metadata)
48 {
49  switch(type) {
50  case 0:
51  av_log(logctx, AV_LOG_WARNING,
52  "Invalid TIFF tag type 0 found for %s with size %d\n",
53  name, count);
54  return 0;
55  case TIFF_DOUBLE : return ff_tadd_doubles_metadata(count, name, sep, gb, le, metadata);
56  case TIFF_SSHORT : return ff_tadd_shorts_metadata(count, name, sep, gb, le, 1, metadata);
57  case TIFF_SHORT : return ff_tadd_shorts_metadata(count, name, sep, gb, le, 0, metadata);
58  case TIFF_SBYTE : return ff_tadd_bytes_metadata(count, name, sep, gb, le, 1, metadata);
59  case TIFF_BYTE :
60  case TIFF_UNDEFINED: return ff_tadd_bytes_metadata(count, name, sep, gb, le, 0, metadata);
61  case TIFF_STRING : return ff_tadd_string_metadata(count, name, gb, le, metadata);
62  case TIFF_SRATIONAL:
63  case TIFF_RATIONAL : return ff_tadd_rational_metadata(count, name, sep, gb, le, metadata);
64  case TIFF_SLONG :
65  case TIFF_LONG : return ff_tadd_long_metadata(count, name, sep, gb, le, metadata);
66  default:
67  avpriv_request_sample(logctx, "TIFF tag type (%u)", type);
68  return 0;
69  };
70 }
71 
72 
73 static int exif_decode_tag(void *logctx, GetByteContext *gbytes, int le,
74  int depth, AVDictionary **metadata)
75 {
76  int ret, cur_pos;
77  unsigned id, count;
78  enum TiffTypes type;
79 
80  if (depth > 2) {
81  return 0;
82  }
83 
84  ff_tread_tag(gbytes, le, &id, &type, &count, &cur_pos);
85 
86  if (!bytestream2_tell(gbytes)) {
87  bytestream2_seek(gbytes, cur_pos, SEEK_SET);
88  return 0;
89  }
90 
91  // read count values and add it metadata
92  // store metadata or proceed with next IFD
93  ret = ff_tis_ifd(id);
94  if (ret) {
95  ret = ff_exif_decode_ifd(logctx, gbytes, le, depth + 1, metadata);
96  } else {
97  const char *name = exif_get_tag_name(id);
98  char *use_name = (char*) name;
99 
100  if (!use_name) {
101  use_name = av_malloc(7);
102  if (!use_name) {
103  return AVERROR(ENOMEM);
104  }
105  snprintf(use_name, 7, "0x%04X", id);
106  }
107 
108  ret = exif_add_metadata(logctx, count, type, use_name, NULL,
109  gbytes, le, metadata);
110 
111  if (!name) {
112  av_freep(&use_name);
113  }
114  }
115 
116  bytestream2_seek(gbytes, cur_pos, SEEK_SET);
117 
118  return ret;
119 }
120 
121 
122 int ff_exif_decode_ifd(void *logctx, GetByteContext *gbytes,
123  int le, int depth, AVDictionary **metadata)
124 {
125  int i, ret;
126  int entries;
127 
128  entries = ff_tget_short(gbytes, le);
129 
130  if (bytestream2_get_bytes_left(gbytes) < entries * 12) {
131  return AVERROR_INVALIDDATA;
132  }
133 
134  for (i = 0; i < entries; i++) {
135  if ((ret = exif_decode_tag(logctx, gbytes, le, depth, metadata)) < 0) {
136  return ret;
137  }
138  }
139 
140  // return next IDF offset or 0x000000000 or a value < 0 for failure
141  return ff_tget_long(gbytes, le);
142 }
143 
144 int avpriv_exif_decode_ifd(void *logctx, const uint8_t *buf, int size,
145  int le, int depth, AVDictionary **metadata)
146 {
147  GetByteContext gb;
148 
149  bytestream2_init(&gb, buf, size);
150 
151  return ff_exif_decode_ifd(logctx, &gb, le, depth, metadata);
152 }
#define NULL
Definition: coverity.c:32
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:59
int ff_exif_decode_ifd(void *logctx, GetByteContext *gbytes, int le, int depth, AVDictionary **metadata)
Definition: exif.c:122
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:182
static const struct exif_tag tag_list[]
Definition: exif.h:43
int ff_tadd_doubles_metadata(int count, const char *name, const char *sep, GetByteContext *gb, int le, AVDictionary **metadata)
Adds count doubles converted to a string into the metadata dictionary.
Definition: tiff_common.c:147
#define avpriv_request_sample(...)
static av_always_inline void bytestream2_init(GetByteContext *g, const uint8_t *buf, int buf_size)
Definition: bytestream.h:133
GLint GLenum type
Definition: opengl_enc.c:104
int ff_tadd_rational_metadata(int count, const char *name, const char *sep, GetByteContext *gb, int le, AVDictionary **metadata)
Adds count rationals converted to a string into the metadata dictionary.
Definition: tiff_common.c:82
EXIF metadata parser.
static int exif_add_metadata(void *logctx, int count, int type, const char *name, const char *sep, GetByteContext *gb, int le, AVDictionary **metadata)
Definition: exif.c:44
uint8_t
#define av_malloc(s)
ptrdiff_t size
Definition: opengl_enc.c:100
#define av_log(a,...)
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:259
static const char * exif_get_tag_name(uint16_t id)
Definition: exif.c:31
unsigned ff_tget_short(GetByteContext *gb, int le)
Reads a short from the bytestream using given endianness.
Definition: tiff_common.c:43
static av_always_inline unsigned int bytestream2_get_bytes_left(GetByteContext *g)
Definition: bytestream.h:154
GLsizei count
Definition: opengl_enc.c:108
static int exif_decode_tag(void *logctx, GetByteContext *gbytes, int le, int depth, AVDictionary **metadata)
Definition: exif.c:73
unsigned ff_tget_long(GetByteContext *gb, int le)
Reads a long from the bytestream using given endianness.
Definition: tiff_common.c:49
TiffTypes
data type identifiers for TIFF tags
Definition: tiff_common.h:37
#define FF_ARRAY_ELEMS(a)
int ff_tis_ifd(unsigned tag)
Returns a value > 0 if the tag is a known IFD-tag.
Definition: tiff_common.c:31
static av_always_inline int bytestream2_tell(GetByteContext *g)
Definition: bytestream.h:188
int avpriv_exif_decode_ifd(void *logctx, const uint8_t *buf, int size, int le, int depth, AVDictionary **metadata)
Recursively decodes all IFD&#39;s and adds included TAGS into the metadata dictionary.
Definition: exif.c:144
void * buf
Definition: avisynth_c.h:766
int ff_tadd_long_metadata(int count, const char *name, const char *sep, GetByteContext *gb, int le, AVDictionary **metadata)
Adds count longs converted to a string into the metadata dictionary.
Definition: tiff_common.c:116
#define snprintf
Definition: snprintf.h:34
int ff_tadd_shorts_metadata(int count, const char *name, const char *sep, GetByteContext *gb, int le, int is_signed, AVDictionary **metadata)
Adds count shorts converted to a string into the metadata dictionary.
Definition: tiff_common.c:178
int ff_tadd_bytes_metadata(int count, const char *name, const char *sep, GetByteContext *gb, int le, int is_signed, AVDictionary **metadata)
Adds count bytes converted to a string into the metadata dictionary.
Definition: tiff_common.c:210
int ff_tadd_string_metadata(int count, const char *name, GetByteContext *gb, int le, AVDictionary **metadata)
Adds a string of count characters into the metadata dictionary.
Definition: tiff_common.c:241
static av_always_inline int bytestream2_seek(GetByteContext *g, int offset, int whence)
Definition: bytestream.h:208
int ff_tread_tag(GetByteContext *gb, int le, unsigned *tag, unsigned *type, unsigned *count, int *next)
Reads the first 3 fields of a TIFF tag, which are the tag id, the tag type and the count of values fo...
Definition: tiff_common.c:286
#define av_freep(p)
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
char name[EXIF_TAG_NAME_LENGTH]
Definition: exif.h:39
enum AVCodecID id
const char * name
Definition: opengl_enc.c:102