FFmpeg
Loading...
Searching...
No Matches
gifdec.c
Go to the documentation of this file.
1/*
2 * GIF demuxer
3 * Copyright (c) 2012 Vitaliy E Sugrobov
4 *
5 * This file is part of FFmpeg.
6 *
7 * FFmpeg is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * FFmpeg is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with FFmpeg; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22/**
23 * @file
24 * GIF demuxer.
25 */
26
27#include "avformat.h"
28#include "demux.h"
29#include "libavutil/bprint.h"
31#include "libavutil/opt.h"
32#include "avio_internal.h"
33#include "internal.h"
34#include "libavcodec/gif.h"
35
36#define GIF_PACKET_SIZE 1024
37
38typedef struct GIFDemuxContext {
39 const AVClass *class;
40 /**
41 * Time span in hundredths of second before
42 * the next frame should be drawn on screen.
43 */
44 int delay;
45 /**
46 * Minimum allowed delay between frames in hundredths of
47 * second. Values below this threshold considered to be
48 * invalid and set to value of default_delay.
49 */
53
54 /**
55 * loop options
56 */
61
62/**
63 * Major web browsers display gifs at ~10-15fps when rate
64 * is not explicitly set or have too low values. We assume default rate to be 10.
65 * Default delay = 100hundredths of second / 10fps = 10hos per frame.
66 */
67#define GIF_DEFAULT_DELAY 10
68/**
69 * By default delay values less than this threshold considered to be invalid.
70 */
71#define GIF_MIN_DELAY 2
72
73static int gif_probe(const AVProbeData *p)
74{
75 /* check magick */
76 if (memcmp(p->buf, gif87a_sig, 6) && memcmp(p->buf, gif89a_sig, 6))
77 return 0;
78
79 /* width or height contains zero? */
80 if (!AV_RL16(&p->buf[6]) || !AV_RL16(&p->buf[8]))
81 return 0;
82
83 return AVPROBE_SCORE_MAX;
84}
85
86static int resync(AVIOContext *pb)
87{
88 int ret = ffio_ensure_seekback(pb, 13);
89 if (ret < 0)
90 return ret;
91
92 for (int i = 0; i < 6; i++) {
93 int b = avio_r8(pb);
94 if (b != gif87a_sig[i] && b != gif89a_sig[i])
95 i = -(b != 'G');
96 if (avio_feof(pb))
97 return AVERROR_EOF;
98 }
99 return 0;
100}
101
103{
104 int sb_size, ret = 0;
105
106 while (0x00 != (sb_size = avio_r8(pb))) {
107 if ((ret = avio_skip(pb, sb_size)) < 0)
108 return ret;
109 }
110
111 return ret;
112}
113
115{
116 GIFDemuxContext *gdc = s->priv_data;
117 AVIOContext *pb = s->pb;
118 AVStream *st;
119 int type, width, height, ret, n, flags;
120 int64_t nb_frames = 0, duration = 0, pos;
121 int64_t ret64;
122
123 if ((ret = resync(pb)) < 0)
124 return ret;
125
126 pos = avio_tell(pb);
127 gdc->delay = gdc->default_delay;
128 width = avio_rl16(pb);
129 height = avio_rl16(pb);
130 flags = avio_r8(pb);
131 avio_skip(pb, 1);
132 n = avio_r8(pb);
133
134 if (width == 0 || height == 0)
135 return AVERROR_INVALIDDATA;
136
138 if (!st)
139 return AVERROR(ENOMEM);
140
141 if (!(pb->seekable & AVIO_SEEKABLE_NORMAL))
142 goto skip;
143
144 if (flags & 0x80)
145 avio_skip(pb, 3 * (1 << ((flags & 0x07) + 1)));
146
147 while ((type = avio_r8(pb)) != GIF_TRAILER) {
148 if (avio_feof(pb))
149 break;
151 int subtype = avio_r8(pb);
152 if (subtype == GIF_COM_EXT_LABEL) {
153 AVBPrint bp;
154 int block_size;
155
157 while ((block_size = avio_r8(pb)) != 0) {
158 avio_read_to_bprint(pb, &bp, block_size);
159 }
160 av_dict_set(&s->metadata, "comment", bp.str, 0);
162 } else if (subtype == GIF_GCE_EXT_LABEL) {
163 int block_size = avio_r8(pb);
164
165 if (block_size == 4) {
166 int delay;
167
168 avio_skip(pb, 1);
169 delay = avio_rl16(pb);
170 delay = delay ? delay : gdc->default_delay;
171 duration += delay;
172 avio_skip(pb, 1);
173 } else {
174 avio_skip(pb, block_size);
175 }
177 } else if (subtype == GIF_APP_EXT_LABEL) {
178 uint8_t data[256];
179 int sb_size;
180
181 sb_size = avio_r8(pb);
182 ret = avio_read(pb, data, sb_size);
183 if (ret < 0 || !sb_size)
184 break;
185
186 if (sb_size == strlen(NETSCAPE_EXT_STR)) {
187 sb_size = avio_r8(pb);
188 ret = avio_read(pb, data, sb_size);
189 if (ret < 0 || !sb_size)
190 break;
191
192 if (sb_size == 3 && data[0] == 1) {
193 gdc->total_iter = AV_RL16(data+1);
194 av_log(s, AV_LOG_DEBUG, "Loop count is %d\n", gdc->total_iter);
195
196 if (gdc->total_iter == 0)
197 gdc->total_iter = -1;
198 }
199 }
201 } else {
203 }
204 } else if (type == GIF_IMAGE_SEPARATOR) {
205 avio_skip(pb, 8);
206 flags = avio_r8(pb);
207 if (flags & 0x80)
208 avio_skip(pb, 3 * (1 << ((flags & 0x07) + 1)));
209 avio_skip(pb, 1);
211 nb_frames++;
212 } else {
213 break;
214 }
215 }
216
217skip:
218 /* jump to start because gif decoder needs header data too */
219 ret64 = avio_seek(pb, pos - 6, SEEK_SET);
220 if (ret64 < 0)
221 return (int)ret64;
222
223 /* GIF format operates with time in "hundredths of second",
224 * therefore timebase is 1/100 */
225 avpriv_set_pts_info(st, 64, 1, 100);
229 st->codecpar->width = width;
230 st->codecpar->height = height;
231 if (nb_frames > 1) {
233 100, duration / nb_frames, INT_MAX);
234 } else if (duration) {
235 st->avg_frame_rate = (AVRational) { 100, duration };
236 }
237 st->start_time = 0;
238 st->duration = duration;
239 st->nb_frames = nb_frames;
240 if (n)
241 st->codecpar->sample_aspect_ratio = av_make_q(n + 15, 64);
242
243 return 0;
244}
245
247{
248 GIFDemuxContext *gdc = s->priv_data;
249 AVIOContext *pb = s->pb;
250 int ret;
251
252 if ((pb->seekable & AVIO_SEEKABLE_NORMAL) &&
253 !gdc->ignore_loop && avio_feof(pb) &&
254 (gdc->total_iter < 0 || (++gdc->iter_count < gdc->total_iter))) {
255 avio_seek(pb, 0, SEEK_SET);
256 }
257 if ((ret = av_new_packet(pkt, GIF_PACKET_SIZE)) < 0)
258 return ret;
259
260 pkt->pos = avio_tell(pb);
261 pkt->stream_index = 0;
262 ret = avio_read_partial(pb, pkt->data, GIF_PACKET_SIZE);
263 if (ret < 0) {
265 return ret;
266 }
267 av_shrink_packet(pkt, ret);
268 return ret;
269}
270
271static const AVOption options[] = {
272 { "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 },
273 { "max_gif_delay", "maximum valid delay between frames (in hundredths of seconds)", offsetof(GIFDemuxContext, max_delay) , AV_OPT_TYPE_INT, {.i64 = 65535} , 0, 65535 , AV_OPT_FLAG_DECODING_PARAM },
274 { "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 },
275 { "ignore_loop" , "ignore loop setting (netscape extension)" , offsetof(GIFDemuxContext, ignore_loop) , AV_OPT_TYPE_BOOL,{.i64 = 1} , 0, 1, AV_OPT_FLAG_DECODING_PARAM },
276 { NULL },
277};
278
279static const AVClass demuxer_class = {
280 .class_name = "GIF demuxer",
281 .item_name = av_default_item_name,
282 .option = options,
283 .version = LIBAVUTIL_VERSION_INT,
284 .category = AV_CLASS_CATEGORY_DEMUXER,
285};
286
288 .p.name = "gif",
289 .p.long_name = NULL_IF_CONFIG_SMALL("CompuServe Graphics Interchange Format (GIF)"),
290 .p.flags = AVFMT_GENERIC_INDEX,
291 .p.extensions = "gif",
292 .p.priv_class = &demuxer_class,
293 .priv_data_size = sizeof(GIFDemuxContext),
297};
const FFInputFormat ff_gif_demuxer
Definition gifdec.c:287
static const AVClass demuxer_class
Definition apngdec.c:418
void avpriv_set_pts_info(AVStream *st, int pts_wrap_bits, unsigned int pts_num, unsigned int pts_den)
Set the time base and wrapping info for a given stream.
Definition avformat.c:834
Main libavformat public API header.
#define AVPROBE_SCORE_MAX
maximum score
Definition avformat.h:483
#define AVFMT_GENERIC_INDEX
Use generic index building code.
Definition avformat.h:499
@ AVSTREAM_PARSE_FULL_RAW
full parsing and repack with timestamp and position generation by parser for raw this assumes that ea...
Definition avformat.h:615
int64_t avio_seek(AVIOContext *s, int64_t offset, int whence)
fseek() equivalent for AVIOContext.
Definition aviobuf.c:236
#define AVIO_SEEKABLE_NORMAL
Seeking works like for a local file.
Definition avio.h:41
int avio_feof(AVIOContext *s)
Similar to feof() but also returns nonzero on read errors.
Definition aviobuf.c:349
int avio_read_partial(AVIOContext *s, unsigned char *buf, int size)
Read size bytes from AVIOContext into buf.
Definition aviobuf.c:687
static av_always_inline int64_t avio_tell(AVIOContext *s)
ftell() equivalent for AVIOContext.
Definition avio.h:494
unsigned int avio_rl16(AVIOContext *s)
Definition aviobuf.c:717
int64_t avio_skip(AVIOContext *s, int64_t offset)
Skip given number of bytes forward.
Definition aviobuf.c:321
int avio_read(AVIOContext *s, unsigned char *buf, int size)
Read size bytes from AVIOContext into buf.
Definition aviobuf.c:615
int avio_read_to_bprint(AVIOContext *h, struct AVBPrint *pb, size_t max_size)
Read contents of h into print buffer, up to max_size bytes, or up to EOF.
Definition aviobuf.c:1254
int avio_r8(AVIOContext *s)
Definition aviobuf.c:606
int ffio_ensure_seekback(AVIOContext *s, int64_t buf_size)
Ensures that the requested seekback buffer size will be available.
Definition aviobuf.c:1026
static int read_packet(void *opaque, uint8_t *buf, int buf_size)
static void BS_FUNC skip(BSCTX *bc, unsigned int n)
Skip n bits in the buffer.
void av_bprint_init(AVBPrint *buf, unsigned size_init, unsigned size_max)
Definition bprint.c:69
AVBPrint public header.
#define AV_BPRINT_SIZE_UNLIMITED
#define flags(name, subs,...)
Definition cbs_h264.c:74
#define i(width, name, range_min, range_max)
Definition cbs_h264.c:63
#define s(width, name)
Definition cbs_vp9.c:198
static int read_probe(const AVProbeData *p)
Definition cdg.c:30
#define NULL
Definition coverity.c:32
long long int64_t
Definition coverity.c:34
static AVPacket * pkt
static int64_t duration
Definition ffplay.c:330
static int read_header(FFV1Context *f, RangeCoder *c)
Definition ffv1dec.c:578
GIF format definitions.
#define GIF_IMAGE_SEPARATOR
Definition gif.h:46
#define GIF_APP_EXT_LABEL
Definition gif.h:49
static attribute_nonstring const uint8_t gif89a_sig[6]
Definition gif.h:37
#define GIF_TRAILER
Definition gif.h:44
#define GIF_EXTENSION_INTRODUCER
Definition gif.h:45
#define GIF_GCE_EXT_LABEL
Definition gif.h:47
#define NETSCAPE_EXT_STR
Definition gif.h:50
#define GIF_COM_EXT_LABEL
Definition gif.h:48
static attribute_nonstring const uint8_t gif87a_sig[6]
Definition gif.h:36
#define AV_OPT_FLAG_DECODING_PARAM
A generic parameter which can be set by the user for demuxing or decoding.
Definition opt.h:355
@ AV_OPT_TYPE_INT
Underlying C type is int.
Definition opt.h:258
@ AV_OPT_TYPE_BOOL
Underlying C type is int.
Definition opt.h:326
@ AV_CODEC_ID_GIF
Definition codec_id.h:147
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
Definition packet.c:434
void av_shrink_packet(AVPacket *pkt, int size)
Reduce packet size, correctly zeroing padding.
Definition packet.c:113
int av_new_packet(AVPacket *pkt, int size)
Allocate the payload of a packet and initialize its fields with default values.
Definition packet.c:98
AVStream * avformat_new_stream(AVFormatContext *s, const struct AVCodec *c)
Add a new stream to a media file.
int av_bprint_finalize(AVBPrint *buf, char **ret_str)
Finalize a print buffer.
Definition bprint.c:235
int av_dict_set(AVDictionary **pm, const char *key, const char *value, int flags)
Set the given entry in *pm, overwriting an existing entry.
Definition dict.c:86
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition error.h:61
#define AVERROR_EOF
End of file.
Definition error.h:57
#define AVERROR(e)
Definition error.h:45
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition log.h:231
const char * av_default_item_name(void *ptr)
Return the context name.
Definition log.c:241
int av_reduce(int *dst_num, int *dst_den, int64_t num, int64_t den, int64_t max)
Reduce a fraction.
Definition rational.c:35
static AVRational av_make_q(int num, int den)
Create an AVRational.
Definition rational.h:71
@ AVMEDIA_TYPE_VIDEO
Definition avutil.h:200
#define LIBAVUTIL_VERSION_INT
Definition version.h:85
cl_device_type type
#define b
Definition input.c:43
#define AV_RL16(p)
static int gif_read_header(AVFormatContext *s)
Definition gifdec.c:114
static int gif_read_packet(AVFormatContext *s, AVPacket *pkt)
Definition gifdec.c:246
static int resync(AVIOContext *pb)
Definition gifdec.c:86
#define GIF_PACKET_SIZE
Definition gifdec.c:36
static int gif_skip_subblocks(AVIOContext *pb)
Definition gifdec.c:102
static int gif_probe(const AVProbeData *p)
Definition gifdec.c:73
#define GIF_DEFAULT_DELAY
Major web browsers display gifs at ~10-15fps when rate is not explicitly set or have too low values.
Definition gifdec.c:67
#define GIF_MIN_DELAY
By default delay values less than this threshold considered to be invalid.
Definition gifdec.c:71
static av_always_inline FFStream * ffstream(AVStream *st)
Definition internal.h:365
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition internal.h:88
@ AV_CLASS_CATEGORY_DEMUXER
Definition log.h:33
const char data[16]
Definition mxf.c:149
AVOptions.
unsigned int pos
Definition spdifenc.c:431
Describe the class of an AVClass context structure.
Definition log.h:76
int height
The height of the video frame in pixels.
Definition codec_par.h:150
int width
The width of the video frame in pixels.
Definition codec_par.h:143
enum AVMediaType codec_type
General type of the encoded data.
Definition codec_par.h:53
AVRational sample_aspect_ratio
The aspect ratio (width/height) which a single pixel should have when displayed.
Definition codec_par.h:161
enum AVCodecID codec_id
Specific type of the encoded data (the codec used).
Definition codec_par.h:57
Format I/O context.
Definition avformat.h:1333
Bytestream IO Context.
Definition avio.h:160
int seekable
A combination of AVIO_SEEKABLE_ flags or 0 when the stream is not seekable.
Definition avio.h:261
AVOption.
Definition opt.h:428
This structure stores compressed data.
Definition packet.h:580
This structure contains the data a format has to probe a file.
Definition avformat.h:471
Rational number (pair of numerator and denominator).
Definition rational.h:58
int num
Numerator.
Definition rational.h:59
int den
Denominator.
Definition rational.h:60
Stream structure.
Definition avformat.h:766
AVCodecParameters * codecpar
Codec parameters associated with this stream.
Definition avformat.h:789
int64_t nb_frames
number of frames in this stream if known or 0
Definition avformat.h:827
int64_t duration
Decoding: duration of the stream, in stream time base.
Definition avformat.h:825
int64_t start_time
Decoding: pts of the first frame of the stream in presentation order, in stream time base.
Definition avformat.h:815
AVRational avg_frame_rate
Average framerate.
Definition avformat.h:855
enum AVStreamParseType need_parsing
Definition internal.h:321
int min_delay
Minimum allowed delay between frames in hundredths of second.
Definition gifdec.c:50
int ignore_loop
Definition gifdec.c:59
int total_iter
loop options
Definition gifdec.c:57
int delay
Time span in hundredths of second before the next frame should be drawn on screen.
Definition gifdec.c:44
int default_delay
Definition gifdec.c:52
#define av_log(a,...)
#define height
Definition dsp.h:89
#define width
Definition dsp.h:89