GCC Code Coverage Report
Directory: ../../../ffmpeg/ Exec Total Coverage
File: src/libavcodec/tiff_common.c Lines: 92 133 69.2 %
Date: 2020-10-23 17:01:47 Branches: 69 116 59.5 %

Line Branch Exec Source
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
931
int ff_tis_ifd(unsigned tag)
32
{
33
    int i;
34
3652
    for (i = 0; i < FF_ARRAY_ELEMS(ifd_tags); i++) {
35
2753
        if (ifd_tags[i] == tag) {
36
32
            return i + 1;
37
        }
38
    }
39
899
    return 0;
40
}
41
42
43
1601
unsigned ff_tget_short(GetByteContext *gb, int le)
44
{
45
1601
    return le ? bytestream2_get_le16(gb) : bytestream2_get_be16(gb);
46
}
47
48
49
2637
unsigned ff_tget_long(GetByteContext *gb, int le)
50
{
51
2637
    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
1689
unsigned ff_tget(GetByteContext *gb, int type, int le)
63
{
64

1689
    switch (type) {
65
    case TIFF_BYTE:  return bytestream2_get_byte(gb);
66
173
    case TIFF_SHORT: return ff_tget_short(gb, le);
67
1516
    case TIFF_LONG:  return ff_tget_long(gb, le);
68
    default:         return UINT_MAX;
69
    }
70
}
71
72
15420
static const char *auto_sep(int count, const char *sep, int i, int columns)
73
{
74
15420
    if (sep)
75
4
        return i ? sep : "";
76

15416
    if (i && i%columns) {
77
14232
        return ", ";
78
    } else
79
1184
        return columns < count ? "\n" : "";
80
}
81
82
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

82
    if (count >= INT_MAX / sizeof(int64_t) || count <= 0)
91
        return AVERROR_INVALIDDATA;
92
82
    if (bytestream2_get_bytes_left(gb) < count * sizeof(int64_t))
93
        return AVERROR_INVALIDDATA;
94
95
82
    av_bprint_init(&bp, 10 * count, AV_BPRINT_SIZE_UNLIMITED);
96
97
164
    for (i = 0; i < count; i++) {
98
82
        nom   = ff_tget_long(gb, le);
99
82
        denom = ff_tget_long(gb, le);
100
82
        av_bprintf(&bp, "%s%7"PRId32":%-7"PRId32, auto_sep(count, sep, i, 4), nom, denom);
101
    }
102
103
82
    if ((i = av_bprint_finalize(&bp, &ap))) {
104
        return i;
105
    }
106
82
    if (!ap) {
107
        return AVERROR(ENOMEM);
108
    }
109
110
82
    av_dict_set(metadata, name, ap, AV_DICT_DONT_STRDUP_VAL);
111
112
82
    return 0;
113
}
114
115
116
12
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

12
    if (count >= INT_MAX / sizeof(int32_t) || count <= 0)
124
        return AVERROR_INVALIDDATA;
125
12
    if (bytestream2_get_bytes_left(gb) < count * sizeof(int32_t))
126
        return AVERROR_INVALIDDATA;
127
128
12
    av_bprint_init(&bp, 10 * count, AV_BPRINT_SIZE_UNLIMITED);
129
130
24
    for (i = 0; i < count; i++) {
131
12
        av_bprintf(&bp, "%s%7i", auto_sep(count, sep, i, 8), ff_tget_long(gb, le));
132
    }
133
134
12
    if ((i = av_bprint_finalize(&bp, &ap))) {
135
        return i;
136
    }
137
12
    if (!ap) {
138
        return AVERROR(ENOMEM);
139
    }
140
141
12
    av_dict_set(metadata, name, ap, AV_DICT_DONT_STRDUP_VAL);
142
143
12
    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
110
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

110
    if (count >= INT_MAX / sizeof(int16_t) || count <= 0)
186
        return AVERROR_INVALIDDATA;
187
110
    if (bytestream2_get_bytes_left(gb) < count * sizeof(int16_t))
188
        return AVERROR_INVALIDDATA;
189
190
110
    av_bprint_init(&bp, 10 * count, AV_BPRINT_SIZE_UNLIMITED);
191
192
222
    for (i = 0; i < count; i++) {
193
112
        int v = is_signed ? (int16_t)ff_tget_short(gb, le) :  ff_tget_short(gb, le);
194
112
        av_bprintf(&bp, "%s%5i", auto_sep(count, sep, i, 8), v);
195
    }
196
197
110
    if ((i = av_bprint_finalize(&bp, &ap))) {
198
        return i;
199
    }
200
110
    if (!ap) {
201
        return AVERROR(ENOMEM);
202
    }
203
204
110
    av_dict_set(metadata, name, ap, AV_DICT_DONT_STRDUP_VAL);
205
206
110
    return 0;
207
}
208
209
210
46
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

46
    if (count >= INT_MAX / sizeof(int8_t) || count < 0)
218
        return AVERROR_INVALIDDATA;
219
46
    if (bytestream2_get_bytes_left(gb) < count * sizeof(int8_t))
220
        return AVERROR_INVALIDDATA;
221
222
46
    av_bprint_init(&bp, 10 * count, AV_BPRINT_SIZE_UNLIMITED);
223
224
15260
    for (i = 0; i < count; i++) {
225
15214
        int v = is_signed ? (int8_t)bytestream2_get_byte(gb) :  bytestream2_get_byte(gb);
226
15214
        av_bprintf(&bp, "%s%3i", auto_sep(count, sep, i, 16), v);
227
    }
228
229
46
    if ((i = av_bprint_finalize(&bp, &ap))) {
230
        return i;
231
    }
232
46
    if (!ap) {
233
        return AVERROR(ENOMEM);
234
    }
235
236
46
    av_dict_set(metadata, name, ap, AV_DICT_DONT_STRDUP_VAL);
237
238
46
    return 0;
239
}
240
241
64
int ff_tadd_string_metadata(int count, const char *name,
242
                            GetByteContext *gb, int le, AVDictionary **metadata)
243
{
244
    char *value;
245
246

64
    if (bytestream2_get_bytes_left(gb) < count || count < 0)
247
        return AVERROR_INVALIDDATA;
248
249
64
    value = av_malloc(count + 1);
250
64
    if (!value)
251
        return AVERROR(ENOMEM);
252
253
64
    bytestream2_get_bufferu(gb, value, count);
254
64
    value[count] = 0;
255
256
64
    av_dict_set(metadata, name, value, AV_DICT_DONT_STRDUP_VAL);
257
64
    return 0;
258
}
259
260
261
35
int ff_tdecode_header(GetByteContext *gb, int *le, int *ifd_offset)
262
{
263
35
    if (bytestream2_get_bytes_left(gb) < 8) {
264
        return AVERROR_INVALIDDATA;
265
    }
266
267
35
    *le = bytestream2_get_le16u(gb);
268
35
    if (*le == AV_RB16("II")) {
269
25
        *le = 1;
270
10
    } else if (*le == AV_RB16("MM")) {
271
10
        *le = 0;
272
    } else {
273
        return AVERROR_INVALIDDATA;
274
    }
275
276
35
    if (ff_tget_short(gb, *le) != 42) {
277
        return AVERROR_INVALIDDATA;
278
    }
279
280
35
    *ifd_offset = ff_tget_long(gb, *le);
281
282
35
    return 0;
283
}
284
285
286
615
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
615
    *tag    = ff_tget_short(gb, le);
293
615
    *type   = ff_tget_short(gb, le);
294
615
    *count  = ff_tget_long (gb, le);
295
296
615
    ifd_tag    = ff_tis_ifd(*tag);
297

615
    valid_type = *type != 0 && *type < FF_ARRAY_ELEMS(type_sizes);
298
299
615
    *next = bytestream2_tell(gb) + 4;
300
301
    // check for valid type
302
615
    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


615
    if (ifd_tag || (*count > 4 || !(type_sizes[*type] * (*count) <= 4 || *type == TIFF_STRING))) {
309
265
        bytestream2_seek(gb, ff_tget_long (gb, le), SEEK_SET);
310
    }
311
312
615
    return 0;
313
}