FFmpeg
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
Examples
File List
Globals
All
Data Structures
Namespaces
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
if
(buf1[0] !=
'P'
)
67
return
AVERROR_INVALIDDATA
;
68
s->
type
= buf1[1]-
'0'
;
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 < 256) {
120
avctx->
pix_fmt
=
AV_PIX_FMT_GRAY8
;
121
}
else
{
122
avctx->
pix_fmt
=
AV_PIX_FMT_GRAY16
;
123
}
124
}
else
if
(depth == 2) {
125
if
(maxval < 256) {
126
avctx->
pix_fmt
=
AV_PIX_FMT_GRAY8A
;
127
}
else
{
128
avctx->
pix_fmt
=
AV_PIX_FMT_YA16
;
129
}
130
}
else
if
(depth == 3) {
131
if
(maxval < 256) {
132
avctx->
pix_fmt
=
AV_PIX_FMT_RGB24
;
133
}
else
{
134
avctx->
pix_fmt
=
AV_PIX_FMT_RGB48
;
135
}
136
}
else
if
(depth == 4) {
137
if
(maxval < 256) {
138
avctx->
pix_fmt
=
AV_PIX_FMT_RGBA
;
139
}
else
{
140
avctx->
pix_fmt
=
AV_PIX_FMT_RGBA64
;
141
}
142
}
else
{
143
return
AVERROR_INVALIDDATA
;
144
}
145
return
0;
146
}
else
{
147
return
AVERROR_INVALIDDATA
;
148
}
149
pnm_get
(s, buf1,
sizeof
(buf1));
150
w = atoi(buf1);
151
pnm_get
(s, buf1,
sizeof
(buf1));
152
h = atoi(buf1);
153
if
(w <= 0 || h <= 0 ||
av_image_check_size
(w, h, 0, avctx) || s->
bytestream
>= s->
bytestream_end
)
154
return
AVERROR_INVALIDDATA
;
155
156
avctx->
width
= w;
157
avctx->
height
= h;
158
159
if
(avctx->
pix_fmt
!=
AV_PIX_FMT_MONOWHITE
&& avctx->
pix_fmt
!=
AV_PIX_FMT_MONOBLACK
) {
160
pnm_get
(s, buf1,
sizeof
(buf1));
161
s->
maxval
= atoi(buf1);
162
if
(s->
maxval
<= 0) {
163
av_log
(avctx,
AV_LOG_ERROR
,
"Invalid maxval: %d\n"
, s->
maxval
);
164
s->
maxval
= 255;
165
}
166
if
(s->
maxval
>= 256) {
167
if
(avctx->
pix_fmt
==
AV_PIX_FMT_GRAY8
) {
168
avctx->
pix_fmt
=
AV_PIX_FMT_GRAY16
;
169
}
else
if
(avctx->
pix_fmt
==
AV_PIX_FMT_RGB24
) {
170
avctx->
pix_fmt
=
AV_PIX_FMT_RGB48
;
171
}
else
if
(avctx->
pix_fmt
==
AV_PIX_FMT_YUV420P
&& s->
maxval
< 65536) {
172
if
(s->
maxval
< 512)
173
avctx->
pix_fmt
=
AV_PIX_FMT_YUV420P9
;
174
else
if
(s->
maxval
< 1024)
175
avctx->
pix_fmt
=
AV_PIX_FMT_YUV420P10
;
176
else
177
avctx->
pix_fmt
=
AV_PIX_FMT_YUV420P16
;
178
}
else
{
179
av_log
(avctx,
AV_LOG_ERROR
,
"Unsupported pixel format\n"
);
180
avctx->
pix_fmt
=
AV_PIX_FMT_NONE
;
181
return
AVERROR_INVALIDDATA
;
182
}
183
}
184
}
else
185
s->
maxval
=1;
186
/* more check if YUV420 */
187
if
(
av_pix_fmt_desc_get
(avctx->
pix_fmt
)->
flags
&
AV_PIX_FMT_FLAG_PLANAR
) {
188
if
((avctx->
width
& 1) != 0)
189
return
AVERROR_INVALIDDATA
;
190
h = (avctx->
height
* 2);
191
if
((h % 3) != 0)
192
return
AVERROR_INVALIDDATA
;
193
h /= 3;
194
avctx->
height
= h;
195
}
196
return
0;
197
}
Generated on Sun Mar 8 2015 02:34:58 for FFmpeg by
1.8.2