3 * Copyright (c) 2002, 2003 Fabrice Bellard
5 * This file is part of Libav.
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.
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.
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
23 #include "bytestream.h"
29 static int pnm_decode_frame(AVCodecContext
*avctx
, void *data
,
30 int *got_frame
, AVPacket
*avpkt
)
32 const uint8_t *buf
= avpkt
->data
;
33 int buf_size
= avpkt
->size
;
34 PNMContext
* const s
= avctx
->priv_data
;
35 AVFrame
*picture
= data
;
36 AVFrame
* const p
= &s
->picture
;
37 int i
, j
, n
, linesize
, h
, upgrade
= 0;
39 int components
, sample_len
, ret
;
43 s
->bytestream_end
= buf
+ buf_size
;
45 if ((ret
= ff_pnm_decode_header(avctx
, s
)) < 0)
49 avctx
->release_buffer(avctx
, p
);
52 if ((ret
= ff_get_buffer(avctx
, p
)) < 0) {
53 av_log(avctx
, AV_LOG_ERROR
, "get_buffer() failed\n");
56 p
->pict_type
= AV_PICTURE_TYPE_I
;
59 switch (avctx
->pix_fmt
) {
61 return AVERROR(EINVAL
);
62 case AV_PIX_FMT_RGB48BE
:
67 case AV_PIX_FMT_RGB24
:
72 case AV_PIX_FMT_GRAY8
:
79 case AV_PIX_FMT_GRAY16BE
:
80 case AV_PIX_FMT_GRAY16LE
:
84 if (s
->maxval
< 65535)
87 case AV_PIX_FMT_MONOWHITE
:
88 case AV_PIX_FMT_MONOBLACK
:
89 n
= (avctx
->width
+ 7) >> 3;
94 linesize
= p
->linesize
[0];
95 if (s
->bytestream
+ n
* avctx
->height
> s
->bytestream_end
)
96 return AVERROR_INVALIDDATA
;
98 for (i
=0; i
<avctx
->height
; i
++) {
100 init_put_bits(&pb
, ptr
, linesize
);
101 for(j
=0; j
<avctx
->width
* components
; j
++){
104 while(s
->bytestream
< s
->bytestream_end
&& (*s
->bytestream
< '0' || *s
->bytestream
> '9' ))
106 if(s
->bytestream
>= s
->bytestream_end
)
107 return AVERROR_INVALIDDATA
;
110 c
= (*s
->bytestream
++) - '0';
112 put_bits(&pb
, sample_len
, (((1<<sample_len
)-1)*v
+ (s
->maxval
>>1))/s
->maxval
);
118 for (i
= 0; i
< avctx
->height
; i
++) {
120 memcpy(ptr
, s
->bytestream
, n
);
121 else if (upgrade
== 1) {
122 unsigned int j
, f
= (255 * 128 + s
->maxval
/ 2) / s
->maxval
;
123 for (j
= 0; j
< n
; j
++)
124 ptr
[j
] = (s
->bytestream
[j
] * f
+ 64) >> 7;
125 } else if (upgrade
== 2) {
126 unsigned int j
, v
, f
= (65535 * 32768 + s
->maxval
/ 2) / s
->maxval
;
127 for (j
= 0; j
< n
/ 2; j
++) {
128 v
= av_be2ne16(((uint16_t *)s
->bytestream
)[j
]);
129 ((uint16_t *)ptr
)[j
] = (v
* f
+ 16384) >> 15;
137 case AV_PIX_FMT_YUV420P
:
138 case AV_PIX_FMT_YUV420P9BE
:
139 case AV_PIX_FMT_YUV420P10BE
:
141 unsigned char *ptr1
, *ptr2
;
145 linesize
= p
->linesize
[0];
146 if (s
->maxval
>= 256)
148 if (s
->bytestream
+ n
* avctx
->height
* 3 / 2 > s
->bytestream_end
)
149 return AVERROR_INVALIDDATA
;
150 for (i
= 0; i
< avctx
->height
; i
++) {
151 memcpy(ptr
, s
->bytestream
, n
);
158 h
= avctx
->height
>> 1;
159 for (i
= 0; i
< h
; i
++) {
160 memcpy(ptr1
, s
->bytestream
, n
);
162 memcpy(ptr2
, s
->bytestream
, n
);
164 ptr1
+= p
->linesize
[1];
165 ptr2
+= p
->linesize
[2];
169 case AV_PIX_FMT_YUV420P16
:
171 uint16_t *ptr1
, *ptr2
;
172 const int f
= (65535 * 32768 + s
->maxval
/ 2) / s
->maxval
;
175 n
= avctx
->width
* 2;
177 linesize
= p
->linesize
[0];
178 if (s
->bytestream
+ n
* avctx
->height
* 3 / 2 > s
->bytestream_end
)
179 return AVERROR_INVALIDDATA
;
180 for (i
= 0; i
< avctx
->height
; i
++) {
181 for (j
= 0; j
< n
/ 2; j
++) {
182 v
= av_be2ne16(((uint16_t *)s
->bytestream
)[j
]);
183 ((uint16_t *)ptr
)[j
] = (v
* f
+ 16384) >> 15;
188 ptr1
= (uint16_t*)p
->data
[1];
189 ptr2
= (uint16_t*)p
->data
[2];
191 h
= avctx
->height
>> 1;
192 for (i
= 0; i
< h
; i
++) {
193 for (j
= 0; j
< n
/ 2; j
++) {
194 v
= av_be2ne16(((uint16_t *)s
->bytestream
)[j
]);
195 ptr1
[j
] = (v
* f
+ 16384) >> 15;
199 for (j
= 0; j
< n
/ 2; j
++) {
200 v
= av_be2ne16(((uint16_t *)s
->bytestream
)[j
]);
201 ptr2
[j
] = (v
* f
+ 16384) >> 15;
205 ptr1
+= p
->linesize
[1] / 2;
206 ptr2
+= p
->linesize
[2] / 2;
210 case AV_PIX_FMT_RGB32
:
212 linesize
= p
->linesize
[0];
213 if (s
->bytestream
+ avctx
->width
* avctx
->height
* 4 > s
->bytestream_end
)
214 return AVERROR_INVALIDDATA
;
215 for (i
= 0; i
< avctx
->height
; i
++) {
218 for (j
= 0; j
< avctx
->width
; j
++) {
219 r
= *s
->bytestream
++;
220 g
= *s
->bytestream
++;
221 b
= *s
->bytestream
++;
222 a
= *s
->bytestream
++;
223 ((uint32_t *)ptr
)[j
] = (a
<< 24) | (r
<< 16) | (g
<< 8) | b
;
229 *picture
= s
->picture
;
232 return s
->bytestream
- s
->bytestream_start
;
236 #if CONFIG_PGM_DECODER
237 AVCodec ff_pgm_decoder
= {
239 .type
= AVMEDIA_TYPE_VIDEO
,
240 .id
= AV_CODEC_ID_PGM
,
241 .priv_data_size
= sizeof(PNMContext
),
244 .decode
= pnm_decode_frame
,
245 .capabilities
= CODEC_CAP_DR1
,
246 .long_name
= NULL_IF_CONFIG_SMALL("PGM (Portable GrayMap) image"),
250 #if CONFIG_PGMYUV_DECODER
251 AVCodec ff_pgmyuv_decoder
= {
253 .type
= AVMEDIA_TYPE_VIDEO
,
254 .id
= AV_CODEC_ID_PGMYUV
,
255 .priv_data_size
= sizeof(PNMContext
),
258 .decode
= pnm_decode_frame
,
259 .capabilities
= CODEC_CAP_DR1
,
260 .long_name
= NULL_IF_CONFIG_SMALL("PGMYUV (Portable GrayMap YUV) image"),
264 #if CONFIG_PPM_DECODER
265 AVCodec ff_ppm_decoder
= {
267 .type
= AVMEDIA_TYPE_VIDEO
,
268 .id
= AV_CODEC_ID_PPM
,
269 .priv_data_size
= sizeof(PNMContext
),
272 .decode
= pnm_decode_frame
,
273 .capabilities
= CODEC_CAP_DR1
,
274 .long_name
= NULL_IF_CONFIG_SMALL("PPM (Portable PixelMap) image"),
278 #if CONFIG_PBM_DECODER
279 AVCodec ff_pbm_decoder
= {
281 .type
= AVMEDIA_TYPE_VIDEO
,
282 .id
= AV_CODEC_ID_PBM
,
283 .priv_data_size
= sizeof(PNMContext
),
286 .decode
= pnm_decode_frame
,
287 .capabilities
= CODEC_CAP_DR1
,
288 .long_name
= NULL_IF_CONFIG_SMALL("PBM (Portable BitMap) image"),
292 #if CONFIG_PAM_DECODER
293 AVCodec ff_pam_decoder
= {
295 .type
= AVMEDIA_TYPE_VIDEO
,
296 .id
= AV_CODEC_ID_PAM
,
297 .priv_data_size
= sizeof(PNMContext
),
300 .decode
= pnm_decode_frame
,
301 .capabilities
= CODEC_CAP_DR1
,
302 .long_name
= NULL_IF_CONFIG_SMALL("PAM (Portable AnyMap) image"),