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
:
139 unsigned char *ptr1
, *ptr2
;
143 linesize
= p
->linesize
[0];
144 if (s
->bytestream
+ n
* avctx
->height
* 3 / 2 > s
->bytestream_end
)
145 return AVERROR_INVALIDDATA
;
146 for (i
= 0; i
< avctx
->height
; i
++) {
147 memcpy(ptr
, s
->bytestream
, n
);
154 h
= avctx
->height
>> 1;
155 for (i
= 0; i
< h
; i
++) {
156 memcpy(ptr1
, s
->bytestream
, n
);
158 memcpy(ptr2
, s
->bytestream
, n
);
160 ptr1
+= p
->linesize
[1];
161 ptr2
+= p
->linesize
[2];
165 case AV_PIX_FMT_RGB32
:
167 linesize
= p
->linesize
[0];
168 if (s
->bytestream
+ avctx
->width
* avctx
->height
* 4 > s
->bytestream_end
)
169 return AVERROR_INVALIDDATA
;
170 for (i
= 0; i
< avctx
->height
; i
++) {
173 for (j
= 0; j
< avctx
->width
; j
++) {
174 r
= *s
->bytestream
++;
175 g
= *s
->bytestream
++;
176 b
= *s
->bytestream
++;
177 a
= *s
->bytestream
++;
178 ((uint32_t *)ptr
)[j
] = (a
<< 24) | (r
<< 16) | (g
<< 8) | b
;
184 *picture
= s
->picture
;
187 return s
->bytestream
- s
->bytestream_start
;
191 #if CONFIG_PGM_DECODER
192 AVCodec ff_pgm_decoder
= {
194 .type
= AVMEDIA_TYPE_VIDEO
,
195 .id
= AV_CODEC_ID_PGM
,
196 .priv_data_size
= sizeof(PNMContext
),
199 .decode
= pnm_decode_frame
,
200 .capabilities
= CODEC_CAP_DR1
,
201 .long_name
= NULL_IF_CONFIG_SMALL("PGM (Portable GrayMap) image"),
205 #if CONFIG_PGMYUV_DECODER
206 AVCodec ff_pgmyuv_decoder
= {
208 .type
= AVMEDIA_TYPE_VIDEO
,
209 .id
= AV_CODEC_ID_PGMYUV
,
210 .priv_data_size
= sizeof(PNMContext
),
213 .decode
= pnm_decode_frame
,
214 .capabilities
= CODEC_CAP_DR1
,
215 .long_name
= NULL_IF_CONFIG_SMALL("PGMYUV (Portable GrayMap YUV) image"),
219 #if CONFIG_PPM_DECODER
220 AVCodec ff_ppm_decoder
= {
222 .type
= AVMEDIA_TYPE_VIDEO
,
223 .id
= AV_CODEC_ID_PPM
,
224 .priv_data_size
= sizeof(PNMContext
),
227 .decode
= pnm_decode_frame
,
228 .capabilities
= CODEC_CAP_DR1
,
229 .long_name
= NULL_IF_CONFIG_SMALL("PPM (Portable PixelMap) image"),
233 #if CONFIG_PBM_DECODER
234 AVCodec ff_pbm_decoder
= {
236 .type
= AVMEDIA_TYPE_VIDEO
,
237 .id
= AV_CODEC_ID_PBM
,
238 .priv_data_size
= sizeof(PNMContext
),
241 .decode
= pnm_decode_frame
,
242 .capabilities
= CODEC_CAP_DR1
,
243 .long_name
= NULL_IF_CONFIG_SMALL("PBM (Portable BitMap) image"),
247 #if CONFIG_PAM_DECODER
248 AVCodec ff_pam_decoder
= {
250 .type
= AVMEDIA_TYPE_VIDEO
,
251 .id
= AV_CODEC_ID_PAM
,
252 .priv_data_size
= sizeof(PNMContext
),
255 .decode
= pnm_decode_frame
,
256 .capabilities
= CODEC_CAP_DR1
,
257 .long_name
= NULL_IF_CONFIG_SMALL("PAM (Portable AnyMap) image"),