3 * Copyright (c) 2002, 2003 Fabrice Bellard.
5 * This file is part of FFmpeg.
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.
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.
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
24 static inline int pnm_space(int c
)
26 return c
== ' ' || c
== '\n' || c
== '\r' || c
== '\t';
29 static void pnm_get(PNMContext
*sc
, char *str
, int buf_size
)
34 /* skip spaces and comments */
36 c
= *sc
->bytestream
++;
39 c
= *sc
->bytestream
++;
40 } while (c
!= '\n' && sc
->bytestream
< sc
->bytestream_end
);
41 } else if (!pnm_space(c
)) {
47 while (sc
->bytestream
< sc
->bytestream_end
&& !pnm_space(c
)) {
48 if ((s
- str
) < buf_size
- 1)
50 c
= *sc
->bytestream
++;
55 int ff_pnm_decode_header(AVCodecContext
*avctx
, PNMContext
* const s
){
56 char buf1
[32], tuple_type
[32];
57 int h
, w
, depth
, maxval
;
59 pnm_get(s
, buf1
, sizeof(buf1
));
60 if (!strcmp(buf1
, "P4")) {
61 avctx
->pix_fmt
= PIX_FMT_MONOWHITE
;
62 } else if (!strcmp(buf1
, "P5")) {
63 if (avctx
->codec_id
== CODEC_ID_PGMYUV
)
64 avctx
->pix_fmt
= PIX_FMT_YUV420P
;
66 avctx
->pix_fmt
= PIX_FMT_GRAY8
;
67 } else if (!strcmp(buf1
, "P6")) {
68 avctx
->pix_fmt
= PIX_FMT_RGB24
;
69 } else if (!strcmp(buf1
, "P7")) {
76 pnm_get(s
, buf1
, sizeof(buf1
));
77 if (!strcmp(buf1
, "WIDTH")) {
78 pnm_get(s
, buf1
, sizeof(buf1
));
79 w
= strtol(buf1
, NULL
, 10);
80 } else if (!strcmp(buf1
, "HEIGHT")) {
81 pnm_get(s
, buf1
, sizeof(buf1
));
82 h
= strtol(buf1
, NULL
, 10);
83 } else if (!strcmp(buf1
, "DEPTH")) {
84 pnm_get(s
, buf1
, sizeof(buf1
));
85 depth
= strtol(buf1
, NULL
, 10);
86 } else if (!strcmp(buf1
, "MAXVAL")) {
87 pnm_get(s
, buf1
, sizeof(buf1
));
88 maxval
= strtol(buf1
, NULL
, 10);
89 } else if (!strcmp(buf1
, "TUPLETYPE")) {
90 pnm_get(s
, tuple_type
, sizeof(tuple_type
));
91 } else if (!strcmp(buf1
, "ENDHDR")) {
97 /* check that all tags are present */
98 if (w
<= 0 || h
<= 0 || maxval
<= 0 || depth
<= 0 || tuple_type
[0] == '\0' || avcodec_check_dimensions(avctx
, w
, h
))
105 avctx
->pix_fmt
= PIX_FMT_MONOWHITE
;
107 avctx
->pix_fmt
= PIX_FMT_GRAY8
;
108 } else if (depth
== 3) {
109 avctx
->pix_fmt
= PIX_FMT_RGB24
;
110 } else if (depth
== 4) {
111 avctx
->pix_fmt
= PIX_FMT_RGB32
;
119 pnm_get(s
, buf1
, sizeof(buf1
));
120 avctx
->width
= atoi(buf1
);
121 if (avctx
->width
<= 0)
123 pnm_get(s
, buf1
, sizeof(buf1
));
124 avctx
->height
= atoi(buf1
);
125 if(avcodec_check_dimensions(avctx
, avctx
->width
, avctx
->height
))
127 if (avctx
->pix_fmt
!= PIX_FMT_MONOWHITE
) {
128 pnm_get(s
, buf1
, sizeof(buf1
));
129 s
->maxval
= atoi(buf1
);
130 if(s
->maxval
>= 256 && avctx
->pix_fmt
== PIX_FMT_GRAY8
) {
131 avctx
->pix_fmt
= PIX_FMT_GRAY16BE
;
132 if (s
->maxval
!= 65535)
133 avctx
->pix_fmt
= PIX_FMT_GRAY16
;
136 /* more check if YUV420 */
137 if (avctx
->pix_fmt
== PIX_FMT_YUV420P
) {
138 if ((avctx
->width
& 1) != 0)
140 h
= (avctx
->height
* 2);