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
22 #include "config_components.h"
24 #include "libavutil/half2float.h"
27 #include "codec_internal.h"
32 static void samplecpy(uint8_t *dst
, const uint8_t *src
, int n
, int maxval
)
38 for (i
=0; i
<n
/2; i
++) {
39 ((uint16_t *)dst
)[i
] = AV_RB16(src
+2*i
);
44 static int pnm_decode_frame(AVCodecContext
*avctx
, AVFrame
*p
,
45 int *got_frame
, AVPacket
*avpkt
)
47 const uint8_t *buf
= avpkt
->data
;
48 int buf_size
= avpkt
->size
;
49 PNMContext
* const s
= avctx
->priv_data
;
50 int i
, j
, k
, n
, linesize
, h
, upgrade
= 0, is_mono
= 0;
52 int components
, sample_len
, ret
;
57 s
->bytestream_end
= buf
+ buf_size
;
59 if ((ret
= ff_pnm_decode_header(avctx
, s
)) < 0)
62 if (avctx
->skip_frame
>= AVDISCARD_ALL
)
65 if ((ret
= ff_get_buffer(avctx
, p
, 0)) < 0)
67 avctx
->bits_per_raw_sample
= av_log2(s
->maxval
) + 1;
69 switch (avctx
->pix_fmt
) {
71 return AVERROR(EINVAL
);
72 case AV_PIX_FMT_RGBA64
:
76 if (s
->maxval
< 65535)
79 case AV_PIX_FMT_RGB48
:
83 if (s
->maxval
< 65535)
91 case AV_PIX_FMT_RGB24
:
98 case AV_PIX_FMT_GRAY8
:
105 case AV_PIX_FMT_GRAY8A
:
106 n
= avctx
->width
* 2;
110 case AV_PIX_FMT_GRAY16
:
111 n
= avctx
->width
* 2;
114 if (s
->maxval
< 65535)
117 case AV_PIX_FMT_YA16
:
118 n
= avctx
->width
* 4;
121 if (s
->maxval
< 65535)
124 case AV_PIX_FMT_MONOWHITE
:
125 case AV_PIX_FMT_MONOBLACK
:
126 n
= (avctx
->width
+ 7) >> 3;
132 linesize
= p
->linesize
[0];
133 if (n
* avctx
->height
> s
->bytestream_end
- s
->bytestream
)
134 return AVERROR_INVALIDDATA
;
135 if(s
->type
< 4 || (is_mono
&& s
->type
==7)){
136 for (i
=0; i
<avctx
->height
; i
++) {
138 init_put_bits(&pb
, ptr
, FFABS(linesize
));
139 for(j
=0; j
<avctx
->width
* components
; j
++){
143 while(s
->bytestream
< s
->bytestream_end
&& (*s
->bytestream
< '0' || *s
->bytestream
> '9' ))
145 if(s
->bytestream
>= s
->bytestream_end
)
146 return AVERROR_INVALIDDATA
;
148 /* read a single digit */
149 v
= (*s
->bytestream
++)&1;
151 /* read a sequence of digits */
152 for (k
= 0; k
< 6 && c
<= 9; k
+= 1) {
154 c
= (*s
->bytestream
++) - '0';
157 av_log(avctx
, AV_LOG_ERROR
, "value %d larger than maxval %d\n", v
, s
->maxval
);
158 return AVERROR_INVALIDDATA
;
161 if (sample_len
== 16) {
162 ((uint16_t*)ptr
)[j
] = (((1<<sample_len
)-1)*v
+ (s
->maxval
>>1))/s
->maxval
;
164 put_bits(&pb
, sample_len
, (((1<<sample_len
)-1)*v
+ (s
->maxval
>>1))/s
->maxval
);
166 if (sample_len
!= 16)
171 for (int i
= 0; i
< avctx
->height
; i
++) {
173 samplecpy(ptr
, s
->bytestream
, n
, s
->maxval
);
174 else if (upgrade
== 1) {
175 unsigned int f
= (255 * 128 + s
->maxval
/ 2) / s
->maxval
;
176 for (unsigned j
= 0; j
< n
; j
++)
177 ptr
[j
] = (s
->bytestream
[j
] * f
+ 64) >> 7;
178 } else if (upgrade
== 2) {
179 unsigned int f
= (65535 * 32768 + s
->maxval
/ 2) / s
->maxval
;
180 for (unsigned j
= 0; j
< n
/ 2; j
++) {
181 unsigned v
= AV_RB16(s
->bytestream
+ 2*j
);
182 ((uint16_t *)ptr
)[j
] = (v
* f
+ 16384) >> 15;
190 case AV_PIX_FMT_YUV420P
:
191 case AV_PIX_FMT_YUV420P9
:
192 case AV_PIX_FMT_YUV420P10
:
194 unsigned char *ptr1
, *ptr2
;
198 linesize
= p
->linesize
[0];
199 if (s
->maxval
>= 256)
201 if (n
* avctx
->height
* 3 / 2 > s
->bytestream_end
- s
->bytestream
)
202 return AVERROR_INVALIDDATA
;
203 for (i
= 0; i
< avctx
->height
; i
++) {
204 samplecpy(ptr
, s
->bytestream
, n
, s
->maxval
);
211 h
= avctx
->height
>> 1;
212 for (i
= 0; i
< h
; i
++) {
213 samplecpy(ptr1
, s
->bytestream
, n
, s
->maxval
);
215 samplecpy(ptr2
, s
->bytestream
, n
, s
->maxval
);
217 ptr1
+= p
->linesize
[1];
218 ptr2
+= p
->linesize
[2];
222 case AV_PIX_FMT_YUV420P16
:
224 uint16_t *ptr1
, *ptr2
;
225 const int f
= (65535 * 32768 + s
->maxval
/ 2) / s
->maxval
;
228 n
= avctx
->width
* 2;
230 linesize
= p
->linesize
[0];
231 if (n
* avctx
->height
* 3 / 2 > s
->bytestream_end
- s
->bytestream
)
232 return AVERROR_INVALIDDATA
;
233 for (i
= 0; i
< avctx
->height
; i
++) {
234 for (j
= 0; j
< n
/ 2; j
++) {
235 v
= AV_RB16(s
->bytestream
+ 2*j
);
236 ((uint16_t *)ptr
)[j
] = (v
* f
+ 16384) >> 15;
241 ptr1
= (uint16_t*)p
->data
[1];
242 ptr2
= (uint16_t*)p
->data
[2];
244 h
= avctx
->height
>> 1;
245 for (i
= 0; i
< h
; i
++) {
246 for (j
= 0; j
< n
/ 2; j
++) {
247 v
= AV_RB16(s
->bytestream
+ 2*j
);
248 ptr1
[j
] = (v
* f
+ 16384) >> 15;
252 for (j
= 0; j
< n
/ 2; j
++) {
253 v
= AV_RB16(s
->bytestream
+ 2*j
);
254 ptr2
[j
] = (v
* f
+ 16384) >> 15;
258 ptr1
+= p
->linesize
[1] / 2;
259 ptr2
+= p
->linesize
[2] / 2;
263 case AV_PIX_FMT_GBRPF32
:
265 if (avctx
->width
* avctx
->height
* 12LL > s
->bytestream_end
- s
->bytestream
)
266 return AVERROR_INVALIDDATA
;
267 scale
= 1.f
/ s
->scale
;
271 r
= (float *)p
->data
[2];
272 g
= (float *)p
->data
[0];
273 b
= (float *)p
->data
[1];
274 for (int i
= 0; i
< avctx
->height
; i
++) {
275 for (int j
= 0; j
< avctx
->width
; j
++) {
276 r
[j
] = av_int2float(AV_RL32(s
->bytestream
+0)) * scale
;
277 g
[j
] = av_int2float(AV_RL32(s
->bytestream
+4)) * scale
;
278 b
[j
] = av_int2float(AV_RL32(s
->bytestream
+8)) * scale
;
282 r
+= p
->linesize
[2] / 4;
283 g
+= p
->linesize
[0] / 4;
284 b
+= p
->linesize
[1] / 4;
289 r
= (float *)p
->data
[2];
290 g
= (float *)p
->data
[0];
291 b
= (float *)p
->data
[1];
292 for (int i
= 0; i
< avctx
->height
; i
++) {
293 for (int j
= 0; j
< avctx
->width
; j
++) {
294 r
[j
] = av_int2float(AV_RB32(s
->bytestream
+0)) * scale
;
295 g
[j
] = av_int2float(AV_RB32(s
->bytestream
+4)) * scale
;
296 b
[j
] = av_int2float(AV_RB32(s
->bytestream
+8)) * scale
;
300 r
+= p
->linesize
[2] / 4;
301 g
+= p
->linesize
[0] / 4;
302 b
+= p
->linesize
[1] / 4;
306 if (avctx
->width
* avctx
->height
* 6 > s
->bytestream_end
- s
->bytestream
)
307 return AVERROR_INVALIDDATA
;
308 scale
= 1.f
/ s
->scale
;
312 r
= (float *)p
->data
[2];
313 g
= (float *)p
->data
[0];
314 b
= (float *)p
->data
[1];
315 for (int i
= 0; i
< avctx
->height
; i
++) {
316 for (int j
= 0; j
< avctx
->width
; j
++) {
317 r
[j
] = av_int2float(half2float(AV_RL16(s
->bytestream
+0), &s
->h2f_tables
)) * scale
;
318 g
[j
] = av_int2float(half2float(AV_RL16(s
->bytestream
+2), &s
->h2f_tables
)) * scale
;
319 b
[j
] = av_int2float(half2float(AV_RL16(s
->bytestream
+4), &s
->h2f_tables
)) * scale
;
323 r
+= p
->linesize
[2] / 4;
324 g
+= p
->linesize
[0] / 4;
325 b
+= p
->linesize
[1] / 4;
330 r
= (float *)p
->data
[2];
331 g
= (float *)p
->data
[0];
332 b
= (float *)p
->data
[1];
333 for (int i
= 0; i
< avctx
->height
; i
++) {
334 for (int j
= 0; j
< avctx
->width
; j
++) {
335 r
[j
] = av_int2float(half2float(AV_RB16(s
->bytestream
+0), &s
->h2f_tables
)) * scale
;
336 g
[j
] = av_int2float(half2float(AV_RB16(s
->bytestream
+2), &s
->h2f_tables
)) * scale
;
337 b
[j
] = av_int2float(half2float(AV_RB16(s
->bytestream
+4), &s
->h2f_tables
)) * scale
;
341 r
+= p
->linesize
[2] / 4;
342 g
+= p
->linesize
[0] / 4;
343 b
+= p
->linesize
[1] / 4;
347 /* PFM is encoded from bottom to top */
348 p
->data
[0] += (avctx
->height
- 1) * p
->linesize
[0];
349 p
->data
[1] += (avctx
->height
- 1) * p
->linesize
[1];
350 p
->data
[2] += (avctx
->height
- 1) * p
->linesize
[2];
351 p
->linesize
[0] = -p
->linesize
[0];
352 p
->linesize
[1] = -p
->linesize
[1];
353 p
->linesize
[2] = -p
->linesize
[2];
355 case AV_PIX_FMT_GRAYF32
:
357 if (avctx
->width
* avctx
->height
* 4 > s
->bytestream_end
- s
->bytestream
)
358 return AVERROR_INVALIDDATA
;
359 scale
= 1.f
/ s
->scale
;
361 float *g
= (float *)p
->data
[0];
362 for (int i
= 0; i
< avctx
->height
; i
++) {
363 for (int j
= 0; j
< avctx
->width
; j
++) {
364 g
[j
] = av_int2float(AV_RL32(s
->bytestream
)) * scale
;
367 g
+= p
->linesize
[0] / 4;
370 float *g
= (float *)p
->data
[0];
371 for (int i
= 0; i
< avctx
->height
; i
++) {
372 for (int j
= 0; j
< avctx
->width
; j
++) {
373 g
[j
] = av_int2float(AV_RB32(s
->bytestream
)) * scale
;
376 g
+= p
->linesize
[0] / 4;
380 if (avctx
->width
* avctx
->height
* 2 > s
->bytestream_end
- s
->bytestream
)
381 return AVERROR_INVALIDDATA
;
382 scale
= 1.f
/ s
->scale
;
384 float *g
= (float *)p
->data
[0];
385 for (int i
= 0; i
< avctx
->height
; i
++) {
386 for (int j
= 0; j
< avctx
->width
; j
++) {
387 g
[j
] = av_int2float(half2float(AV_RL16(s
->bytestream
), &s
->h2f_tables
)) * scale
;
390 g
+= p
->linesize
[0] / 4;
393 float *g
= (float *)p
->data
[0];
394 for (int i
= 0; i
< avctx
->height
; i
++) {
395 for (int j
= 0; j
< avctx
->width
; j
++) {
396 g
[j
] = av_int2float(half2float(AV_RB16(s
->bytestream
), &s
->h2f_tables
)) * scale
;
399 g
+= p
->linesize
[0] / 4;
403 /* PFM is encoded from bottom to top */
404 p
->data
[0] += (avctx
->height
- 1) * p
->linesize
[0];
405 p
->linesize
[0] = -p
->linesize
[0];
410 return s
->bytestream
- s
->bytestream_start
;
414 #if CONFIG_PGM_DECODER
415 const FFCodec ff_pgm_decoder
= {
417 CODEC_LONG_NAME("PGM (Portable GrayMap) image"),
418 .p
.type
= AVMEDIA_TYPE_VIDEO
,
419 .p
.id
= AV_CODEC_ID_PGM
,
420 .p
.capabilities
= AV_CODEC_CAP_DR1
,
421 .priv_data_size
= sizeof(PNMContext
),
422 .caps_internal
= FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM
,
423 FF_CODEC_DECODE_CB(pnm_decode_frame
),
427 #if CONFIG_PGMYUV_DECODER
428 const FFCodec ff_pgmyuv_decoder
= {
430 CODEC_LONG_NAME("PGMYUV (Portable GrayMap YUV) image"),
431 .p
.type
= AVMEDIA_TYPE_VIDEO
,
432 .p
.id
= AV_CODEC_ID_PGMYUV
,
433 .p
.capabilities
= AV_CODEC_CAP_DR1
,
434 .priv_data_size
= sizeof(PNMContext
),
435 .caps_internal
= FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM
,
436 FF_CODEC_DECODE_CB(pnm_decode_frame
),
440 #if CONFIG_PPM_DECODER
441 const FFCodec ff_ppm_decoder
= {
443 CODEC_LONG_NAME("PPM (Portable PixelMap) image"),
444 .p
.type
= AVMEDIA_TYPE_VIDEO
,
445 .p
.id
= AV_CODEC_ID_PPM
,
446 .p
.capabilities
= AV_CODEC_CAP_DR1
,
447 .priv_data_size
= sizeof(PNMContext
),
448 .caps_internal
= FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM
,
449 FF_CODEC_DECODE_CB(pnm_decode_frame
),
453 #if CONFIG_PBM_DECODER
454 const FFCodec ff_pbm_decoder
= {
456 CODEC_LONG_NAME("PBM (Portable BitMap) image"),
457 .p
.type
= AVMEDIA_TYPE_VIDEO
,
458 .p
.id
= AV_CODEC_ID_PBM
,
459 .p
.capabilities
= AV_CODEC_CAP_DR1
,
460 .priv_data_size
= sizeof(PNMContext
),
461 .caps_internal
= FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM
,
462 FF_CODEC_DECODE_CB(pnm_decode_frame
),
466 #if CONFIG_PAM_DECODER
467 const FFCodec ff_pam_decoder
= {
469 CODEC_LONG_NAME("PAM (Portable AnyMap) image"),
470 .p
.type
= AVMEDIA_TYPE_VIDEO
,
471 .p
.id
= AV_CODEC_ID_PAM
,
472 .p
.capabilities
= AV_CODEC_CAP_DR1
,
473 .priv_data_size
= sizeof(PNMContext
),
474 .caps_internal
= FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM
,
475 FF_CODEC_DECODE_CB(pnm_decode_frame
),
479 #if CONFIG_PFM_DECODER
480 const FFCodec ff_pfm_decoder
= {
482 CODEC_LONG_NAME("PFM (Portable FloatMap) image"),
483 .p
.type
= AVMEDIA_TYPE_VIDEO
,
484 .p
.id
= AV_CODEC_ID_PFM
,
485 .p
.capabilities
= AV_CODEC_CAP_DR1
,
486 .priv_data_size
= sizeof(PNMContext
),
487 .caps_internal
= FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM
,
488 FF_CODEC_DECODE_CB(pnm_decode_frame
),
492 #if CONFIG_PHM_DECODER
493 static av_cold
int phm_dec_init(AVCodecContext
*avctx
)
495 PNMContext
*s
= avctx
->priv_data
;
497 ff_init_half2float_tables(&s
->h2f_tables
);
502 const FFCodec ff_phm_decoder
= {
504 CODEC_LONG_NAME("PHM (Portable HalfFloatMap) image"),
505 .p
.type
= AVMEDIA_TYPE_VIDEO
,
506 .p
.id
= AV_CODEC_ID_PHM
,
507 .p
.capabilities
= AV_CODEC_CAP_DR1
,
508 .priv_data_size
= sizeof(PNMContext
),
509 .init
= phm_dec_init
,
510 .caps_internal
= FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM
,
511 FF_CODEC_DECODE_CB(pnm_decode_frame
),