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