summaryrefslogtreecommitdiff
path: root/libavformat/gifdec.c (plain)
blob: 8993ca615c054b1e1973055b5743f9bde5b2af11
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 "libavutil/intreadwrite.h"
29#include "libavutil/opt.h"
30#include "internal.h"
31#include "libavcodec/gif.h"
32
33typedef struct GIFDemuxContext {
34 const AVClass *class;
35 /**
36 * Time span in hundredths of second before
37 * the next frame should be drawn on screen.
38 */
39 int delay;
40 /**
41 * Minimum allowed delay between frames in hundredths of
42 * second. Values below this threshold considered to be
43 * invalid and set to value of default_delay.
44 */
45 int min_delay;
46 int max_delay;
47 int default_delay;
48
49 /**
50 * loop options
51 */
52 int total_iter;
53 int iter_count;
54 int ignore_loop;
55
56 int nb_frames;
57 int last_duration;
58} GIFDemuxContext;
59
60/**
61 * Major web browsers display gifs at ~10-15fps when rate
62 * is not explicitly set or have too low values. We assume default rate to be 10.
63 * Default delay = 100hundredths of second / 10fps = 10hos per frame.
64 */
65#define GIF_DEFAULT_DELAY 10
66/**
67 * By default delay values less than this threshold considered to be invalid.
68 */
69#define GIF_MIN_DELAY 2
70
71static int gif_probe(AVProbeData *p)
72{
73 /* check magick */
74 if (memcmp(p->buf, gif87a_sig, 6) && memcmp(p->buf, gif89a_sig, 6))
75 return 0;
76
77 /* width or height contains zero? */
78 if (!AV_RL16(&p->buf[6]) || !AV_RL16(&p->buf[8]))
79 return 0;
80
81 return AVPROBE_SCORE_MAX;
82}
83
84static int resync(AVIOContext *pb)
85{
86 int i;
87 for (i = 0; i < 6; i++) {
88 int b = avio_r8(pb);
89 if (b != gif87a_sig[i] && b != gif89a_sig[i])
90 i = -(b != 'G');
91 if (avio_feof(pb))
92 return AVERROR_EOF;
93 }
94 return 0;
95}
96
97static int gif_read_header(AVFormatContext *s)
98{
99 GIFDemuxContext *gdc = s->priv_data;
100 AVIOContext *pb = s->pb;
101 AVStream *st;
102 int width, height, ret;
103
104 if ((ret = resync(pb)) < 0)
105 return ret;
106
107 gdc->delay = gdc->default_delay;
108 width = avio_rl16(pb);
109 height = avio_rl16(pb);
110
111 if (width == 0 || height == 0)
112 return AVERROR_INVALIDDATA;
113
114 st = avformat_new_stream(s, NULL);
115 if (!st)
116 return AVERROR(ENOMEM);
117
118 /* GIF format operates with time in "hundredths of second",
119 * therefore timebase is 1/100 */
120 avpriv_set_pts_info(st, 64, 1, 100);
121 st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
122 st->codecpar->codec_id = AV_CODEC_ID_GIF;
123 st->codecpar->width = width;
124 st->codecpar->height = height;
125
126 /* jump to start because gif decoder needs header data too */
127 if (avio_seek(pb, 0, SEEK_SET) != 0)
128 return AVERROR(EIO);
129
130 return 0;
131}
132
133static int gif_skip_subblocks(AVIOContext *pb)
134{
135 int sb_size, ret = 0;
136
137 while (0x00 != (sb_size = avio_r8(pb))) {
138 if ((ret = avio_skip(pb, sb_size)) < 0)
139 return ret;
140 }
141
142 return ret;
143}
144
145static int gif_read_ext(AVFormatContext *s)
146{
147 GIFDemuxContext *gdc = s->priv_data;
148 AVIOContext *pb = s->pb;
149 int sb_size, ext_label = avio_r8(pb);
150 int ret;
151
152 if (ext_label == GIF_GCE_EXT_LABEL) {
153 if ((sb_size = avio_r8(pb)) < 4) {
154 av_log(s, AV_LOG_FATAL, "Graphic Control Extension block's size less than 4.\n");
155 return AVERROR_INVALIDDATA;
156 }
157
158 /* skip packed fields */
159 if ((ret = avio_skip(pb, 1)) < 0)
160 return ret;
161
162 gdc->delay = avio_rl16(pb);
163
164 if (gdc->delay < gdc->min_delay)
165 gdc->delay = gdc->default_delay;
166 gdc->delay = FFMIN(gdc->delay, gdc->max_delay);
167
168 /* skip the rest of the Graphic Control Extension block */
169 if ((ret = avio_skip(pb, sb_size - 3)) < 0 )
170 return ret;
171 } else if (ext_label == GIF_APP_EXT_LABEL) {
172 uint8_t data[256];
173
174 sb_size = avio_r8(pb);
175 ret = avio_read(pb, data, sb_size);
176 if (ret < 0 || !sb_size)
177 return ret;
178
179 if (sb_size == strlen(NETSCAPE_EXT_STR)) {
180 sb_size = avio_r8(pb);
181 ret = avio_read(pb, data, sb_size);
182 if (ret < 0 || !sb_size)
183 return ret;
184
185 if (sb_size == 3 && data[0] == 1) {
186 gdc->total_iter = AV_RL16(data+1);
187
188 if (gdc->total_iter == 0)
189 gdc->total_iter = -1;
190 }
191 }
192 }
193
194 if ((ret = gif_skip_subblocks(pb)) < 0)
195 return ret;
196
197 return 0;
198}
199
200static int gif_read_packet(AVFormatContext *s, AVPacket *pkt)
201{
202 GIFDemuxContext *gdc = s->priv_data;
203 AVIOContext *pb = s->pb;
204 int packed_fields, block_label, ct_size,
205 keyframe, frame_parsed = 0, ret;
206 int64_t frame_start = avio_tell(pb), frame_end;
207 unsigned char buf[6];
208
209 if ((ret = avio_read(pb, buf, 6)) == 6) {
210 keyframe = memcmp(buf, gif87a_sig, 6) == 0 ||
211 memcmp(buf, gif89a_sig, 6) == 0;
212 } else if (ret < 0) {
213 return ret;
214 } else {
215 keyframe = 0;
216 }
217
218 if (keyframe) {
219parse_keyframe:
220 /* skip 2 bytes of width and 2 of height */
221 if ((ret = avio_skip(pb, 4)) < 0)
222 return ret;
223
224 packed_fields = avio_r8(pb);
225
226 /* skip 1 byte of Background Color Index and 1 byte of Pixel Aspect Ratio */
227 if ((ret = avio_skip(pb, 2)) < 0)
228 return ret;
229
230 /* global color table presence */
231 if (packed_fields & 0x80) {
232 ct_size = 3 * (1 << ((packed_fields & 0x07) + 1));
233
234 if ((ret = avio_skip(pb, ct_size)) < 0)
235 return ret;
236 }
237 } else {
238 avio_seek(pb, -ret, SEEK_CUR);
239 ret = AVERROR_EOF;
240 }
241
242 while (GIF_TRAILER != (block_label = avio_r8(pb)) && !avio_feof(pb)) {
243 if (block_label == GIF_EXTENSION_INTRODUCER) {
244 if ((ret = gif_read_ext (s)) < 0 )
245 goto resync;
246 } else if (block_label == GIF_IMAGE_SEPARATOR) {
247 /* skip to last byte of Image Descriptor header */
248 if ((ret = avio_skip(pb, 8)) < 0)
249 return ret;
250
251 packed_fields = avio_r8(pb);
252
253 /* local color table presence */
254 if (packed_fields & 0x80) {
255 ct_size = 3 * (1 << ((packed_fields & 0x07) + 1));
256
257 if ((ret = avio_skip(pb, ct_size)) < 0)
258 return ret;
259 }
260
261 /* read LZW Minimum Code Size */
262 if (avio_r8(pb) < 1) {
263 av_log(s, AV_LOG_ERROR, "lzw minimum code size must be >= 1\n");
264 goto resync;
265 }
266
267 if ((ret = gif_skip_subblocks(pb)) < 0)
268 goto resync;
269
270 frame_end = avio_tell(pb);
271
272 if (avio_seek(pb, frame_start, SEEK_SET) != frame_start)
273 return AVERROR(EIO);
274
275 ret = av_get_packet(pb, pkt, frame_end - frame_start);
276 if (ret < 0)
277 return ret;
278
279 if (keyframe)
280 pkt->flags |= AV_PKT_FLAG_KEY;
281
282 pkt->stream_index = 0;
283 pkt->duration = gdc->delay;
284
285 gdc->nb_frames ++;
286 gdc->last_duration = pkt->duration;
287
288 /* Graphic Control Extension's scope is single frame.
289 * Remove its influence. */
290 gdc->delay = gdc->default_delay;
291 frame_parsed = 1;
292
293 break;
294 } else {
295 av_log(s, AV_LOG_ERROR, "invalid block label\n");
296resync:
297 if (!keyframe)
298 avio_seek(pb, frame_start, SEEK_SET);
299 if ((ret = resync(pb)) < 0)
300 return ret;
301 frame_start = avio_tell(pb) - 6;
302 keyframe = 1;
303 goto parse_keyframe;
304 }
305 }
306
307 if ((ret >= 0 && !frame_parsed) || ret == AVERROR_EOF) {
308 if (gdc->nb_frames == 1) {
309 s->streams[0]->r_frame_rate = (AVRational) {100, gdc->last_duration};
310 }
311 /* This might happen when there is no image block
312 * between extension blocks and GIF_TRAILER or EOF */
313 if (!gdc->ignore_loop && (block_label == GIF_TRAILER || avio_feof(pb))
314 && (gdc->total_iter < 0 || ++gdc->iter_count < gdc->total_iter))
315 return avio_seek(pb, 0, SEEK_SET);
316 return AVERROR_EOF;
317 } else
318 return ret;
319}
320
321static const AVOption options[] = {
322 { "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 },
323 { "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 },
324 { "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 },
325 { "ignore_loop" , "ignore loop setting (netscape extension)" , offsetof(GIFDemuxContext, ignore_loop) , AV_OPT_TYPE_BOOL,{.i64 = 1} , 0, 1, AV_OPT_FLAG_DECODING_PARAM },
326 { NULL },
327};
328
329static const AVClass demuxer_class = {
330 .class_name = "GIF demuxer",
331 .item_name = av_default_item_name,
332 .option = options,
333 .version = LIBAVUTIL_VERSION_INT,
334 .category = AV_CLASS_CATEGORY_DEMUXER,
335};
336
337AVInputFormat ff_gif_demuxer = {
338 .name = "gif",
339 .long_name = NULL_IF_CONFIG_SMALL("CompuServe Graphics Interchange Format (GIF)"),
340 .priv_data_size = sizeof(GIFDemuxContext),
341 .read_probe = gif_probe,
342 .read_header = gif_read_header,
343 .read_packet = gif_read_packet,
344 .flags = AVFMT_GENERIC_INDEX,
345 .priv_class = &demuxer_class,
346};
347