Libav
Main Page
Related Pages
Modules
Data Structures
Files
Examples
File List
Globals
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 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
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
for
(;;) {
41
c = *sc->
bytestream
++;
42
if
(c ==
'#'
) {
43
do
{
44
c = *sc->
bytestream
++;
45
}
while
(c !=
'\n'
&& sc->
bytestream
< sc->
bytestream_end
);
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))
111
return
AVERROR_INVALIDDATA
;
112
113
avctx->
width
= w;
114
avctx->
height
= h;
115
if
(depth == 1) {
116
if
(maxval == 1)
117
avctx->
pix_fmt
=
AV_PIX_FMT_MONOWHITE
;
118
else
119
avctx->
pix_fmt
=
AV_PIX_FMT_GRAY8
;
120
}
else
if
(depth == 3) {
121
if
(maxval < 256) {
122
avctx->
pix_fmt
=
AV_PIX_FMT_RGB24
;
123
}
else
{
124
av_log
(avctx,
AV_LOG_ERROR
,
"16-bit components are only supported for grayscale\n"
);
125
avctx->
pix_fmt
=
AV_PIX_FMT_NONE
;
126
return
AVERROR_INVALIDDATA
;
127
}
128
}
else
if
(depth == 4) {
129
avctx->
pix_fmt
=
AV_PIX_FMT_RGB32
;
130
}
else
{
131
return
AVERROR_INVALIDDATA
;
132
}
133
return
0;
134
}
else
{
135
return
AVERROR_INVALIDDATA
;
136
}
137
pnm_get
(s, buf1,
sizeof
(buf1));
138
avctx->
width
= atoi(buf1);
139
if
(avctx->
width
<= 0)
140
return
AVERROR_INVALIDDATA
;
141
pnm_get
(s, buf1,
sizeof
(buf1));
142
avctx->
height
= atoi(buf1);
143
if
(
av_image_check_size
(avctx->
width
, avctx->
height
, 0, avctx))
144
return
AVERROR_INVALIDDATA
;
145
if
(avctx->
pix_fmt
!=
AV_PIX_FMT_MONOWHITE
) {
146
pnm_get
(s, buf1,
sizeof
(buf1));
147
s->
maxval
= atoi(buf1);
148
if
(s->
maxval
<= 0) {
149
av_log
(avctx,
AV_LOG_ERROR
,
"Invalid maxval: %d\n"
, s->
maxval
);
150
s->
maxval
= 255;
151
}
152
if
(s->
maxval
>= 256) {
153
if
(avctx->
pix_fmt
==
AV_PIX_FMT_GRAY8
) {
154
avctx->
pix_fmt
=
AV_PIX_FMT_GRAY16BE
;
155
if
(s->
maxval
!= 65535)
156
avctx->
pix_fmt
=
AV_PIX_FMT_GRAY16
;
157
}
else
if
(avctx->
pix_fmt
==
AV_PIX_FMT_RGB24
) {
158
if
(s->
maxval
> 255)
159
avctx->
pix_fmt
=
AV_PIX_FMT_RGB48BE
;
160
}
else
if
(avctx->
pix_fmt
==
AV_PIX_FMT_YUV420P
&& s->
maxval
< 65536) {
161
if
(s->
maxval
< 512)
162
avctx->
pix_fmt
=
AV_PIX_FMT_YUV420P9BE
;
163
else
if
(s->
maxval
< 1024)
164
avctx->
pix_fmt
=
AV_PIX_FMT_YUV420P10BE
;
165
else
166
avctx->
pix_fmt
=
AV_PIX_FMT_YUV420P16
;
167
}
else
{
168
av_log
(avctx,
AV_LOG_ERROR
,
"Unsupported pixel format\n"
);
169
avctx->
pix_fmt
=
AV_PIX_FMT_NONE
;
170
return
AVERROR_INVALIDDATA
;
171
}
172
}
173
}
else
174
s->
maxval
=1;
175
/* more check if YUV420 */
176
if
(
av_pix_fmt_desc_get
(avctx->
pix_fmt
)->
flags
&
AV_PIX_FMT_FLAG_PLANAR
) {
177
if
((avctx->
width
& 1) != 0)
178
return
AVERROR_INVALIDDATA
;
179
h = (avctx->
height
* 2);
180
if
((h % 3) != 0)
181
return
AVERROR_INVALIDDATA
;
182
h /= 3;
183
avctx->
height
= h;
184
}
185
return
0;
186
}
Generated on Sun Jun 1 2014 17:55:32 for Libav by
1.8.1.2