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
AVERROR_INVALIDDATA
;
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
AVERROR_INVALIDDATA
;
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
AVERROR_INVALIDDATA
;
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
AVERROR_INVALIDDATA
;
141
}
142
return
0;
143
}
else
{
144
return
AVERROR_INVALIDDATA
;
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
AVERROR_INVALIDDATA
;
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
if
(avctx->
pix_fmt
==
AV_PIX_FMT_YUV420P
&& s->
maxval
< 65536) {
169
if
(s->
maxval
< 512)
170
avctx->
pix_fmt
=
AV_PIX_FMT_YUV420P9BE
;
171
else
if
(s->
maxval
< 1024)
172
avctx->
pix_fmt
=
AV_PIX_FMT_YUV420P10BE
;
173
else
174
avctx->
pix_fmt
=
AV_PIX_FMT_YUV420P16
;
175
}
else
{
176
av_log
(avctx,
AV_LOG_ERROR
,
"Unsupported pixel format\n"
);
177
avctx->
pix_fmt
=
AV_PIX_FMT_NONE
;
178
return
AVERROR_INVALIDDATA
;
179
}
180
}
181
}
else
182
s->
maxval
=1;
183
/* more check if YUV420 */
184
if
(
av_pix_fmt_desc_get
(avctx->
pix_fmt
)->
flags
&
PIX_FMT_PLANAR
) {
185
if
((avctx->
width
& 1) != 0)
186
return
AVERROR_INVALIDDATA
;
187
h = (avctx->
height
* 2);
188
if
((h % 3) != 0)
189
return
AVERROR_INVALIDDATA
;
190
h /= 3;
191
avctx->
height
= h;
192
}
193
return
0;
194
}
195
196
av_cold
int
ff_pnm_end
(
AVCodecContext
*avctx)
197
{
198
PNMContext
*s = avctx->
priv_data
;
199
200
if
(s->
picture
.
data
[0])
201
avctx->
release_buffer
(avctx, &s->
picture
);
202
203
return
0;
204
}
205
206
av_cold
int
ff_pnm_init
(
AVCodecContext
*avctx)
207
{
208
PNMContext
*s = avctx->
priv_data
;
209
210
avcodec_get_frame_defaults
(&s->
picture
);
211
avctx->
coded_frame
= &s->
picture
;
212
213
return
0;
214
}
Generated on Sat May 25 2013 04:01:09 for FFmpeg by
1.8.2