diff options
Diffstat (limited to 'libavcodec/pnm.c')
-rw-r--r-- | libavcodec/pnm.c | 21 |
1 files changed, 17 insertions, 4 deletions
diff --git a/libavcodec/pnm.c b/libavcodec/pnm.c index b5c2881948..a6ae01b494 100644 --- a/libavcodec/pnm.c +++ b/libavcodec/pnm.c @@ -24,6 +24,7 @@ #include "libavutil/avassert.h" #include "libavutil/imgutils.h" +#include "libavutil/avstring.h" #include "avcodec.h" #include "internal.h" #include "pnm.h" @@ -69,8 +70,9 @@ int ff_pnm_decode_header(AVCodecContext *avctx, PNMContext * const s) if (s->bytestream_end - s->bytestream < 3 || s->bytestream[0] != 'P' || - s->bytestream[1] < '1' || - s->bytestream[1] > '7') { + (s->bytestream[1] < '1' || + s->bytestream[1] > '7' && + s->bytestream[1] != 'F')) { s->bytestream += s->bytestream_end > s->bytestream; s->bytestream += s->bytestream_end > s->bytestream; return AVERROR_INVALIDDATA; @@ -78,7 +80,9 @@ int ff_pnm_decode_header(AVCodecContext *avctx, PNMContext * const s) pnm_get(s, buf1, sizeof(buf1)); s->type= buf1[1]-'0'; - if (s->type==1 || s->type==4) { + if (buf1[1] == 'F') { + avctx->pix_fmt = AV_PIX_FMT_GBRPF32; + } else if (s->type==1 || s->type==4) { avctx->pix_fmt = AV_PIX_FMT_MONOWHITE; } else if (s->type==2 || s->type==5) { if (avctx->codec_id == AV_CODEC_ID_PGMYUV) @@ -173,7 +177,16 @@ int ff_pnm_decode_header(AVCodecContext *avctx, PNMContext * const s) if (ret < 0) return ret; - if (avctx->pix_fmt != AV_PIX_FMT_MONOWHITE && avctx->pix_fmt != AV_PIX_FMT_MONOBLACK) { + if (avctx->pix_fmt == AV_PIX_FMT_GBRPF32) { + pnm_get(s, buf1, sizeof(buf1)); + if (av_sscanf(buf1, "%f", &s->scale) != 1) { + av_log(avctx, AV_LOG_ERROR, "Invalid scale.\n"); + return AVERROR_INVALIDDATA; + } + s->endian = s->scale < 0.f; + s->scale = fabsf(s->scale); + s->maxval = (1ULL << 32) - 1; + } else if (avctx->pix_fmt != AV_PIX_FMT_MONOWHITE && avctx->pix_fmt != AV_PIX_FMT_MONOBLACK) { pnm_get(s, buf1, sizeof(buf1)); s->maxval = atoi(buf1); if (s->maxval <= 0 || s->maxval > UINT16_MAX) { |