FFmpeg
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
Examples
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
libavcodec
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
(
AVCodecContext
*avctx,
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
TIFF_DOUBLE
:
return
ff_tadd_doubles_metadata
(count, name, sep, gb, le, metadata);
51
case
TIFF_SSHORT
:
return
ff_tadd_shorts_metadata
(count, name, sep, gb, le, 1, metadata);
52
case
TIFF_SHORT
:
return
ff_tadd_shorts_metadata
(count, name, sep, gb, le, 0, metadata);
53
case
TIFF_SBYTE
:
return
ff_tadd_bytes_metadata
(count, name, sep, gb, le, 1, metadata);
54
case
TIFF_BYTE
:
55
case
TIFF_UNDEFINED
:
return
ff_tadd_bytes_metadata
(count, name, sep, gb, le, 0, metadata);
56
case
TIFF_STRING
:
return
ff_tadd_string_metadata
(count, name, gb, le, metadata);
57
case
TIFF_SRATIONAL
:
58
case
TIFF_RATIONAL
:
return
ff_tadd_rational_metadata
(count, name, sep, gb, le, metadata);
59
case
TIFF_SLONG
:
60
case
TIFF_LONG
:
return
ff_tadd_long_metadata
(count, name, sep, gb, le, metadata);
61
default
:
62
avpriv_request_sample
(avctx,
"TIFF tag type (%u)"
, type);
63
return
0;
64
};
65
}
66
67
68
static
int
exif_decode_tag
(
AVCodecContext
*avctx,
GetByteContext
*gbytes,
int
le
,
69
int
depth
,
AVDictionary
**metadata)
70
{
71
int
ret
, cur_pos;
72
unsigned
id
,
count
;
73
enum
TiffTypes
type
;
74
75
if
(depth > 2) {
76
return
0;
77
}
78
79
ff_tread_tag
(gbytes, le, &
id
, &type, &count, &cur_pos);
80
81
if
(!
bytestream2_tell
(gbytes)) {
82
bytestream2_seek
(gbytes, cur_pos, SEEK_SET);
83
return
0;
84
}
85
86
// read count values and add it metadata
87
// store metadata or proceed with next IFD
88
ret =
ff_tis_ifd
(
id
);
89
if
(ret) {
90
ret =
avpriv_exif_decode_ifd
(avctx, gbytes, le, depth + 1, metadata);
91
}
else
{
92
const
char
*
name
=
exif_get_tag_name
(
id
);
93
char
*use_name = (
char
*) name;
94
95
if
(!use_name) {
96
use_name =
av_malloc
(7);
97
if
(!use_name) {
98
return
AVERROR
(ENOMEM);
99
}
100
snprintf
(use_name, 7,
"0x%04X"
,
id
);
101
}
102
103
ret =
exif_add_metadata
(avctx, count, type, use_name, NULL,
104
gbytes, le, metadata);
105
106
if
(!name) {
107
av_freep
(&use_name);
108
}
109
}
110
111
bytestream2_seek
(gbytes, cur_pos, SEEK_SET);
112
113
return
ret
;
114
}
115
116
117
int
avpriv_exif_decode_ifd
(
AVCodecContext
*avctx,
GetByteContext
*gbytes,
int
le
,
118
int
depth
,
AVDictionary
**metadata)
119
{
120
int
i,
ret
;
121
int
entries;
122
123
entries =
ff_tget_short
(gbytes, le);
124
125
if
(
bytestream2_get_bytes_left
(gbytes) < entries * 12) {
126
return
AVERROR_INVALIDDATA
;
127
}
128
129
for
(i = 0; i < entries; i++) {
130
if
((ret =
exif_decode_tag
(avctx, gbytes, le, depth, metadata)) < 0) {
131
return
ret
;
132
}
133
}
134
135
// return next IDF offset or 0x000000000 or a value < 0 for failure
136
return
ff_tget_long
(gbytes, le);
137
}
Generated on Sun Jul 20 2014 23:05:46 for FFmpeg by
1.8.2