X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavformat%2Ficodec.c;h=17acfb4b2fb483da742a8af357c2fb8d9123856b;hb=14478b6c3820339442d8c96b701d021499de0827;hp=22e209903bcad002d775e83eb5b53d183322cf4c;hpb=a240aefc7a2591f7b307e2910df655801ae6ca44;p=ffmpeg diff --git a/libavformat/icodec.c b/libavformat/icodec.c index 22e209903bc..17acfb4b2fb 100644 --- a/libavformat/icodec.c +++ b/libavformat/icodec.c @@ -27,6 +27,7 @@ #include "libavutil/intreadwrite.h" #include "libavcodec/bytestream.h" #include "libavcodec/bmp.h" +#include "libavcodec/png.h" #include "avformat.h" #include "internal.h" @@ -44,9 +45,34 @@ typedef struct { static int probe(AVProbeData *p) { - if (AV_RL16(p->buf) == 0 && AV_RL16(p->buf + 2) == 1 && AV_RL16(p->buf + 4)) - return AVPROBE_SCORE_MAX / 4; - return 0; + unsigned i, frames, checked = 0; + + if (p->buf_size < 22 || AV_RL16(p->buf) || AV_RL16(p->buf + 2) != 1) + return 0; + frames = AV_RL16(p->buf + 4); + if (!frames) + return 0; + for (i = 0; i < frames && i * 16 + 22 <= p->buf_size; i++) { + unsigned offset; + if (AV_RL16(p->buf + 10 + i * 16) & ~1) + return FFMIN(i, AVPROBE_SCORE_MAX / 4); + if (p->buf[13 + i * 16]) + return FFMIN(i, AVPROBE_SCORE_MAX / 4); + if (AV_RL32(p->buf + 14 + i * 16) < 40) + return FFMIN(i, AVPROBE_SCORE_MAX / 4); + offset = AV_RL32(p->buf + 18 + i * 16); + if (offset < 22) + return FFMIN(i, AVPROBE_SCORE_MAX / 4); + if (offset > p->buf_size - 8) + continue; + if (p->buf[offset] != 40 && AV_RB64(p->buf + offset) != PNGSIG) + return FFMIN(i, AVPROBE_SCORE_MAX / 4); + checked++; + } + + if (checked < frames) + return AVPROBE_SCORE_MAX / 4 + FFMIN(checked, 1); + return AVPROBE_SCORE_MAX / 2 + 1; } static int read_header(AVFormatContext *s)