summaryrefslogtreecommitdiff
path: root/libavformat/img2dec.c
diff options
context:
space:
mode:
authorCarl Eugen Hoyos <cehoyos@ag.or.at>2014-06-21 21:43:19 +0200
committerMichael Niedermayer <michaelni@gmx.at>2014-07-03 18:14:06 +0200
commitd538dd824ee7abf9f3bb6459485f3e804fcc4777 (patch)
treed4ba62f4c9914076b4b3cc211f386512f0a1c3a6 /libavformat/img2dec.c
parentdea377fcc0cbb2ffe4b1be860d2e207da28b098a (diff)
avformat: Add image3 demuxers with format autodetection
Reviewed-by: wm4 <nfxjfg@googlemail.com> Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavformat/img2dec.c')
-rw-r--r--libavformat/img2dec.c138
1 files changed, 137 insertions, 1 deletions
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)