FFmpeg
tiff_common.c
Go to the documentation of this file.
1 /*
2  * TIFF Common Routines
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  * TIFF Common Routines
25  * @author Thilo Borgmann <thilo.borgmann _at_ mail.de>
26  */
27 
28 #include "tiff_common.h"
29 
30 
31 int ff_tis_ifd(unsigned tag)
32 {
33  int i;
34  for (i = 0; i < FF_ARRAY_ELEMS(ifd_tags); i++) {
35  if (ifd_tags[i] == tag) {
36  return i + 1;
37  }
38  }
39  return 0;
40 }
41 
42 
43 unsigned ff_tget_short(GetByteContext *gb, int le)
44 {
45  return le ? bytestream2_get_le16(gb) : bytestream2_get_be16(gb);
46 }
47 
48 
49 unsigned ff_tget_long(GetByteContext *gb, int le)
50 {
51  return le ? bytestream2_get_le32(gb) : bytestream2_get_be32(gb);
52 }
53 
54 
55 double ff_tget_double(GetByteContext *gb, int le)
56 {
57  av_alias64 i = { .u64 = le ? bytestream2_get_le64(gb) : bytestream2_get_be64(gb)};
58  return i.f64;
59 }
60 
61 
62 unsigned ff_tget(GetByteContext *gb, int type, int le)
63 {
64  switch (type) {
65  case TIFF_BYTE: return bytestream2_get_byte(gb);
66  case TIFF_SHORT: return ff_tget_short(gb, le);
67  case TIFF_LONG: return ff_tget_long(gb, le);
68  default: return UINT_MAX;
69  }
70 }
71 
72 static const char *auto_sep(int count, const char *sep, int i, int columns)
73 {
74  if (sep)
75  return i ? sep : "";
76  if (i && i%columns) {
77  return ", ";
78  } else
79  return columns < count ? "\n" : "";
80 }
81 
82 int ff_tadd_rational_metadata(int count, const char *name, const char *sep,
83  GetByteContext *gb, int le, AVDictionary **metadata)
84 {
85  AVBPrint bp;
86  char *ap;
87  int32_t nom, denom;
88  int i;
89 
90  if (count >= INT_MAX / sizeof(int64_t) || count <= 0)
91  return AVERROR_INVALIDDATA;
92  if (bytestream2_get_bytes_left(gb) < count * sizeof(int64_t))
93  return AVERROR_INVALIDDATA;
94 
95  av_bprint_init(&bp, 10 * count, AV_BPRINT_SIZE_UNLIMITED);
96 
97  for (i = 0; i < count; i++) {
98  nom = ff_tget_long(gb, le);
99  denom = ff_tget_long(gb, le);
100  av_bprintf(&bp, "%s%7"PRId32":%-7"PRId32, auto_sep(count, sep, i, 4), nom, denom);
101  }
102 
103  if ((i = av_bprint_finalize(&bp, &ap))) {
104  return i;
105  }
106  if (!ap) {
107  return AVERROR(ENOMEM);
108  }
109 
110  av_dict_set(metadata, name, ap, AV_DICT_DONT_STRDUP_VAL);
111 
112  return 0;
113 }
114 
115 
116 int ff_tadd_long_metadata(int count, const char *name, const char *sep,
117  GetByteContext *gb, int le, AVDictionary **metadata)
118 {
119  AVBPrint bp;
120  char *ap;
121  int i;
122 
123  if (count >= INT_MAX / sizeof(int32_t) || count <= 0)
124  return AVERROR_INVALIDDATA;
125  if (bytestream2_get_bytes_left(gb) < count * sizeof(int32_t))
126  return AVERROR_INVALIDDATA;
127 
128  av_bprint_init(&bp, 10 * count, AV_BPRINT_SIZE_UNLIMITED);
129 
130  for (i = 0; i < count; i++) {
131  av_bprintf(&bp, "%s%7i", auto_sep(count, sep, i, 8), ff_tget_long(gb, le));
132  }
133 
134  if ((i = av_bprint_finalize(&bp, &ap))) {
135  return i;
136  }
137  if (!ap) {
138  return AVERROR(ENOMEM);
139  }
140 
141  av_dict_set(metadata, name, ap, AV_DICT_DONT_STRDUP_VAL);
142 
143  return 0;
144 }
145 
146 
147 int ff_tadd_doubles_metadata(int count, const char *name, const char *sep,
148  GetByteContext *gb, int le, AVDictionary **metadata)
149 {
150  AVBPrint bp;
151  char *ap;
152  int i;
153 
154  if (count >= INT_MAX / sizeof(int64_t) || count <= 0)
155  return AVERROR_INVALIDDATA;
156  if (bytestream2_get_bytes_left(gb) < count * sizeof(int64_t))
157  return AVERROR_INVALIDDATA;
158 
159  av_bprint_init(&bp, 10 * count, 100 * count);
160 
161  for (i = 0; i < count; i++) {
162  av_bprintf(&bp, "%s%.15g", auto_sep(count, sep, i, 4), ff_tget_double(gb, le));
163  }
164 
165  if ((i = av_bprint_finalize(&bp, &ap))) {
166  return i;
167  }
168  if (!ap) {
169  return AVERROR(ENOMEM);
170  }
171 
172  av_dict_set(metadata, name, ap, AV_DICT_DONT_STRDUP_VAL);
173 
174  return 0;
175 }
176 
177 
178 int ff_tadd_shorts_metadata(int count, const char *name, const char *sep,
179  GetByteContext *gb, int le, int is_signed, AVDictionary **metadata)
180 {
181  AVBPrint bp;
182  char *ap;
183  int i;
184 
185  if (count >= INT_MAX / sizeof(int16_t) || count <= 0)
186  return AVERROR_INVALIDDATA;
187  if (bytestream2_get_bytes_left(gb) < count * sizeof(int16_t))
188  return AVERROR_INVALIDDATA;
189 
190  av_bprint_init(&bp, 10 * count, AV_BPRINT_SIZE_UNLIMITED);
191 
192  for (i = 0; i < count; i++) {
193  int v = is_signed ? (int16_t)ff_tget_short(gb, le) : ff_tget_short(gb, le);
194  av_bprintf(&bp, "%s%5i", auto_sep(count, sep, i, 8), v);
195  }
196 
197  if ((i = av_bprint_finalize(&bp, &ap))) {
198  return i;
199  }
200  if (!ap) {
201  return AVERROR(ENOMEM);
202  }
203 
204  av_dict_set(metadata, name, ap, AV_DICT_DONT_STRDUP_VAL);
205 
206  return 0;
207 }
208 
209 
210 int ff_tadd_bytes_metadata(int count, const char *name, const char *sep,
211  GetByteContext *gb, int le, int is_signed, AVDictionary **metadata)
212 {
213  AVBPrint bp;
214  char *ap;
215  int i;
216 
217  if (count >= INT_MAX / sizeof(int8_t) || count < 0)
218  return AVERROR_INVALIDDATA;
219  if (bytestream2_get_bytes_left(gb) < count * sizeof(int8_t))
220  return AVERROR_INVALIDDATA;
221 
222  av_bprint_init(&bp, 10 * count, AV_BPRINT_SIZE_UNLIMITED);
223 
224  for (i = 0; i < count; i++) {
225  int v = is_signed ? (int8_t)bytestream2_get_byte(gb) : bytestream2_get_byte(gb);
226  av_bprintf(&bp, "%s%3i", auto_sep(count, sep, i, 16), v);
227  }
228 
229  if ((i = av_bprint_finalize(&bp, &ap))) {
230  return i;
231  }
232  if (!ap) {
233  return AVERROR(ENOMEM);
234  }
235 
236  av_dict_set(metadata, name, ap, AV_DICT_DONT_STRDUP_VAL);
237 
238  return 0;
239 }
240 
241 int ff_tadd_string_metadata(int count, const char *name,
242  GetByteContext *gb, int le, AVDictionary **metadata)
243 {
244  char *value;
245 
246  if (bytestream2_get_bytes_left(gb) < count || count < 0)
247  return AVERROR_INVALIDDATA;
248 
249  value = av_malloc(count + 1);
250  if (!value)
251  return AVERROR(ENOMEM);
252 
253  bytestream2_get_bufferu(gb, value, count);
254  value[count] = 0;
255 
257  return 0;
258 }
259 
260 
261 int ff_tdecode_header(GetByteContext *gb, int *le, int *ifd_offset)
262 {
263  if (bytestream2_get_bytes_left(gb) < 8) {
264  return AVERROR_INVALIDDATA;
265  }
266 
267  *le = bytestream2_get_le16u(gb);
268  if (*le == AV_RB16("II")) {
269  *le = 1;
270  } else if (*le == AV_RB16("MM")) {
271  *le = 0;
272  } else {
273  return AVERROR_INVALIDDATA;
274  }
275 
276  if (ff_tget_short(gb, *le) != 42) {
277  return AVERROR_INVALIDDATA;
278  }
279 
280  *ifd_offset = ff_tget_long(gb, *le);
281 
282  return 0;
283 }
284 
285 
286 int ff_tread_tag(GetByteContext *gb, int le, unsigned *tag, unsigned *type,
287  unsigned *count, int *next)
288 {
289  int ifd_tag;
290  int valid_type;
291 
292  *tag = ff_tget_short(gb, le);
293  *type = ff_tget_short(gb, le);
294  *count = ff_tget_long (gb, le);
295 
296  ifd_tag = ff_tis_ifd(*tag);
297  valid_type = *type != 0 && *type < FF_ARRAY_ELEMS(type_sizes);
298 
299  *next = bytestream2_tell(gb) + 4;
300 
301  // check for valid type
302  if (!valid_type) {
303  return AVERROR_INVALIDDATA;
304  }
305 
306  // seek to offset if this is an IFD-tag or
307  // if count values do not fit into the offset value
308  if (ifd_tag || (*count > 4 || !(type_sizes[*type] * (*count) <= 4 || *type == TIFF_STRING))) {
309  bytestream2_seek(gb, ff_tget_long (gb, le), SEEK_SET);
310  }
311 
312  return 0;
313 }
ff_tadd_string_metadata
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
AV_BPRINT_SIZE_UNLIMITED
#define AV_BPRINT_SIZE_UNLIMITED
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
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
av_bprint_finalize
int av_bprint_finalize(AVBPrint *buf, char **ret_str)
Finalize a print buffer.
Definition: bprint.c:235
av_bprint_init
void av_bprint_init(AVBPrint *buf, unsigned size_init, unsigned size_max)
Definition: bprint.c:69
GetByteContext
Definition: bytestream.h:33
auto_sep
static const char * auto_sep(int count, const char *sep, int i, int columns)
Definition: tiff_common.c:72
bytestream2_seek
static av_always_inline int bytestream2_seek(GetByteContext *g, int offset, int whence)
Definition: bytestream.h:208
TIFF_LONG
@ TIFF_LONG
Definition: tiff_common.h:41
AVDictionary
Definition: dict.c:30
ff_tadd_rational_metadata
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
av_malloc
#define av_malloc(s)
Definition: tableprint_vlc.h:31
ff_tadd_long_metadata
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
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:74
TIFF_SHORT
@ TIFF_SHORT
Definition: tiff_common.h:40
TIFF_STRING
@ TIFF_STRING
Definition: tiff_common.h:39
ff_tadd_shorts_metadata
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
int32_t
int32_t
Definition: audio_convert.c:194
ff_tget_short
unsigned ff_tget_short(GetByteContext *gb, int le)
Reads a short from the bytestream using given endianness.
Definition: tiff_common.c:43
tiff_common.h
TIFF_BYTE
@ TIFF_BYTE
Definition: tiff_common.h:38
bytestream2_get_bytes_left
static av_always_inline int bytestream2_get_bytes_left(GetByteContext *g)
Definition: bytestream.h:154
bytestream2_tell
static av_always_inline int bytestream2_tell(GetByteContext *g)
Definition: bytestream.h:188
ff_tread_tag
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
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:31
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:269
ff_tget_long
unsigned ff_tget_long(GetByteContext *gb, int le)
Reads a long from the bytestream using given endianness.
Definition: tiff_common.c:49
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
tag
uint32_t tag
Definition: movenc.c:1532
av_bprintf
void av_bprintf(AVBPrint *buf, const char *fmt,...)
Definition: bprint.c:94
FF_ARRAY_ELEMS
#define FF_ARRAY_ELEMS(a)
Definition: sinewin_tablegen_template.c:38
ff_tget_double
double ff_tget_double(GetByteContext *gb, int le)
Reads a double from the bytestream using given endianness.
Definition: tiff_common.c:55
ifd_tags
static const uint16_t ifd_tags[]
Definition: tiff_common.h:58
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:261
bytestream2_get_bufferu
static av_always_inline unsigned int bytestream2_get_bufferu(GetByteContext *g, uint8_t *dst, unsigned int size)
Definition: bytestream.h:273
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:70
ff_tadd_doubles_metadata
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
ff_tadd_bytes_metadata
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
AVERROR_INVALIDDATA
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:59
type_sizes
static const uint8_t type_sizes[14]
sizes of various TIFF field types (string size = 100)
Definition: tiff_common.h:54
ff_tget
unsigned ff_tget(GetByteContext *gb, int type, int le)
Reads a byte from the bytestream using given endianness.
Definition: tiff_common.c:62
AV_RB16
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_WB32 unsigned int_TMPL AV_WB24 unsigned int_TMPL AV_RB16
Definition: bytestream.h:94