[FFmpeg-cvslog] gifdec: resync support

Michael Niedermayer git at videolan.org
Fri Jan 25 17:30:44 CET 2013


ffmpeg | branch: master | Michael Niedermayer <michaelni at gmx.at> | Mon Jan 21 18:52:01 2013 +0100| [13aca070ab83afbd9026b298ead38f9ea88f6a92] | committer: Michael Niedermayer

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>

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=13aca070ab83afbd9026b298ead38f9ea88f6a92
---

 libavformat/gifdec.c |   32 ++++++++++++++++++++++++++------
 1 file changed, 26 insertions(+), 6 deletions(-)

diff --git a/libavformat/gifdec.c b/libavformat/gifdec.c
index 4f4ce2c..d43a537 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;
         }
     }
 



More information about the ffmpeg-cvslog mailing list