Browse code

avcodec/tiff: Refactor TIFF tag related functions to share the code.

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>

Thilo Borgmann authored on 2013/08/13 02:32:40
Showing 5 changed files
... ...
@@ -426,7 +426,7 @@ OBJS-$(CONFIG_TARGA_Y216_DECODER)      += targa_y216dec.o
426 426
 OBJS-$(CONFIG_THEORA_DECODER)          += xiph.o
427 427
 OBJS-$(CONFIG_THP_DECODER)             += mjpegdec.o mjpeg.o
428 428
 OBJS-$(CONFIG_TIERTEXSEQVIDEO_DECODER) += tiertexseqv.o
429
-OBJS-$(CONFIG_TIFF_DECODER)            += tiff.o lzw.o faxcompr.o tiff_data.o
429
+OBJS-$(CONFIG_TIFF_DECODER)            += tiff.o lzw.o faxcompr.o tiff_data.o tiff_common.o
430 430
 OBJS-$(CONFIG_TIFF_ENCODER)            += tiffenc.o rle.o lzwenc.o tiff_data.o
431 431
 OBJS-$(CONFIG_TMV_DECODER)             += tmv.o cga_data.o
432 432
 OBJS-$(CONFIG_TRUEHD_DECODER)          += mlpdec.o mlpdsp.o
... ...
@@ -70,38 +70,6 @@ typedef struct TiffContext {
70 70
     TiffGeoTag *geotags;
71 71
 } TiffContext;
72 72
 
73
-static unsigned tget_short(GetByteContext *gb, int le)
74
-{
75
-    unsigned v = le ? bytestream2_get_le16(gb) : bytestream2_get_be16(gb);
76
-    return v;
77
-}
78
-
79
-static unsigned tget_long(GetByteContext *gb, int le)
80
-{
81
-    unsigned v = le ? bytestream2_get_le32(gb) : bytestream2_get_be32(gb);
82
-    return v;
83
-}
84
-
85
-static double tget_double(GetByteContext *gb, int le)
86
-{
87
-    av_alias64 i = { .u64 = le ? bytestream2_get_le64(gb) : bytestream2_get_be64(gb)};
88
-    return i.f64;
89
-}
90
-
91
-static unsigned tget(GetByteContext *gb, int type, int le)
92
-{
93
-    switch (type) {
94
-    case TIFF_BYTE:
95
-        return bytestream2_get_byte(gb);
96
-    case TIFF_SHORT:
97
-        return tget_short(gb, le);
98
-    case TIFF_LONG:
99
-        return tget_long(gb, le);
100
-    default:
101
-        return UINT_MAX;
102
-    }
103
-}
104
-
105 73
 static void free_geotags(TiffContext *const s)
106 74
 {
107 75
     int i;
... ...
@@ -245,111 +213,13 @@ static char *doubles2str(double *dp, int count, const char *sep)
245 245
     return ap0;
246 246
 }
247 247
 
248
-static char *shorts2str(int16_t *sp, int count, const char *sep)
249
-{
250
-    int i;
251
-    char *ap, *ap0;
252
-    uint64_t component_len;
253
-    if (!sep) sep = ", ";
254
-    component_len = 7LL + strlen(sep);
255
-    if (count >= (INT_MAX - 1)/component_len)
256
-        return NULL;
257
-    ap = av_malloc(component_len * count + 1);
258
-    if (!ap)
259
-        return NULL;
260
-    ap0   = ap;
261
-    ap[0] = '\0';
262
-    for (i = 0; i < count; i++) {
263
-        unsigned l = snprintf(ap, component_len, "%d%s", sp[i], sep);
264
-        if (l >= component_len) {
265
-            av_free(ap0);
266
-            return NULL;
267
-        }
268
-        ap += l;
269
-    }
270
-    ap0[strlen(ap0) - strlen(sep)] = '\0';
271
-    return ap0;
272
-}
273
-
274
-static int add_doubles_metadata(int count,
275
-                                const char *name, const char *sep,
276
-                                TiffContext *s, AVFrame *frame)
277
-{
278
-    char *ap;
279
-    int i;
280
-    double *dp;
281
-
282
-    if (count >= INT_MAX / sizeof(int64_t) || count <= 0)
283
-        return AVERROR_INVALIDDATA;
284
-    if (bytestream2_get_bytes_left(&s->gb) < count * sizeof(int64_t))
285
-        return AVERROR_INVALIDDATA;
286
-
287
-    dp = av_malloc(count * sizeof(double));
288
-    if (!dp)
289
-        return AVERROR(ENOMEM);
290
-
291
-    for (i = 0; i < count; i++)
292
-        dp[i] = tget_double(&s->gb, s->le);
293
-    ap = doubles2str(dp, count, sep);
294
-    av_freep(&dp);
295
-    if (!ap)
296
-        return AVERROR(ENOMEM);
297
-    av_dict_set(avpriv_frame_get_metadatap(frame), name, ap, AV_DICT_DONT_STRDUP_VAL);
298
-    return 0;
299
-}
300
-
301
-static int add_shorts_metadata(int count, const char *name,
302
-                               const char *sep, TiffContext *s, AVFrame *frame)
303
-{
304
-    char *ap;
305
-    int i;
306
-    int16_t *sp;
307
-
308
-    if (count >= INT_MAX / sizeof(int16_t) || count <= 0)
309
-        return AVERROR_INVALIDDATA;
310
-    if (bytestream2_get_bytes_left(&s->gb) < count * sizeof(int16_t))
311
-        return AVERROR_INVALIDDATA;
312
-
313
-    sp = av_malloc(count * sizeof(int16_t));
314
-    if (!sp)
315
-        return AVERROR(ENOMEM);
316
-
317
-    for (i = 0; i < count; i++)
318
-        sp[i] = tget_short(&s->gb, s->le);
319
-    ap = shorts2str(sp, count, sep);
320
-    av_freep(&sp);
321
-    if (!ap)
322
-        return AVERROR(ENOMEM);
323
-    av_dict_set(avpriv_frame_get_metadatap(frame), name, ap, AV_DICT_DONT_STRDUP_VAL);
324
-    return 0;
325
-}
326
-
327
-static int add_string_metadata(int count, const char *name,
328
-                               TiffContext *s, AVFrame *frame)
329
-{
330
-    char *value;
331
-
332
-    if (bytestream2_get_bytes_left(&s->gb) < count || count < 0)
333
-        return AVERROR_INVALIDDATA;
334
-
335
-    value = av_malloc(count + 1);
336
-    if (!value)
337
-        return AVERROR(ENOMEM);
338
-
339
-    bytestream2_get_bufferu(&s->gb, value, count);
340
-    value[count] = 0;
341
-
342
-    av_dict_set(avpriv_frame_get_metadatap(frame), name, value, AV_DICT_DONT_STRDUP_VAL);
343
-    return 0;
344
-}
345
-
346 248
 static int add_metadata(int count, int type,
347 249
                         const char *name, const char *sep, TiffContext *s, AVFrame *frame)
348 250
 {
349 251
     switch(type) {
350
-    case TIFF_DOUBLE: return add_doubles_metadata(count, name, sep, s, frame);
351
-    case TIFF_SHORT : return add_shorts_metadata(count, name, sep, s, frame);
352
-    case TIFF_STRING: return add_string_metadata(count, name, s, frame);
252
+    case TIFF_DOUBLE: return ff_tadd_doubles_metadata(count, name, sep, &s->gb, s->le, avpriv_frame_get_metadatap(frame));
253
+    case TIFF_SHORT : return ff_tadd_shorts_metadata(count, name, sep, &s->gb, s->le, avpriv_frame_get_metadatap(frame));
254
+    case TIFF_STRING: return ff_tadd_string_metadata(count, name, &s->gb, s->le, avpriv_frame_get_metadatap(frame));
353 255
     default         : return AVERROR_INVALIDDATA;
354 256
     };
355 257
 }
... ...
@@ -702,14 +572,8 @@ static int tiff_decode_tag(TiffContext *s, AVFrame *frame)
702 702
     uint32_t *pal;
703 703
     double *dp;
704 704
 
705
-    tag   = tget_short(&s->gb, s->le);
706
-    type  = tget_short(&s->gb, s->le);
707
-    count = tget_long(&s->gb, s->le);
708
-    start = bytestream2_tell(&s->gb) + 4;
709
-
710
-    if (type == 0 || type >= FF_ARRAY_ELEMS(type_sizes)) {
711
-        av_log(s->avctx, AV_LOG_DEBUG, "Unknown tiff type (%u) encountered\n",
712
-               type);
705
+    ret = ff_tread_tag(&s->gb, s->le, &tag, &type, &count, &start);
706
+    if (ret < 0) {
713 707
         goto end;
714 708
     }
715 709
 
... ...
@@ -717,10 +581,10 @@ static int tiff_decode_tag(TiffContext *s, AVFrame *frame)
717 717
         switch (type) {
718 718
         case TIFF_BYTE:
719 719
         case TIFF_SHORT:
720
-            value = tget(&s->gb, type, s->le);
720
+            value = ff_tget(&s->gb, type, s->le);
721 721
             break;
722 722
         case TIFF_LONG:
723
-            off   = tget_long(&s->gb, s->le);
723
+            off   = ff_tget_long(&s->gb, s->le);
724 724
             value = off;
725 725
             break;
726 726
         case TIFF_STRING:
... ...
@@ -728,14 +592,12 @@ static int tiff_decode_tag(TiffContext *s, AVFrame *frame)
728 728
                 break;
729 729
             }
730 730
         default:
731
-            off   = tget_long(&s->gb, s->le);
731
+            off   = bytestream2_tell(&s->gb);
732 732
             value = UINT_MAX;
733
-            bytestream2_seek(&s->gb, off, SEEK_SET);
734 733
         }
735 734
     } else {
736 735
         if (type_sizes[type] * count > 4) {
737
-            off   = tget_long(&s->gb, s->le);
738
-            bytestream2_seek(&s->gb, off, SEEK_SET);
736
+            off   = bytestream2_tell(&s->gb);
739 737
         }
740 738
     }
741 739
 
... ...
@@ -768,7 +630,7 @@ static int tiff_decode_tag(TiffContext *s, AVFrame *frame)
768 768
                 if (bytestream2_get_bytes_left(&s->gb) < type_sizes[type] * count)
769 769
                     return AVERROR_INVALIDDATA;
770 770
                 for (i = 0; i < count; i++)
771
-                    s->bpp += tget(&s->gb, type, s->le);
771
+                    s->bpp += ff_tget(&s->gb, type, s->le);
772 772
                 break;
773 773
             default:
774 774
                 s->bpp = -1;
... ...
@@ -908,7 +770,7 @@ static int tiff_decode_tag(TiffContext *s, AVFrame *frame)
908 908
             for (i = 0; i < count / 3; i++) {
909 909
                 if (k == 2)
910 910
                     pal[i] = 0xFFU << 24;
911
-                j =  (tget(&s->gb, type, s->le) >> off) << (k * 8);
911
+                j =  (ff_tget(&s->gb, type, s->le) >> off) << (k * 8);
912 912
                 pal[i] |= j;
913 913
             }
914 914
         }
... ...
@@ -942,7 +804,7 @@ static int tiff_decode_tag(TiffContext *s, AVFrame *frame)
942 942
     case TIFF_GEO_KEY_DIRECTORY:
943 943
         ADD_METADATA(1, "GeoTIFF_Version", NULL);
944 944
         ADD_METADATA(2, "GeoTIFF_Key_Revision", ".");
945
-        s->geotag_count   = tget_short(&s->gb, s->le);
945
+        s->geotag_count   = ff_tget_short(&s->gb, s->le);
946 946
         if (s->geotag_count > count / 4 - 1) {
947 947
             s->geotag_count = count / 4 - 1;
948 948
             av_log(s->avctx, AV_LOG_WARNING, "GeoTIFF key directory buffer shorter than specified\n");
... ...
@@ -958,14 +820,14 @@ static int tiff_decode_tag(TiffContext *s, AVFrame *frame)
958 958
             goto end;
959 959
         }
960 960
         for (i = 0; i < s->geotag_count; i++) {
961
-            s->geotags[i].key    = tget_short(&s->gb, s->le);
962
-            s->geotags[i].type   = tget_short(&s->gb, s->le);
963
-            s->geotags[i].count  = tget_short(&s->gb, s->le);
961
+            s->geotags[i].key    = ff_tget_short(&s->gb, s->le);
962
+            s->geotags[i].type   = ff_tget_short(&s->gb, s->le);
963
+            s->geotags[i].count  = ff_tget_short(&s->gb, s->le);
964 964
 
965 965
             if (!s->geotags[i].type)
966
-                s->geotags[i].val  = get_geokey_val(s->geotags[i].key, tget_short(&s->gb, s->le));
966
+                s->geotags[i].val  = get_geokey_val(s->geotags[i].key, ff_tget_short(&s->gb, s->le));
967 967
             else
968
-                s->geotags[i].offset = tget_short(&s->gb, s->le);
968
+                s->geotags[i].offset = ff_tget_short(&s->gb, s->le);
969 969
         }
970 970
         break;
971 971
     case TIFF_GEO_DOUBLE_PARAMS:
... ...
@@ -979,7 +841,7 @@ static int tiff_decode_tag(TiffContext *s, AVFrame *frame)
979 979
             goto end;
980 980
         }
981 981
         for (i = 0; i < count; i++)
982
-            dp[i] = tget_double(&s->gb, s->le);
982
+            dp[i] = ff_tget_double(&s->gb, s->le);
983 983
         for (i = 0; i < s->geotag_count; i++) {
984 984
             if (s->geotags[i].type == TIFF_GEO_DOUBLE_PARAMS) {
985 985
                 if (s->geotags[i].count == 0
... ...
@@ -1075,7 +937,7 @@ static int decode_frame(AVCodecContext *avctx,
1075 1075
     TiffContext *const s = avctx->priv_data;
1076 1076
     AVFrame *const p = data;
1077 1077
     unsigned off;
1078
-    int id, le, ret, plane, planes;
1078
+    int le, ret, plane, planes;
1079 1079
     int i, j, entries, stride;
1080 1080
     unsigned soff, ssize;
1081 1081
     uint8_t *dst;
... ...
@@ -1085,15 +947,11 @@ static int decode_frame(AVCodecContext *avctx,
1085 1085
     bytestream2_init(&s->gb, avpkt->data, avpkt->size);
1086 1086
 
1087 1087
     // parse image header
1088
-    if (avpkt->size < 8)
1089
-        return AVERROR_INVALIDDATA;
1090
-    id   = bytestream2_get_le16u(&s->gb);
1091
-    if (id == 0x4949)
1092
-        le = 1;
1093
-    else if (id == 0x4D4D)
1094
-        le = 0;
1095
-    else {
1096
-        av_log(avctx, AV_LOG_ERROR, "TIFF header not found\n");
1088
+    if ((ret = ff_tdecode_header(&s->gb, &le, &off))) {
1089
+        av_log(avctx, AV_LOG_ERROR, "Invalid TIFF header\n");
1090
+        return ret;
1091
+    } else if (off >= UINT_MAX - 14 || avpkt->size < off + 14) {
1092
+        av_log(avctx, AV_LOG_ERROR, "IFD offset is greater than image size\n");
1097 1093
         return AVERROR_INVALIDDATA;
1098 1094
     }
1099 1095
     s->le         = le;
... ...
@@ -1104,23 +962,11 @@ static int decode_frame(AVCodecContext *avctx,
1104 1104
     s->fill_order = 0;
1105 1105
     free_geotags(s);
1106 1106
 
1107
-    // As TIFF 6.0 specification puts it "An arbitrary but carefully chosen number
1108
-    // that further identifies the file as a TIFF file"
1109
-    if (tget_short(&s->gb, le) != 42) {
1110
-        av_log(avctx, AV_LOG_ERROR,
1111
-               "The answer to life, universe and everything is not correct!\n");
1112
-        return AVERROR_INVALIDDATA;
1113
-    }
1114 1107
     // Reset these offsets so we can tell if they were set this frame
1115 1108
     s->stripsizesoff = s->strippos = 0;
1116 1109
     /* parse image file directory */
1117
-    off = tget_long(&s->gb, le);
1118
-    if (off >= UINT_MAX - 14 || avpkt->size < off + 14) {
1119
-        av_log(avctx, AV_LOG_ERROR, "IFD offset is greater than image size\n");
1120
-        return AVERROR_INVALIDDATA;
1121
-    }
1122 1110
     bytestream2_seek(&s->gb, off, SEEK_SET);
1123
-    entries = tget_short(&s->gb, le);
1111
+    entries = ff_tget_short(&s->gb, le);
1124 1112
     if (bytestream2_get_bytes_left(&s->gb) < entries * 12)
1125 1113
         return AVERROR_INVALIDDATA;
1126 1114
     for (i = 0; i < entries; i++) {
... ...
@@ -1180,12 +1026,12 @@ static int decode_frame(AVCodecContext *avctx,
1180 1180
         dst    = p->data[plane];
1181 1181
     for (i = 0; i < s->height; i += s->rps) {
1182 1182
         if (s->stripsizesoff)
1183
-            ssize = tget(&stripsizes, s->sstype, s->le);
1183
+            ssize = ff_tget(&stripsizes, s->sstype, s->le);
1184 1184
         else
1185 1185
             ssize = s->stripsize;
1186 1186
 
1187 1187
         if (s->strippos)
1188
-            soff = tget(&stripdata, s->sot, s->le);
1188
+            soff = ff_tget(&stripdata, s->sot, s->le);
1189 1189
         else
1190 1190
             soff = s->stripoff;
1191 1191
 
... ...
@@ -31,6 +31,7 @@
31 31
 #define AVCODEC_TIFF_H
32 32
 
33 33
 #include <stdint.h>
34
+#include "tiff_common.h"
34 35
 
35 36
 /** abridged list of TIFF tags */
36 37
 enum TiffTags {
... ...
@@ -97,22 +98,6 @@ enum TiffCompr {
97 97
     TIFF_DEFLATE  = 0x80B2
98 98
 };
99 99
 
100
-enum TiffTypes {
101
-    TIFF_BYTE = 1,
102
-    TIFF_STRING,
103
-    TIFF_SHORT,
104
-    TIFF_LONG,
105
-    TIFF_RATIONAL,
106
-    TIFF_SBYTE,
107
-    TIFF_UNDEFINED,
108
-    TIFF_SSHORT,
109
-    TIFF_SLONG,
110
-    TIFF_SRATIONAL,
111
-    TIFF_FLOAT,
112
-    TIFF_DOUBLE,
113
-    TIFF_IFD
114
-};
115
-
116 100
 enum TiffGeoTagKey {
117 101
     TIFF_GT_MODEL_TYPE_GEOKEY                = 1024,
118 102
     TIFF_GT_RASTER_TYPE_GEOKEY               = 1025,
... ...
@@ -167,11 +152,6 @@ enum TiffGeoTagType {
167 167
     GEOTIFF_STRING = 34737
168 168
 };
169 169
 
170
-/** sizes of various TIFF field types (string size = 100)*/
171
-static const uint8_t type_sizes[14] = {
172
-    0, 1, 100, 2, 4, 8, 1, 1, 2, 4, 8, 4, 8, 4
173
-};
174
-
175 170
 typedef struct TiffGeoTag {
176 171
     enum TiffGeoTagKey key;
177 172
     enum TiffTags type;
178 173
new file mode 100644
... ...
@@ -0,0 +1,282 @@
0
+/*
1
+ * TIFF Common Routines
2
+ * Copyright (c) 2013 Thilo Borgmann <thilo.borgmann _at_ googlemail.com>
3
+ *
4
+ * This file is part of FFmpeg.
5
+ *
6
+ * FFmpeg is free software; you can redistribute it and/or
7
+ * modify it under the terms of the GNU Lesser General Public
8
+ * License as published by the Free Software Foundation; either
9
+ * version 2.1 of the License, or (at your option) any later version.
10
+ *
11
+ * FFmpeg is distributed in the hope that it will be useful,
12
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
+ * Lesser General Public License for more details.
15
+ *
16
+ * You should have received a copy of the GNU Lesser General Public
17
+ * License along with FFmpeg; if not, write to the Free Software
18
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19
+ */
20
+
21
+/**
22
+ * @file
23
+ * TIFF Common Routines
24
+ * @author Thilo Borgmann <thilo.borgmann _at_ googlemail.com>
25
+ */
26
+
27
+#include "tiff_common.h"
28
+
29
+
30
+int ff_tis_ifd(unsigned tag)
31
+{
32
+    int i;
33
+    for (i = 0; i < FF_ARRAY_ELEMS(ifd_tags); i++) {
34
+        if (ifd_tags[i] == tag) {
35
+            return i + 1;
36
+        }
37
+    }
38
+    return 0;
39
+}
40
+
41
+
42
+unsigned ff_tget_short(GetByteContext *gb, int le)
43
+{
44
+    unsigned v = le ? bytestream2_get_le16(gb) : bytestream2_get_be16(gb);
45
+    return v;
46
+}
47
+
48
+
49
+unsigned ff_tget_long(GetByteContext *gb, int le)
50
+{
51
+    unsigned v = le ? bytestream2_get_le32(gb) : bytestream2_get_be32(gb);
52
+    return v;
53
+}
54
+
55
+
56
+double ff_tget_double(GetByteContext *gb, int le)
57
+{
58
+    av_alias64 i = { .u64 = le ? bytestream2_get_le64(gb) : bytestream2_get_be64(gb)};
59
+    return i.f64;
60
+}
61
+
62
+
63
+unsigned ff_tget(GetByteContext *gb, int type, int le)
64
+{
65
+    switch (type) {
66
+    case TIFF_BYTE:
67
+        return bytestream2_get_byte(gb);
68
+    case TIFF_SHORT:
69
+        return ff_tget_short(gb, le);
70
+    case TIFF_LONG:
71
+        return ff_tget_long(gb, le);
72
+    default:
73
+        return UINT_MAX;
74
+    }
75
+}
76
+
77
+
78
+int ff_tadd_rational_metadata(int count, const char *name, const char *sep,
79
+                              GetByteContext *gb, int le, AVDictionary **metadata)
80
+{
81
+    AVBPrint bp;
82
+    char *ap;
83
+    int32_t nom, denom;
84
+    int i;
85
+
86
+    if (count >= INT_MAX / sizeof(int64_t) || count <= 0)
87
+        return AVERROR_INVALIDDATA;
88
+    if (bytestream2_get_bytes_left(gb) < count * sizeof(int64_t))
89
+        return AVERROR_INVALIDDATA;
90
+    if (!sep) sep = ", ";
91
+
92
+    av_bprint_init(&bp, 10 * count, AV_BPRINT_SIZE_AUTOMATIC);
93
+
94
+    for (i = 0; i < count; i++) {
95
+        nom   = ff_tget_long(gb, le);
96
+        denom = ff_tget_long(gb, le);
97
+        av_bprintf(&bp, "%s%i:%i", (i ? sep : ""), nom, denom);
98
+    }
99
+
100
+    if ((i = av_bprint_finalize(&bp, &ap))) {
101
+        return i;
102
+    }
103
+    if (!ap) {
104
+        return AVERROR(ENOMEM);
105
+    }
106
+
107
+    av_dict_set(metadata, name, ap, AV_DICT_DONT_STRDUP_VAL);
108
+
109
+    return 0;
110
+}
111
+
112
+
113
+int ff_tadd_long_metadata(int count, const char *name, const char *sep,
114
+                          GetByteContext *gb, int le, AVDictionary **metadata)
115
+{
116
+    AVBPrint bp;
117
+    char *ap;
118
+    int i;
119
+
120
+    if (count >= INT_MAX / sizeof(int32_t) || count <= 0)
121
+        return AVERROR_INVALIDDATA;
122
+    if (bytestream2_get_bytes_left(gb) < count * sizeof(int32_t))
123
+        return AVERROR_INVALIDDATA;
124
+    if (!sep) sep = ", ";
125
+
126
+    av_bprint_init(&bp, 10 * count, AV_BPRINT_SIZE_AUTOMATIC);
127
+
128
+    for (i = 0; i < count; i++) {
129
+        av_bprintf(&bp, "%s%i", (i ? sep : ""), ff_tget_long(gb, le));
130
+    }
131
+
132
+    if ((i = av_bprint_finalize(&bp, &ap))) {
133
+        return i;
134
+    }
135
+    if (!ap) {
136
+        return AVERROR(ENOMEM);
137
+    }
138
+
139
+    av_dict_set(metadata, name, ap, AV_DICT_DONT_STRDUP_VAL);
140
+
141
+    return 0;
142
+}
143
+
144
+
145
+int ff_tadd_doubles_metadata(int count, const char *name, const char *sep,
146
+                             GetByteContext *gb, int le, AVDictionary **metadata)
147
+{
148
+    AVBPrint bp;
149
+    char *ap;
150
+    int i;
151
+
152
+    if (count >= INT_MAX / sizeof(int64_t) || count <= 0)
153
+        return AVERROR_INVALIDDATA;
154
+    if (bytestream2_get_bytes_left(gb) < count * sizeof(int64_t))
155
+        return AVERROR_INVALIDDATA;
156
+    if (!sep) sep = ", ";
157
+
158
+    av_bprint_init(&bp, 10 * count, AV_BPRINT_SIZE_AUTOMATIC);
159
+
160
+    for (i = 0; i < count; i++) {
161
+        av_bprintf(&bp, "%s%f", (i ? sep : ""), ff_tget_double(gb, le));
162
+    }
163
+
164
+    if ((i = av_bprint_finalize(&bp, &ap))) {
165
+        return i;
166
+    }
167
+    if (!ap) {
168
+        return AVERROR(ENOMEM);
169
+    }
170
+
171
+    av_dict_set(metadata, name, ap, AV_DICT_DONT_STRDUP_VAL);
172
+
173
+    return 0;
174
+}
175
+
176
+
177
+int ff_tadd_shorts_metadata(int count, const char *name, const char *sep,
178
+                            GetByteContext *gb, int le, AVDictionary **metadata)
179
+{
180
+    AVBPrint bp;
181
+    char *ap;
182
+    int i;
183
+
184
+    if (count >= INT_MAX / sizeof(int16_t) || count <= 0)
185
+        return AVERROR_INVALIDDATA;
186
+    if (bytestream2_get_bytes_left(gb) < count * sizeof(int16_t))
187
+        return AVERROR_INVALIDDATA;
188
+    if (!sep) sep = ", ";
189
+
190
+    av_bprint_init(&bp, 10 * count, AV_BPRINT_SIZE_AUTOMATIC);
191
+
192
+    for (i = 0; i < count; i++) {
193
+        av_bprintf(&bp, "%s%i", (i ? sep : ""), ff_tget_short(gb, le));
194
+    }
195
+
196
+    if ((i = av_bprint_finalize(&bp, &ap))) {
197
+        return i;
198
+    }
199
+    if (!ap) {
200
+        return AVERROR(ENOMEM);
201
+    }
202
+
203
+    av_dict_set(metadata, name, ap, AV_DICT_DONT_STRDUP_VAL);
204
+
205
+    return 0;
206
+}
207
+
208
+
209
+int ff_tadd_string_metadata(int count, const char *name,
210
+                            GetByteContext *gb, int le, AVDictionary **metadata)
211
+{
212
+    char *value;
213
+
214
+    if (bytestream2_get_bytes_left(gb) < count || count < 0)
215
+        return AVERROR_INVALIDDATA;
216
+
217
+    value = av_malloc(count + 1);
218
+    if (!value)
219
+        return AVERROR(ENOMEM);
220
+
221
+    bytestream2_get_bufferu(gb, value, count);
222
+    value[count] = 0;
223
+
224
+    av_dict_set(metadata, name, value, AV_DICT_DONT_STRDUP_VAL);
225
+    return 0;
226
+}
227
+
228
+
229
+int ff_tdecode_header(GetByteContext *gb, int *le, int *ifd_offset)
230
+{
231
+    if (bytestream2_get_bytes_left(gb) < 8) {
232
+        return AVERROR_INVALIDDATA;
233
+    }
234
+
235
+    *le = bytestream2_get_le16u(gb);
236
+    if (*le == AV_RB16("II")) {
237
+        *le = 1;
238
+    } else if (*le == AV_RB16("MM")) {
239
+        *le = 0;
240
+    } else {
241
+        return AVERROR_INVALIDDATA;
242
+    }
243
+
244
+    if (ff_tget_short(gb, *le) != 42) {
245
+        return AVERROR_INVALIDDATA;
246
+    }
247
+
248
+    *ifd_offset = ff_tget_long(gb, *le);
249
+
250
+    return 0;
251
+}
252
+
253
+
254
+int ff_tread_tag(GetByteContext *gb, int le, unsigned *tag, unsigned *type,
255
+                 unsigned *count, int *next)
256
+{
257
+    int ifd_tag;
258
+    int valid_type;
259
+
260
+    *tag    = ff_tget_short(gb, le);
261
+    *type   = ff_tget_short(gb, le);
262
+    *count  = ff_tget_long (gb, le);
263
+
264
+    ifd_tag    = ff_tis_ifd(*tag);
265
+    valid_type = *type != 0 && *type < FF_ARRAY_ELEMS(type_sizes);
266
+
267
+    *next = bytestream2_tell(gb) + 4;
268
+
269
+    // check for valid type
270
+    if (!valid_type) {
271
+        return AVERROR_INVALIDDATA;
272
+    }
273
+
274
+    // seek to offset if this is an IFD-tag or
275
+    // if count values do not fit into the offset value
276
+    if (ifd_tag || (*count > 4 || !(type_sizes[*type] * (*count) <= 4 || *type == TIFF_STRING))) {
277
+        bytestream2_seek(gb, ff_tget_long (gb, le), SEEK_SET);
278
+    }
279
+
280
+    return 0;
281
+}
0 282
new file mode 100644
... ...
@@ -0,0 +1,146 @@
0
+/*
1
+ * TIFF Common Routines
2
+ * Copyright (c) 2013 Thilo Borgmann <thilo.borgmann _at_ googlemail.com>
3
+ *
4
+ * This file is part of FFmpeg.
5
+ *
6
+ * FFmpeg is free software; you can redistribute it and/or
7
+ * modify it under the terms of the GNU Lesser General Public
8
+ * License as published by the Free Software Foundation; either
9
+ * version 2.1 of the License, or (at your option) any later version.
10
+ *
11
+ * FFmpeg is distributed in the hope that it will be useful,
12
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
+ * Lesser General Public License for more details.
15
+ *
16
+ * You should have received a copy of the GNU Lesser General Public
17
+ * License along with FFmpeg; if not, write to the Free Software
18
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19
+ */
20
+
21
+/**
22
+ * @file
23
+ * TIFF Common Routines
24
+ * @author Thilo Borgmann <thilo.borgmann _at_ googlemail.com>
25
+ */
26
+
27
+#ifndef AVCODEC_TIFF_COMMON_H
28
+#define AVCODEC_TIFF_COMMON_H
29
+
30
+#include "avcodec.h"
31
+#include "tiff.h"
32
+#include "bytestream.h"
33
+#include "libavutil/bprint.h"
34
+
35
+/** data type identifiers for TIFF tags */
36
+enum TiffTypes {
37
+    TIFF_BYTE = 1,
38
+    TIFF_STRING,
39
+    TIFF_SHORT,
40
+    TIFF_LONG,
41
+    TIFF_RATIONAL,
42
+    TIFF_SBYTE,
43
+    TIFF_UNDEFINED,
44
+    TIFF_SSHORT,
45
+    TIFF_SLONG,
46
+    TIFF_SRATIONAL,
47
+    TIFF_FLOAT,
48
+    TIFF_DOUBLE,
49
+    TIFF_IFD
50
+};
51
+
52
+/** sizes of various TIFF field types (string size = 100)*/
53
+static const uint8_t type_sizes[14] = {
54
+    0, 1, 100, 2, 4, 8, 1, 1, 2, 4, 8, 4, 8, 4
55
+};
56
+
57
+static const uint16_t ifd_tags[] = {
58
+    0x8769, // EXIF IFD
59
+    0x8825, // GPS IFD
60
+    0xA005  // Interoperability IFD
61
+};
62
+
63
+
64
+/** Returns a value > 0 if the tag is a known IFD-tag.
65
+ *  The return value is the array index + 1 within ifd_tags[].
66
+ */
67
+int ff_tis_ifd(unsigned tag);
68
+
69
+/** Reads a short from the bytestream using given endianess. */
70
+unsigned ff_tget_short(GetByteContext *gb, int le);
71
+
72
+/** Reads a long from the bytestream using given endianess. */
73
+unsigned ff_tget_long(GetByteContext *gb, int le);
74
+
75
+/** Reads a double from the bytestream using given endianess. */
76
+double   ff_tget_double(GetByteContext *gb, int le);
77
+
78
+/** Reads a byte from the bytestream using given endianess. */
79
+unsigned ff_tget(GetByteContext *gb, int type, int le);
80
+
81
+/** Returns an allocated string containing count
82
+ *  rational values using the given seperator.
83
+ */
84
+char *ff_trationals2str(int *rp, int count, const char *sep);
85
+
86
+/** Returns an allocated string containing count
87
+ *  long values using the given seperator.
88
+ */
89
+char *ff_tlongs2str(int32_t *lp, int count, const char *sep);
90
+
91
+/** Returns an allocated string containing count
92
+ *  double values using the given seperator.
93
+ */
94
+char *ff_tdoubles2str(double *dp, int count, const char *sep);
95
+
96
+/** Returns an allocated string containing count
97
+ *  short values using the given seperator.
98
+ */
99
+char *ff_tshorts2str(int16_t *sp, int count, const char *sep);
100
+
101
+/** Adds count rationals converted to a string
102
+ *  into the metadata dictionary.
103
+ */
104
+int ff_tadd_rational_metadata(int count, const char *name, const char *sep,
105
+                              GetByteContext *gb, int le, AVDictionary **metadata);
106
+
107
+/** Adds count longs converted to a string
108
+ *  into the metadata dictionary.
109
+ */
110
+int ff_tadd_long_metadata(int count, const char *name, const char *sep,
111
+                          GetByteContext *gb, int le, AVDictionary **metadata);
112
+
113
+/** Adds count doubles converted to a string
114
+ *  into the metadata dictionary.
115
+ */
116
+int ff_tadd_doubles_metadata(int count, const char *name, const char *sep,
117
+                             GetByteContext *gb, int le, AVDictionary **metadata);
118
+
119
+/** Adds count shorts converted to a string
120
+ *  into the metadata dictionary.
121
+ */
122
+int ff_tadd_shorts_metadata(int count, const char *name, const char *sep,
123
+                            GetByteContext *gb, int le, AVDictionary **metadata);
124
+
125
+/** Adds a string of count characters
126
+ *  into the metadata dictionary.
127
+ */
128
+int ff_tadd_string_metadata(int count, const char *name,
129
+                            GetByteContext *gb, int le, AVDictionary **metadata);
130
+
131
+/** Decodes a TIFF header from the input bytestream
132
+ *  and sets the endianess in *le and the offset to
133
+ *  the first IFD in *ifd_offset accordingly.
134
+ */
135
+int ff_tdecode_header(GetByteContext *gb, int *le, int *ifd_offset);
136
+
137
+/** Reads the first 3 fields of a TIFF tag, which are
138
+ *  the tag id, the tag type and the count of values for that tag.
139
+ *  Afterwards the bytestream is located at the first value to read and
140
+ *  *next holds the bytestream offset of the following tag.
141
+ */
142
+int ff_tread_tag(GetByteContext *gb, int le, unsigned *tag, unsigned *type,
143
+                 unsigned *count, int *next);
144
+
145
+#endif /* AVCODEC_TIFF_COMMON_H */