From d538dd824ee7abf9f3bb6459485f3e804fcc4777 Mon Sep 17 00:00:00 2001 From: Carl Eugen Hoyos Date: Sat, 21 Jun 2014 21:43:19 +0200 Subject: avformat: Add image3 demuxers with format autodetection Reviewed-by: wm4 Signed-off-by: Michael Niedermayer --- libavformat/img2dec.c | 138 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 137 insertions(+), 1 deletion(-) (limited to 'libavformat/img2dec.c') diff --git a/libavformat/img2dec.c b/libavformat/img2dec.c index dc962dbb33..a8f87efb67 100644 --- a/libavformat/img2dec.c +++ b/libavformat/img2dec.c @@ -27,6 +27,7 @@ #include "libavutil/opt.h" #include "libavutil/pixdesc.h" #include "libavutil/parseutils.h" +#include "libavutil/intreadwrite.h" #include "avformat.h" #include "internal.h" #include "img2.h" @@ -302,7 +303,33 @@ int ff_img_read_header(AVFormatContext *s1) const char *str = strrchr(s->path, '.'); s->split_planes = str && !av_strcasecmp(str + 1, "y"); st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - st->codec->codec_id = ff_guess_image2_codec(s->path); + if (s1->pb) { + uint8_t probe_buffer[AVPROBE_PADDING_SIZE] = {0}; + AVInputFormat *fmt = NULL; + AVProbeData pd; + int ret = avio_read(s1->pb, probe_buffer, 8); + if (ret < 8) + return AVERROR(EINVAL); + avio_seek(s1->pb, -8, SEEK_CUR); + + pd.buf = probe_buffer; + pd.buf_size = 8; + pd.filename = s1->filename; + + while ((fmt = av_iformat_next(fmt))) { + if (fmt->read_header != ff_img_read_header || + !fmt->read_probe || + (fmt->flags & AVFMT_NOFILE) || + !fmt->raw_codec_id) + continue; + if (fmt->read_probe(&pd) > 0) { + st->codec->codec_id = fmt->raw_codec_id; + break; + } + } + } + if (st->codec->codec_id == AV_CODEC_ID_NONE) + st->codec->codec_id = ff_guess_image2_codec(s->path); if (st->codec->codec_id == AV_CODEC_ID_LJPEG) st->codec->codec_id = AV_CODEC_ID_MJPEG; if (st->codec->codec_id == AV_CODEC_ID_ALIAS_PIX) // we cannot distingiush this from BRENDER_PIX @@ -387,6 +414,8 @@ int ff_img_read_packet(AVFormatContext *s1, AVPacket *pkt) return AVERROR(EIO); if (s->frame_size > 0) { size[0] = s->frame_size; + } else if (!s1->streams[0]->parser) { + size[0] = avio_size(s1->pb); } else { size[0] = 4096; } @@ -522,3 +551,110 @@ AVInputFormat ff_image2pipe_demuxer = { .priv_class = &img2pipe_class, }; #endif + +static int bmp_probe(AVProbeData *p) +{ + const uint8_t *b = p->buf; + + if (AV_RB16(b) == 0x424d) + if (!AV_RN32(b + 6)) { + return AVPROBE_SCORE_EXTENSION + 1; + } else { + return AVPROBE_SCORE_EXTENSION / 4; + } + return 0; +} + +static int dpx_probe(AVProbeData *p) +{ + const uint8_t *b = p->buf; + + if (AV_RN32(b) == AV_RN32("SDPX") || AV_RN32(b) == AV_RN32("XPDS")) + return AVPROBE_SCORE_EXTENSION + 1; + return 0; +} + +static int exr_probe(AVProbeData *p) +{ + const uint8_t *b = p->buf; + + if (AV_RL32(b) == 20000630) + return AVPROBE_SCORE_EXTENSION + 1; + return 0; +} + +static int pictor_probe(AVProbeData *p) +{ + const uint8_t *b = p->buf; + + if (AV_RL16(b) == 0x1234) + return AVPROBE_SCORE_EXTENSION / 4; + return 0; +} + +static int png_probe(AVProbeData *p) +{ + const uint8_t *b = p->buf; + + if (AV_RB64(b) == 0x89504e470d0a1a0a) + return AVPROBE_SCORE_MAX - 1; + return 0; +} + +static int sgi_probe(AVProbeData *p) +{ + const uint8_t *b = p->buf; + + if (AV_RB16(b) == 474 && + (b[2] & ~1) == 0 && + (b[3] & ~3) == 0 && b[3] && + (AV_RB16(b + 4) & ~7) == 0 && AV_RB16(b + 4)) + return AVPROBE_SCORE_EXTENSION + 1; + return 0; +} + +static int sunrast_probe(AVProbeData *p) +{ + const uint8_t *b = p->buf; + + if (AV_RB32(b) == 0x59a66a95) + return AVPROBE_SCORE_EXTENSION + 1; + return 0; +} + +static int tiff_probe(AVProbeData *p) +{ + const uint8_t *b = p->buf; + + if (AV_RB32(b) == 0x49492a00) + return AVPROBE_SCORE_EXTENSION + 1; + return 0; +} + +#define IMAGEAUTO_DEMUXER(imgname, codecid)\ +static const AVClass imgname ## _class = {\ + .class_name = AV_STRINGIFY(imgname) " demuxer",\ + .item_name = av_default_item_name,\ + .option = options,\ + .version = LIBAVUTIL_VERSION_INT,\ +};\ +AVInputFormat ff_image_ ## imgname ## _pipe_demuxer = {\ + .name = AV_STRINGIFY(imgname) "_pipe",\ + .priv_data_size = sizeof(VideoDemuxData),\ + .read_probe = imgname ## _probe,\ + .read_header = ff_img_read_header,\ + .read_packet = ff_img_read_packet,\ + .read_close = img_read_close,\ + .read_seek = img_read_seek,\ + .priv_class = & imgname ## _class,\ + .raw_codec_id = codecid,\ +}; + +IMAGEAUTO_DEMUXER(bmp, AV_CODEC_ID_BMP) +IMAGEAUTO_DEMUXER(dpx, AV_CODEC_ID_DPX) +IMAGEAUTO_DEMUXER(exr, AV_CODEC_ID_EXR) +IMAGEAUTO_DEMUXER(pictor, AV_CODEC_ID_PICTOR) +IMAGEAUTO_DEMUXER(png, AV_CODEC_ID_PNG) +IMAGEAUTO_DEMUXER(sgi, AV_CODEC_ID_SGI) +IMAGEAUTO_DEMUXER(sunrast, AV_CODEC_ID_SUNRAST) +IMAGEAUTO_DEMUXER(tiff, AV_CODEC_ID_TIFF) -- cgit v1.2.3