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
25 static inline int pnm_space(int c
)
27 return c
== ' ' || c
== '\n' || c
== '\r' || c
== '\t';
30 static void pnm_get(PNMContext
*sc
, char *str
, int buf_size
)
35 /* skip spaces and comments */
37 c
= *sc
->bytestream
++;
40 c
= *sc
->bytestream
++;
41 } while (c
!= '\n' && sc
->bytestream
< sc
->bytestream_end
);
42 } else if (!pnm_space(c
)) {
48 while (sc
->bytestream
< sc
->bytestream_end
&& !pnm_space(c
)) {
49 if ((s
- str
) < buf_size
- 1)
51 c
= *sc
->bytestream
++;
56 int ff_pnm_decode_header(AVCodecContext
*avctx
, PNMContext
* const s
)
58 char buf1
[32], tuple_type
[32];
59 int h
, w
, depth
, maxval
;
61 pnm_get(s
, buf1
, sizeof(buf1
));
62 if (!strcmp(buf1
, "P4")) {
63 avctx
->pix_fmt
= PIX_FMT_MONOWHITE
;
64 } else if (!strcmp(buf1
, "P5")) {
65 if (avctx
->codec_id
== CODEC_ID_PGMYUV
)
66 avctx
->pix_fmt
= PIX_FMT_YUV420P
;
68 avctx
->pix_fmt
= PIX_FMT_GRAY8
;
69 } else if (!strcmp(buf1
, "P6")) {
70 avctx
->pix_fmt
= PIX_FMT_RGB24
;
71 } else if (!strcmp(buf1
, "P7")) {
78 pnm_get(s
, buf1
, sizeof(buf1
));
79 if (!strcmp(buf1
, "WIDTH")) {
80 pnm_get(s
, buf1
, sizeof(buf1
));
81 w
= strtol(buf1
, NULL
, 10);
82 } else if (!strcmp(buf1
, "HEIGHT")) {
83 pnm_get(s
, buf1
, sizeof(buf1
));
84 h
= strtol(buf1
, NULL
, 10);
85 } else if (!strcmp(buf1
, "DEPTH")) {
86 pnm_get(s
, buf1
, sizeof(buf1
));
87 depth
= strtol(buf1
, NULL
, 10);
88 } else if (!strcmp(buf1
, "MAXVAL")) {
89 pnm_get(s
, buf1
, sizeof(buf1
));
90 maxval
= strtol(buf1
, NULL
, 10);
91 } else if (!strcmp(buf1
, "TUPLETYPE")) {
92 pnm_get(s
, tuple_type
, sizeof(tuple_type
));
93 } else if (!strcmp(buf1
, "ENDHDR")) {
99 /* check that all tags are present */
100 if (w
<= 0 || h
<= 0 || maxval
<= 0 || depth
<= 0 || tuple_type
[0] == '\0' || avcodec_check_dimensions(avctx
, w
, h
))
107 avctx
->pix_fmt
= PIX_FMT_MONOWHITE
;
109 avctx
->pix_fmt
= PIX_FMT_GRAY8
;
110 } else if (depth
== 3) {
112 avctx
->pix_fmt
= PIX_FMT_RGB24
;
114 av_log(avctx
, AV_LOG_ERROR
, "16-bit components are only supported for grayscale\n");
115 avctx
->pix_fmt
= PIX_FMT_NONE
;
118 } else if (depth
== 4) {
119 avctx
->pix_fmt
= PIX_FMT_RGB32
;
127 pnm_get(s
, buf1
, sizeof(buf1
));
128 avctx
->width
= atoi(buf1
);
129 if (avctx
->width
<= 0)
131 pnm_get(s
, buf1
, sizeof(buf1
));
132 avctx
->height
= atoi(buf1
);
133 if(avcodec_check_dimensions(avctx
, avctx
->width
, avctx
->height
))
135 if (avctx
->pix_fmt
!= PIX_FMT_MONOWHITE
) {
136 pnm_get(s
, buf1
, sizeof(buf1
));
137 s
->maxval
= atoi(buf1
);
138 if (s
->maxval
>= 256) {
139 if (avctx
->pix_fmt
== PIX_FMT_GRAY8
) {
140 avctx
->pix_fmt
= PIX_FMT_GRAY16BE
;
141 if (s
->maxval
!= 65535)
142 avctx
->pix_fmt
= PIX_FMT_GRAY16
;
143 } else if (avctx
->pix_fmt
== PIX_FMT_RGB24
) {
145 avctx
->pix_fmt
= PIX_FMT_RGB48BE
;
147 av_log(avctx
, AV_LOG_ERROR
, "Unsupported pixel format\n");
148 avctx
->pix_fmt
= PIX_FMT_NONE
;
153 /* more check if YUV420 */
154 if (avctx
->pix_fmt
== PIX_FMT_YUV420P
) {
155 if ((avctx
->width
& 1) != 0)
157 h
= (avctx
->height
* 2);
166 av_cold
int ff_pnm_end(AVCodecContext
*avctx
)
168 PNMContext
*s
= avctx
->priv_data
;
170 if (s
->picture
.data
[0])
171 avctx
->release_buffer(avctx
, &s
->picture
);
176 av_cold
int ff_pnm_init(AVCodecContext
*avctx
)
178 PNMContext
*s
= avctx
->priv_data
;
180 avcodec_get_frame_defaults((AVFrame
*)&s
->picture
);
181 avctx
->coded_frame
= (AVFrame
*)&s
->picture
;