FFmpeg
Main Page
Related Pages
Modules
Data Structures
Files
Examples
File List
Globals
•
All
Data Structures
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
libavcodec
pnm.c
Go to the documentation of this file.
1
/*
2
* PNM image format
3
* Copyright (c) 2002, 2003 Fabrice Bellard
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
#include <stdlib.h>
23
#include <string.h>
24
25
#include "
libavutil/imgutils.h
"
26
#include "
avcodec.h
"
27
#include "
pnm.h
"
28
29
static
inline
int
pnm_space
(
int
c
)
30
{
31
return
c ==
' '
|| c ==
'\n'
|| c ==
'\r'
|| c ==
'\t'
;
32
}
33
34
static
void
pnm_get
(
PNMContext
*sc,
char
*str,
int
buf_size)
35
{
36
char
*s;
37
int
c
;
38
39
/* skip spaces and comments */
40
while
(sc->
bytestream
< sc->
bytestream_end
) {
41
c = *sc->
bytestream
++;
42
if
(c ==
'#'
) {
43
while
(c !=
'\n'
&& sc->
bytestream
< sc->
bytestream_end
) {
44
c = *sc->
bytestream
++;
45
}
46
}
else
if
(!
pnm_space
(c)) {
47
break
;
48
}
49
}
50
51
s = str;
52
while
(sc->
bytestream
< sc->
bytestream_end
&& !
pnm_space
(c)) {
53
if
((s - str) < buf_size - 1)
54
*s++ =
c
;
55
c = *sc->
bytestream
++;
56
}
57
*s =
'\0'
;
58
}
59
60
int
ff_pnm_decode_header
(
AVCodecContext
*avctx,
PNMContext
*
const
s)
61
{
62
char
buf1[32], tuple_type[32];
63
int
h, w,
depth
, maxval;
64
65
pnm_get
(s, buf1,
sizeof
(buf1));
66
s->
type
= buf1[1]-
'0'
;
67
if
(buf1[0] !=
'P'
)
68
return
-1;
69
70
if
(s->
type
==1 || s->
type
==4) {
71
avctx->
pix_fmt
=
AV_PIX_FMT_MONOWHITE
;
72
}
else
if
(s->
type
==2 || s->
type
==5) {
73
if
(avctx->
codec_id
==
AV_CODEC_ID_PGMYUV
)
74
avctx->
pix_fmt
=
AV_PIX_FMT_YUV420P
;
75
else
76
avctx->
pix_fmt
=
AV_PIX_FMT_GRAY8
;
77
}
else
if
(s->
type
==3 || s->
type
==6) {
78
avctx->
pix_fmt
=
AV_PIX_FMT_RGB24
;
79
}
else
if
(s->
type
==7) {
80
w = -1;
81
h = -1;
82
maxval = -1;
83
depth = -1;
84
tuple_type[0] =
'\0'
;
85
for
(;;) {
86
pnm_get
(s, buf1,
sizeof
(buf1));
87
if
(!strcmp(buf1,
"WIDTH"
)) {
88
pnm_get
(s, buf1,
sizeof
(buf1));
89
w = strtol(buf1,
NULL
, 10);
90
}
else
if
(!strcmp(buf1,
"HEIGHT"
)) {
91
pnm_get
(s, buf1,
sizeof
(buf1));
92
h = strtol(buf1,
NULL
, 10);
93
}
else
if
(!strcmp(buf1,
"DEPTH"
)) {
94
pnm_get
(s, buf1,
sizeof
(buf1));
95
depth = strtol(buf1,
NULL
, 10);
96
}
else
if
(!strcmp(buf1,
"MAXVAL"
)) {
97
pnm_get
(s, buf1,
sizeof
(buf1));
98
maxval = strtol(buf1,
NULL
, 10);
99
}
else
if
(!strcmp(buf1,
"TUPLTYPE"
) ||
100
/* libavcodec used to write invalid files */
101
!strcmp(buf1,
"TUPLETYPE"
)) {
102
pnm_get
(s, tuple_type,
sizeof
(tuple_type));
103
}
else
if
(!strcmp(buf1,
"ENDHDR"
)) {
104
break
;
105
}
else
{
106
return
-1;
107
}
108
}
109
/* check that all tags are present */
110
if
(w <= 0 || h <= 0 || maxval <= 0 || depth <= 0 || tuple_type[0] ==
'\0'
||
av_image_check_size
(w, h, 0, avctx) || s->
bytestream
>= s->
bytestream_end
)
111
return
-1;
112
113
avctx->
width
= w;
114
avctx->
height
= h;
115
s->
maxval
= maxval;
116
if
(depth == 1) {
117
if
(maxval == 1) {
118
avctx->
pix_fmt
=
AV_PIX_FMT_MONOBLACK
;
119
}
else
if
(maxval == 255) {
120
avctx->
pix_fmt
=
AV_PIX_FMT_GRAY8
;
121
}
else
{
122
avctx->
pix_fmt
=
AV_PIX_FMT_GRAY16BE
;
123
}
124
}
else
if
(depth == 2) {
125
if
(maxval == 255)
126
avctx->
pix_fmt
=
AV_PIX_FMT_GRAY8A
;
127
}
else
if
(depth == 3) {
128
if
(maxval < 256) {
129
avctx->
pix_fmt
=
AV_PIX_FMT_RGB24
;
130
}
else
{
131
avctx->
pix_fmt
=
AV_PIX_FMT_RGB48BE
;
132
}
133
}
else
if
(depth == 4) {
134
if
(maxval < 256) {
135
avctx->
pix_fmt
=
AV_PIX_FMT_RGBA
;
136
}
else
{
137
avctx->
pix_fmt
=
AV_PIX_FMT_RGBA64BE
;
138
}
139
}
else
{
140
return
-1;
141
}
142
return
0;
143
}
else
{
144
return
-1;
145
}
146
pnm_get
(s, buf1,
sizeof
(buf1));
147
w = atoi(buf1);
148
pnm_get
(s, buf1,
sizeof
(buf1));
149
h = atoi(buf1);
150
if
(w <= 0 || h <= 0 ||
av_image_check_size
(w, h, 0, avctx) || s->
bytestream
>= s->
bytestream_end
)
151
return
-1;
152
153
avctx->
width
= w;
154
avctx->
height
= h;
155
156
if
(avctx->
pix_fmt
!=
AV_PIX_FMT_MONOWHITE
&& avctx->
pix_fmt
!=
AV_PIX_FMT_MONOBLACK
) {
157
pnm_get
(s, buf1,
sizeof
(buf1));
158
s->
maxval
= atoi(buf1);
159
if
(s->
maxval
<= 0) {
160
av_log
(avctx,
AV_LOG_ERROR
,
"Invalid maxval: %d\n"
, s->
maxval
);
161
s->
maxval
= 255;
162
}
163
if
(s->
maxval
>= 256) {
164
if
(avctx->
pix_fmt
==
AV_PIX_FMT_GRAY8
) {
165
avctx->
pix_fmt
=
AV_PIX_FMT_GRAY16BE
;
166
}
else
if
(avctx->
pix_fmt
==
AV_PIX_FMT_RGB24
) {
167
avctx->
pix_fmt
=
AV_PIX_FMT_RGB48BE
;
168
}
else
{
169
av_log
(avctx,
AV_LOG_ERROR
,
"Unsupported pixel format\n"
);
170
avctx->
pix_fmt
=
AV_PIX_FMT_NONE
;
171
return
-1;
172
}
173
}
174
}
else
175
s->
maxval
=1;
176
/* more check if YUV420 */
177
if
(avctx->
pix_fmt
==
AV_PIX_FMT_YUV420P
) {
178
if
((avctx->
width
& 1) != 0)
179
return
-1;
180
h = (avctx->
height
* 2);
181
if
((h % 3) != 0)
182
return
-1;
183
h /= 3;
184
avctx->
height
= h;
185
}
186
return
0;
187
}
188
189
av_cold
int
ff_pnm_end
(
AVCodecContext
*avctx)
190
{
191
PNMContext
*s = avctx->
priv_data
;
192
193
if
(s->
picture
.
data
[0])
194
avctx->
release_buffer
(avctx, &s->
picture
);
195
196
return
0;
197
}
198
199
av_cold
int
ff_pnm_init
(
AVCodecContext
*avctx)
200
{
201
PNMContext
*s = avctx->
priv_data
;
202
203
avcodec_get_frame_defaults
(&s->
picture
);
204
avctx->
coded_frame
= &s->
picture
;
205
206
return
0;
207
}
Generated on Sat May 25 2013 03:58:39 for FFmpeg by
1.8.2