diff options
| author | Tim Redfern <tim@eclectronics.org> | 2013-12-29 12:19:38 +0000 |
|---|---|---|
| committer | Tim Redfern <tim@eclectronics.org> | 2013-12-29 12:19:38 +0000 |
| commit | f7813a5324be39d13ab536c245d15dfc602a7849 (patch) | |
| tree | fad99148b88823d34a5df2f0a25881a002eb291b /ffmpeg/libavformat/gifdec.c | |
| parent | b7a5a477b8ff4d4e3028b9dfb9a9df0a41463f92 (diff) | |
basic type mechanism working
Diffstat (limited to 'ffmpeg/libavformat/gifdec.c')
| -rw-r--r-- | ffmpeg/libavformat/gifdec.c | 34 |
1 files changed, 33 insertions, 1 deletions
diff --git a/ffmpeg/libavformat/gifdec.c b/ffmpeg/libavformat/gifdec.c index 1122849..2981bca 100644 --- a/ffmpeg/libavformat/gifdec.c +++ b/ffmpeg/libavformat/gifdec.c @@ -44,6 +44,13 @@ typedef struct GIFDemuxContext { */ int min_delay; int default_delay; + + /** + * loop options + */ + int total_iter; + int iter_count; + int ignore_loop; } GIFDemuxContext; /** @@ -156,6 +163,27 @@ static int gif_read_ext(AVFormatContext *s) /* skip the rest of the Graphic Control Extension block */ if ((ret = avio_skip(pb, sb_size - 3)) < 0 ) return ret; + } else if (ext_label == GIF_APP_EXT_LABEL) { + uint8_t data[256]; + + sb_size = avio_r8(pb); + ret = avio_read(pb, data, sb_size); + if (ret < 0 || !sb_size) + return ret; + + if (sb_size == strlen(NETSCAPE_EXT_STR)) { + sb_size = avio_r8(pb); + ret = avio_read(pb, data, sb_size); + if (ret < 0 || !sb_size) + return ret; + + if (sb_size == 3 && data[0] == 1) { + gdc->total_iter = AV_RL16(data+1); + + if (gdc->total_iter == 0) + gdc->total_iter = -1; + } + } } if ((ret = gif_skip_subblocks(pb)) < 0) @@ -268,9 +296,12 @@ resync: } } - if (ret >= 0 && !frame_parsed) { + if ((ret >= 0 && !frame_parsed) || ret == AVERROR_EOF) { /* This might happen when there is no image block * between extension blocks and GIF_TRAILER or EOF */ + if (!gdc->ignore_loop && (block_label == GIF_TRAILER || url_feof(pb)) + && (gdc->total_iter < 0 || ++gdc->iter_count < gdc->total_iter)) + return avio_seek(pb, 0, SEEK_SET); return AVERROR_EOF; } else return ret; @@ -279,6 +310,7 @@ resync: static const AVOption options[] = { { "min_delay" , "minimum valid delay between frames (in hundredths of second)", offsetof(GIFDemuxContext, min_delay) , AV_OPT_TYPE_INT, {.i64 = GIF_MIN_DELAY} , 0, 100 * 60, AV_OPT_FLAG_DECODING_PARAM }, { "default_delay", "default delay between frames (in hundredths of second)" , offsetof(GIFDemuxContext, default_delay), AV_OPT_TYPE_INT, {.i64 = GIF_DEFAULT_DELAY}, 0, 100 * 60, AV_OPT_FLAG_DECODING_PARAM }, + { "ignore_loop" , "ignore loop setting (netscape extension)" , offsetof(GIFDemuxContext, ignore_loop) , AV_OPT_TYPE_INT, {.i64 = 1} , 0, 1, AV_OPT_FLAG_DECODING_PARAM }, { NULL }, }; |
