[FFmpeg-devel] [PATCH] gifdec: resync support

Don Moir donmoir at comcast.net
Mon Jan 21 22:47:37 CET 2013


----- Original Message ----- 
From: "Michael Niedermayer" <michaelni at gmx.at>
To: "FFmpeg development discussions and patches" <ffmpeg-devel at ffmpeg.org>
Sent: Monday, January 21, 2013 12:56 PM
Subject: [FFmpeg-devel] [PATCH] gifdec: resync support


> This allows decoding gifs that have junk at the begin
> and also allows byte wise seeking
> 
> Signed-off-by: Michael Niedermayer <michaelni at gmx.at>
> ---
> libavformat/gifdec.c |   32 ++++++++++++++++++++++++++------
> 1 file changed, 26 insertions(+), 6 deletions(-)
> 
> diff --git a/libavformat/gifdec.c b/libavformat/gifdec.c
> index 4f4ce2c..357d698 100644
> --- a/libavformat/gifdec.c
> +++ b/libavformat/gifdec.c
> @@ -70,6 +70,19 @@ static int gif_probe(AVProbeData *p)
>     return AVPROBE_SCORE_MAX;
> }
> 
> +static int resync(AVIOContext *pb)
> +{
> +    int i;
> +    for (i=0; i<6; i++) {
> +        int b = avio_r8(pb);
> +        if(b != gif87a_sig[i] && b != gif89a_sig[i])
> +            i = -(b != 'G');
> +        if(url_feof(pb))
> +            return AVERROR_EOF;
> +    }
> +    return 0;
> +}
> +
> static int gif_read_header(AVFormatContext *s)
> {
>     GIFDemuxContext *gdc = s->priv_data;
> @@ -77,8 +90,7 @@ static int gif_read_header(AVFormatContext *s)
>     AVStream        *st;
>     int width, height, ret;
> 
> -    /* skip 6-byte magick */
> -    if ((ret = avio_skip(pb, 6)) < 0)
> +    if ((ret = resync(pb)) < 0)
>         return ret;
> 
>     gdc->delay  = gdc->default_delay;
> @@ -171,6 +183,7 @@ static int gif_read_packet(AVFormatContext *s, AVPacket *pkt)
>     }
> 
>     if (keyframe) {
> +parse_keyframe:
>         /* skip 2 bytes of width and 2 of height */
>         if ((ret = avio_skip(pb, 4)) < 0)
>             return ret;
> @@ -196,7 +209,7 @@ static int gif_read_packet(AVFormatContext *s, AVPacket *pkt)
>     while (GIF_TRAILER != (block_label = avio_r8(pb)) && !url_feof(pb)) {
>         if (block_label == GIF_EXTENSION_INTRODUCER) {
>             if ((ret = gif_read_ext (s)) < 0 )
> -                return ret;
> +                goto resync;
>         } else if (block_label == GIF_IMAGE_SEPARATOR) {
>             /* skip to last byte of Image Descriptor header */
>             if ((ret = avio_skip(pb, 8)) < 0)
> @@ -215,11 +228,11 @@ static int gif_read_packet(AVFormatContext *s, AVPacket *pkt)
>             /* read LZW Minimum Code Size */
>             if (avio_r8(pb) < 1) {
>                 av_log(s, AV_LOG_ERROR, "lzw minimum code size must be >= 1\n");
> -                return AVERROR_INVALIDDATA;
> +                goto resync;
>             }
> 
>             if ((ret = gif_skip_subblocks(pb)) < 0)
> -                return ret;
> +                goto resync;
> 
>             frame_end = avio_tell(pb);
> 
> @@ -244,7 +257,14 @@ static int gif_read_packet(AVFormatContext *s, AVPacket *pkt)
>             break;
>         } else {
>             av_log(s, AV_LOG_ERROR, "invalid block label\n");
> -            return AVERROR_INVALIDDATA;
> +resync:
> +            if (!keyframe)
> +                avio_seek(pb, frame_start, SEEK_SET);
> +            if((ret = resync(pb)) < 0)
> +                return ret;
> +            frame_start = avio_tell(pb) - 6;
> +            keyframe = 1;
> +            goto parse_keyframe;
>         }
>     }

There is also a av_log (s,AV_LOG_FATAL,...) in gif_read_ext in same file. Should be AV_LOG_ERROR I think.


More information about the ffmpeg-devel mailing list