Libav
Main Page
Related Pages
Modules
Data Structures
Files
Examples
File List
Globals
libavcodec
png_parser.c
Go to the documentation of this file.
1
/*
2
* PNG parser
3
* Copyright (c) 2009 Peter Holik
4
*
5
* This file is part of Libav.
6
*
7
* Libav 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
* Libav 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 Libav; if not, write to the Free Software
19
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20
*/
21
27
#include "
libavutil/intreadwrite.h
"
28
#include "
libavutil/common.h
"
29
30
#include "
parser.h
"
31
32
#define PNG_SIGNATURE UINT64_C(0x89504e470d0a1a0a)
33
#define MNG_SIGNATURE UINT64_C(0x8a4d4e470d0a1a0a)
34
35
typedef
struct
PNGParseContext
{
36
ParseContext
pc
;
37
38
int
chunk_pos
;
39
int
chunk_length
;
40
int
remaining_size
;
41
}
PNGParseContext
;
42
43
static
int
png_parse
(
AVCodecParserContext
*s,
AVCodecContext
*avctx,
44
const
uint8_t
**poutbuf,
int
*poutbuf_size,
45
const
uint8_t
*buf,
int
buf_size)
46
{
47
PNGParseContext
*ppc = s->
priv_data
;
48
int
next =
END_NOT_FOUND
;
49
int
i = 0;
50
51
*poutbuf_size = 0;
52
if
(buf_size == 0)
53
return
0;
54
55
if
(!ppc->
pc
.
frame_start_found
) {
56
uint64_t state64 = ppc->
pc
.
state64
;
57
for
(; i < buf_size; i++) {
58
state64 = (state64 << 8) | buf[i];
59
if
(state64 ==
PNG_SIGNATURE
||
60
state64 ==
MNG_SIGNATURE
) {
61
i++;
62
ppc->
pc
.
frame_start_found
= 1;
63
break
;
64
}
65
}
66
ppc->
pc
.
state64
= state64;
67
}
else
if
(ppc->
remaining_size
) {
68
i =
FFMIN
(ppc->
remaining_size
, buf_size);
69
ppc->
remaining_size
-= i;
70
if
(ppc->
remaining_size
)
71
goto
flush
;
72
if
(ppc->
chunk_pos
== -1) {
73
next = i;
74
goto
flush
;
75
}
76
}
77
78
for
(; ppc->
pc
.
frame_start_found
&& i < buf_size; i++) {
79
ppc->
pc
.
state
= (ppc->
pc
.
state
<< 8) | buf[i];
80
if
(ppc->
chunk_pos
== 3) {
81
ppc->
chunk_length
= ppc->
pc
.
state
;
82
if
(ppc->
chunk_length
> 0x7fffffff) {
83
ppc->
chunk_pos
= ppc->
pc
.
frame_start_found
= 0;
84
goto
flush
;
85
}
86
ppc->
chunk_length
+= 4;
87
}
else
if
(ppc->
chunk_pos
== 7) {
88
if
(ppc->
chunk_length
>= buf_size - i)
89
ppc->
remaining_size
= ppc->
chunk_length
- buf_size + i + 1;
90
if
(ppc->
pc
.
state
==
MKBETAG
(
'I'
,
'E'
,
'N'
,
'D'
)) {
91
if
(ppc->
remaining_size
)
92
ppc->
chunk_pos
= -1;
93
else
94
next = ppc->
chunk_length
+ i + 1;
95
break
;
96
}
else
{
97
ppc->
chunk_pos
= 0;
98
if
(ppc->
remaining_size
)
99
break
;
100
else
101
i += ppc->
chunk_length
;
102
continue
;
103
}
104
}
105
ppc->
chunk_pos
++;
106
}
107
108
flush
:
109
if
(
ff_combine_frame
(&ppc->
pc
, next, &buf, &buf_size) < 0)
110
return
buf_size;
111
112
ppc->
chunk_pos
= ppc->
pc
.
frame_start_found
= 0;
113
114
*poutbuf = buf;
115
*poutbuf_size = buf_size;
116
return
next;
117
}
118
119
AVCodecParser
ff_png_parser
= {
120
.
codec_ids
= {
AV_CODEC_ID_PNG
},
121
.priv_data_size =
sizeof
(
PNGParseContext
),
122
.parser_parse =
png_parse
,
123
.parser_close =
ff_parse_close
,
124
};
Generated on Sun Jun 1 2014 17:55:32 for Libav by
1.8.1.2