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
* const p
= data
;
36 int i
, j
, n
, linesize
, h
, upgrade
= 0;
38 int components
, sample_len
, ret
;
42 s
->bytestream_end
= buf
+ buf_size
;
44 if ((ret
= ff_pnm_decode_header(avctx
, s
)) < 0)
47 if ((ret
= ff_get_buffer(avctx
, p
, 0)) < 0) {
48 av_log(avctx
, AV_LOG_ERROR
, "get_buffer() failed\n");
51 p
->pict_type
= AV_PICTURE_TYPE_I
;
54 switch (avctx
->pix_fmt
) {
56 return AVERROR(EINVAL
);
57 case AV_PIX_FMT_RGB48BE
:
62 case AV_PIX_FMT_RGB24
:
67 case AV_PIX_FMT_GRAY8
:
74 case AV_PIX_FMT_GRAY16BE
:
75 case AV_PIX_FMT_GRAY16LE
:
79 if (s
->maxval
< 65535)
82 case AV_PIX_FMT_MONOWHITE
:
83 case AV_PIX_FMT_MONOBLACK
:
84 n
= (avctx
->width
+ 7) >> 3;
89 linesize
= p
->linesize
[0];
90 if (s
->bytestream
+ n
* avctx
->height
> s
->bytestream_end
)
91 return AVERROR_INVALIDDATA
;
93 for (i
=0; i
<avctx
->height
; i
++) {
95 init_put_bits(&pb
, ptr
, linesize
);
96 for(j
=0; j
<avctx
->width
* components
; j
++){
99 while(s
->bytestream
< s
->bytestream_end
&& (*s
->bytestream
< '0' || *s
->bytestream
> '9' ))
101 if(s
->bytestream
>= s
->bytestream_end
)
102 return AVERROR_INVALIDDATA
;
105 c
= (*s
->bytestream
++) - '0';
107 put_bits(&pb
, sample_len
, (((1<<sample_len
)-1)*v
+ (s
->maxval
>>1))/s
->maxval
);
113 for (i
= 0; i
< avctx
->height
; i
++) {
115 memcpy(ptr
, s
->bytestream
, n
);
116 else if (upgrade
== 1) {
117 unsigned int j
, f
= (255 * 128 + s
->maxval
/ 2) / s
->maxval
;
118 for (j
= 0; j
< n
; j
++)
119 ptr
[j
] = (s
->bytestream
[j
] * f
+ 64) >> 7;
120 } else if (upgrade
== 2) {
121 unsigned int j
, v
, f
= (65535 * 32768 + s
->maxval
/ 2) / s
->maxval
;
122 for (j
= 0; j
< n
/ 2; j
++) {
123 v
= av_be2ne16(((uint16_t *)s
->bytestream
)[j
]);
124 ((uint16_t *)ptr
)[j
] = (v
* f
+ 16384) >> 15;
132 case AV_PIX_FMT_YUV420P
:
133 case AV_PIX_FMT_YUV420P9BE
:
134 case AV_PIX_FMT_YUV420P10BE
:
136 unsigned char *ptr1
, *ptr2
;
140 linesize
= p
->linesize
[0];
141 if (s
->maxval
>= 256)
143 if (s
->bytestream
+ n
* avctx
->height
* 3 / 2 > s
->bytestream_end
)
144 return AVERROR_INVALIDDATA
;
145 for (i
= 0; i
< avctx
->height
; i
++) {
146 memcpy(ptr
, s
->bytestream
, n
);
153 h
= avctx
->height
>> 1;
154 for (i
= 0; i
< h
; i
++) {
155 memcpy(ptr1
, s
->bytestream
, n
);
157 memcpy(ptr2
, s
->bytestream
, n
);
159 ptr1
+= p
->linesize
[1];
160 ptr2
+= p
->linesize
[2];
164 case AV_PIX_FMT_YUV420P16
:
166 uint16_t *ptr1
, *ptr2
;
167 const int f
= (65535 * 32768 + s
->maxval
/ 2) / s
->maxval
;
170 n
= avctx
->width
* 2;
172 linesize
= p
->linesize
[0];
173 if (s
->bytestream
+ n
* avctx
->height
* 3 / 2 > s
->bytestream_end
)
174 return AVERROR_INVALIDDATA
;
175 for (i
= 0; i
< avctx
->height
; i
++) {
176 for (j
= 0; j
< n
/ 2; j
++) {
177 v
= av_be2ne16(((uint16_t *)s
->bytestream
)[j
]);
178 ((uint16_t *)ptr
)[j
] = (v
* f
+ 16384) >> 15;
183 ptr1
= (uint16_t*)p
->data
[1];
184 ptr2
= (uint16_t*)p
->data
[2];
186 h
= avctx
->height
>> 1;
187 for (i
= 0; i
< h
; i
++) {
188 for (j
= 0; j
< n
/ 2; j
++) {
189 v
= av_be2ne16(((uint16_t *)s
->bytestream
)[j
]);
190 ptr1
[j
] = (v
* f
+ 16384) >> 15;
194 for (j
= 0; j
< n
/ 2; j
++) {
195 v
= av_be2ne16(((uint16_t *)s
->bytestream
)[j
]);
196 ptr2
[j
] = (v
* f
+ 16384) >> 15;
200 ptr1
+= p
->linesize
[1] / 2;
201 ptr2
+= p
->linesize
[2] / 2;
205 case AV_PIX_FMT_RGB32
:
207 linesize
= p
->linesize
[0];
208 if (s
->bytestream
+ avctx
->width
* avctx
->height
* 4 > s
->bytestream_end
)
209 return AVERROR_INVALIDDATA
;
210 for (i
= 0; i
< avctx
->height
; i
++) {
213 for (j
= 0; j
< avctx
->width
; j
++) {
214 r
= *s
->bytestream
++;
215 g
= *s
->bytestream
++;
216 b
= *s
->bytestream
++;
217 a
= *s
->bytestream
++;
218 ((uint32_t *)ptr
)[j
] = (a
<< 24) | (r
<< 16) | (g
<< 8) | b
;
226 return s
->bytestream
- s
->bytestream_start
;
230 #if CONFIG_PGM_DECODER
231 AVCodec ff_pgm_decoder
= {
233 .long_name
= NULL_IF_CONFIG_SMALL("PGM (Portable GrayMap) image"),
234 .type
= AVMEDIA_TYPE_VIDEO
,
235 .id
= AV_CODEC_ID_PGM
,
236 .priv_data_size
= sizeof(PNMContext
),
237 .decode
= pnm_decode_frame
,
238 .capabilities
= AV_CODEC_CAP_DR1
,
242 #if CONFIG_PGMYUV_DECODER
243 AVCodec ff_pgmyuv_decoder
= {
245 .long_name
= NULL_IF_CONFIG_SMALL("PGMYUV (Portable GrayMap YUV) image"),
246 .type
= AVMEDIA_TYPE_VIDEO
,
247 .id
= AV_CODEC_ID_PGMYUV
,
248 .priv_data_size
= sizeof(PNMContext
),
249 .decode
= pnm_decode_frame
,
250 .capabilities
= AV_CODEC_CAP_DR1
,
254 #if CONFIG_PPM_DECODER
255 AVCodec ff_ppm_decoder
= {
257 .long_name
= NULL_IF_CONFIG_SMALL("PPM (Portable PixelMap) image"),
258 .type
= AVMEDIA_TYPE_VIDEO
,
259 .id
= AV_CODEC_ID_PPM
,
260 .priv_data_size
= sizeof(PNMContext
),
261 .decode
= pnm_decode_frame
,
262 .capabilities
= AV_CODEC_CAP_DR1
,
266 #if CONFIG_PBM_DECODER
267 AVCodec ff_pbm_decoder
= {
269 .long_name
= NULL_IF_CONFIG_SMALL("PBM (Portable BitMap) image"),
270 .type
= AVMEDIA_TYPE_VIDEO
,
271 .id
= AV_CODEC_ID_PBM
,
272 .priv_data_size
= sizeof(PNMContext
),
273 .decode
= pnm_decode_frame
,
274 .capabilities
= AV_CODEC_CAP_DR1
,
278 #if CONFIG_PAM_DECODER
279 AVCodec ff_pam_decoder
= {
281 .long_name
= NULL_IF_CONFIG_SMALL("PAM (Portable AnyMap) image"),
282 .type
= AVMEDIA_TYPE_VIDEO
,
283 .id
= AV_CODEC_ID_PAM
,
284 .priv_data_size
= sizeof(PNMContext
),
285 .decode
= pnm_decode_frame
,
286 .capabilities
= AV_CODEC_CAP_DR1
,