Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
Thilo Borgmann authored on 2013/08/13 02:32:40... | ... |
@@ -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 */ |