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