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