]> rtime.felk.cvut.cz Git - frescor/ffmpeg.git/blob - libavformat/gifdec.c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
[frescor/ffmpeg.git] / libavformat / gifdec.c
1 /*
2  * GIF decoder
3  * Copyright (c) 2003 Fabrice Bellard.
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 #include "avformat.h"
22
23 int gif_write(ByteIOContext *pb, AVImageInfo *info);
24
25 //#define DEBUG
26
27 #define MAXBITS                 12
28 #define         SIZTABLE        (1<<MAXBITS)
29
30 #define GCE_DISPOSAL_NONE       0
31 #define GCE_DISPOSAL_INPLACE    1
32 #define GCE_DISPOSAL_BACKGROUND 2
33 #define GCE_DISPOSAL_RESTORE    3
34
35 typedef struct GifState {
36     int screen_width;
37     int screen_height;
38     int bits_per_pixel;
39     int background_color_index;
40     int transparent_color_index;
41     int color_resolution;
42     uint8_t *image_buf;
43     int image_linesize;
44     uint32_t *image_palette;
45     int pix_fmt;
46
47     /* after the frame is displayed, the disposal method is used */
48     int gce_disposal;
49     /* delay during which the frame is shown */
50     int gce_delay;
51
52     /* LZW compatible decoder */
53     ByteIOContext *f;
54     int eob_reached;
55     uint8_t *pbuf, *ebuf;
56     int bbits;
57     unsigned int bbuf;
58
59     int cursize;                /* The current code size */
60     int curmask;
61     int codesize;
62     int clear_code;
63     int end_code;
64     int newcodes;               /* First available code */
65     int top_slot;               /* Highest code for current size */
66     int slot;                   /* Last read code */
67     int fc, oc;
68     uint8_t *sp;
69     uint8_t stack[SIZTABLE];
70     uint8_t suffix[SIZTABLE];
71     uint16_t prefix[SIZTABLE];
72
73     /* aux buffers */
74     uint8_t global_palette[256 * 3];
75     uint8_t local_palette[256 * 3];
76     uint8_t buf[256];
77 } GifState;
78
79
80 static const uint8_t gif87a_sig[6] = "GIF87a";
81 static const uint8_t gif89a_sig[6] = "GIF89a";
82
83 static const uint16_t mask[17] =
84 {
85     0x0000, 0x0001, 0x0003, 0x0007,
86     0x000F, 0x001F, 0x003F, 0x007F,
87     0x00FF, 0x01FF, 0x03FF, 0x07FF,
88     0x0FFF, 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF
89 };
90
91 /* Probe gif video format or gif image format. The current heuristic
92    supposes the gif87a is always a single image. For gif89a, we
93    consider it as a video only if a GCE extension is present in the
94    first kilobyte. */
95 static int gif_video_probe(AVProbeData * pd)
96 {
97     const uint8_t *p, *p_end;
98     int bits_per_pixel, has_global_palette, ext_code, ext_len;
99     int gce_flags, gce_disposal;
100
101     if (pd->buf_size < 24 ||
102         memcmp(pd->buf, gif89a_sig, 6) != 0)
103         return 0;
104     p_end = pd->buf + pd->buf_size;
105     p = pd->buf + 6;
106     bits_per_pixel = (p[4] & 0x07) + 1;
107     has_global_palette = (p[4] & 0x80);
108     p += 7;
109     if (has_global_palette)
110         p += (1 << bits_per_pixel) * 3;
111     for(;;) {
112         if (p >= p_end)
113             return 0;
114         if (*p != '!')
115             break;
116         p++;
117         if (p >= p_end)
118             return 0;
119         ext_code = *p++;
120         if (p >= p_end)
121             return 0;
122         ext_len = *p++;
123         if (ext_code == 0xf9) {
124             if (p >= p_end)
125                 return 0;
126             /* if GCE extension found with gce_disposal != 0: it is
127                likely to be an animation */
128             gce_flags = *p++;
129             gce_disposal = (gce_flags >> 2) & 0x7;
130             if (gce_disposal != 0)
131                 return AVPROBE_SCORE_MAX;
132             else
133                 return 0;
134         }
135         for(;;) {
136             if (ext_len == 0)
137                 break;
138             p += ext_len;
139             if (p >= p_end)
140                 return 0;
141             ext_len = *p++;
142         }
143     }
144     return 0;
145 }
146
147 static int gif_image_probe(AVProbeData * pd)
148 {
149     if (pd->buf_size >= 24 &&
150         (memcmp(pd->buf, gif87a_sig, 6) == 0 ||
151          memcmp(pd->buf, gif89a_sig, 6) == 0))
152         return AVPROBE_SCORE_MAX - 1;
153     else
154         return 0;
155 }
156
157
158 static void GLZWDecodeInit(GifState * s, int csize)
159 {
160     /* read buffer */
161     s->eob_reached = 0;
162     s->pbuf = s->buf;
163     s->ebuf = s->buf;
164     s->bbuf = 0;
165     s->bbits = 0;
166
167     /* decoder */
168     s->codesize = csize;
169     s->cursize = s->codesize + 1;
170     s->curmask = mask[s->cursize];
171     s->top_slot = 1 << s->cursize;
172     s->clear_code = 1 << s->codesize;
173     s->end_code = s->clear_code + 1;
174     s->slot = s->newcodes = s->clear_code + 2;
175     s->oc = s->fc = 0;
176     s->sp = s->stack;
177 }
178
179 /* XXX: optimize */
180 static inline int GetCode(GifState * s)
181 {
182     int c, sizbuf;
183     uint8_t *ptr;
184
185     while (s->bbits < s->cursize) {
186         ptr = s->pbuf;
187         if (ptr >= s->ebuf) {
188             if (!s->eob_reached) {
189                 sizbuf = get_byte(s->f);
190                 s->ebuf = s->buf + sizbuf;
191                 s->pbuf = s->buf;
192                 if (sizbuf > 0) {
193                     get_buffer(s->f, s->buf, sizbuf);
194                 } else {
195                     s->eob_reached = 1;
196                 }
197             }
198             ptr = s->pbuf;
199         }
200         s->bbuf |= ptr[0] << s->bbits;
201         ptr++;
202         s->pbuf = ptr;
203         s->bbits += 8;
204     }
205     c = s->bbuf & s->curmask;
206     s->bbuf >>= s->cursize;
207     s->bbits -= s->cursize;
208     return c;
209 }
210
211 /* NOTE: the algorithm here is inspired from the LZW GIF decoder
212    written by Steven A. Bennett in 1987. */
213 /* return the number of byte decoded */
214 static int GLZWDecode(GifState * s, uint8_t * buf, int len)
215 {
216     int l, c, code, oc, fc;
217     uint8_t *sp;
218
219     if (s->end_code < 0)
220         return 0;
221
222     l = len;
223     sp = s->sp;
224     oc = s->oc;
225     fc = s->fc;
226
227     while (sp > s->stack) {
228         *buf++ = *(--sp);
229         if ((--l) == 0)
230             goto the_end;
231     }
232
233     for (;;) {
234         c = GetCode(s);
235         if (c == s->end_code) {
236             s->end_code = -1;
237             break;
238         } else if (c == s->clear_code) {
239             s->cursize = s->codesize + 1;
240             s->curmask = mask[s->cursize];
241             s->slot = s->newcodes;
242             s->top_slot = 1 << s->cursize;
243             while ((c = GetCode(s)) == s->clear_code);
244             if (c == s->end_code) {
245                 s->end_code = -1;
246                 break;
247             }
248             /* test error */
249             if (c >= s->slot)
250                 c = 0;
251             fc = oc = c;
252             *buf++ = c;
253             if ((--l) == 0)
254                 break;
255         } else {
256             code = c;
257             if (code >= s->slot) {
258                 *sp++ = fc;
259                 code = oc;
260             }
261             while (code >= s->newcodes) {
262                 *sp++ = s->suffix[code];
263                 code = s->prefix[code];
264             }
265             *sp++ = code;
266             if (s->slot < s->top_slot) {
267                 s->suffix[s->slot] = fc = code;
268                 s->prefix[s->slot++] = oc;
269                 oc = c;
270             }
271             if (s->slot >= s->top_slot) {
272                 if (s->cursize < MAXBITS) {
273                     s->top_slot <<= 1;
274                     s->curmask = mask[++s->cursize];
275                 }
276             }
277             while (sp > s->stack) {
278                 *buf++ = *(--sp);
279                 if ((--l) == 0)
280                     goto the_end;
281             }
282         }
283     }
284   the_end:
285     s->sp = sp;
286     s->oc = oc;
287     s->fc = fc;
288     return len - l;
289 }
290
291 static int gif_read_image(GifState *s)
292 {
293     ByteIOContext *f = s->f;
294     int left, top, width, height, bits_per_pixel, code_size, flags;
295     int is_interleaved, has_local_palette, y, x, pass, y1, linesize, n, i;
296     uint8_t *ptr, *line, *d, *spal, *palette, *sptr, *ptr1;
297
298     left = get_le16(f);
299     top = get_le16(f);
300     width = get_le16(f);
301     height = get_le16(f);
302     flags = get_byte(f);
303     is_interleaved = flags & 0x40;
304     has_local_palette = flags & 0x80;
305     bits_per_pixel = (flags & 0x07) + 1;
306 #ifdef DEBUG
307     printf("gif: image x=%d y=%d w=%d h=%d\n", left, top, width, height);
308 #endif
309
310     if (has_local_palette) {
311         get_buffer(f, s->local_palette, 3 * (1 << bits_per_pixel));
312         palette = s->local_palette;
313     } else {
314         palette = s->global_palette;
315         bits_per_pixel = s->bits_per_pixel;
316     }
317
318     /* verify that all the image is inside the screen dimensions */
319     if (left + width > s->screen_width ||
320         top + height > s->screen_height)
321         return -EINVAL;
322
323     /* build the palette */
324     if (s->pix_fmt == PIX_FMT_RGB24) {
325         line = av_malloc(width);
326         if (!line)
327             return -ENOMEM;
328     } else {
329         n = (1 << bits_per_pixel);
330         spal = palette;
331         for(i = 0; i < n; i++) {
332             s->image_palette[i] = (0xff << 24) |
333                 (spal[0] << 16) | (spal[1] << 8) | (spal[2]);
334             spal += 3;
335         }
336         for(; i < 256; i++)
337             s->image_palette[i] = (0xff << 24);
338         /* handle transparency */
339         if (s->transparent_color_index >= 0)
340             s->image_palette[s->transparent_color_index] = 0;
341         line = NULL;
342     }
343
344     /* now get the image data */
345     s->f = f;
346     code_size = get_byte(f);
347     GLZWDecodeInit(s, code_size);
348
349     /* read all the image */
350     linesize = s->image_linesize;
351     ptr1 = s->image_buf + top * linesize + (left * 3);
352     ptr = ptr1;
353     pass = 0;
354     y1 = 0;
355     for (y = 0; y < height; y++) {
356         if (s->pix_fmt == PIX_FMT_RGB24) {
357             /* transcode to RGB24 */
358             GLZWDecode(s, line, width);
359             d = ptr;
360             sptr = line;
361             for(x = 0; x < width; x++) {
362                 spal = palette + sptr[0] * 3;
363                 d[0] = spal[0];
364                 d[1] = spal[1];
365                 d[2] = spal[2];
366                 d += 3;
367                 sptr++;
368             }
369         } else {
370             GLZWDecode(s, ptr, width);
371         }
372         if (is_interleaved) {
373             switch(pass) {
374             default:
375             case 0:
376             case 1:
377                 y1 += 8;
378                 ptr += linesize * 8;
379                 if (y1 >= height) {
380                     y1 = 4;
381                     if (pass == 0)
382                         ptr = ptr1 + linesize * 4;
383                     else
384                         ptr = ptr1 + linesize * 2;
385                     pass++;
386                 }
387                 break;
388             case 2:
389                 y1 += 4;
390                 ptr += linesize * 4;
391                 if (y1 >= height) {
392                     y1 = 1;
393                     ptr = ptr1 + linesize;
394                     pass++;
395                 }
396                 break;
397             case 3:
398                 y1 += 2;
399                 ptr += linesize * 2;
400                 break;
401             }
402         } else {
403             ptr += linesize;
404         }
405     }
406     av_free(line);
407
408     /* read the garbage data until end marker is found */
409     while (!s->eob_reached)
410         GetCode(s);
411     return 0;
412 }
413
414 static int gif_read_extension(GifState *s)
415 {
416     ByteIOContext *f = s->f;
417     int ext_code, ext_len, i, gce_flags, gce_transparent_index;
418
419     /* extension */
420     ext_code = get_byte(f);
421     ext_len = get_byte(f);
422 #ifdef DEBUG
423     printf("gif: ext_code=0x%x len=%d\n", ext_code, ext_len);
424 #endif
425     switch(ext_code) {
426     case 0xf9:
427         if (ext_len != 4)
428             goto discard_ext;
429         s->transparent_color_index = -1;
430         gce_flags = get_byte(f);
431         s->gce_delay = get_le16(f);
432         gce_transparent_index = get_byte(f);
433         if (gce_flags & 0x01)
434             s->transparent_color_index = gce_transparent_index;
435         else
436             s->transparent_color_index = -1;
437         s->gce_disposal = (gce_flags >> 2) & 0x7;
438 #ifdef DEBUG
439         printf("gif: gce_flags=%x delay=%d tcolor=%d disposal=%d\n",
440                gce_flags, s->gce_delay,
441                s->transparent_color_index, s->gce_disposal);
442 #endif
443         ext_len = get_byte(f);
444         break;
445     }
446
447     /* NOTE: many extension blocks can come after */
448  discard_ext:
449     while (ext_len != 0) {
450         for (i = 0; i < ext_len; i++)
451             get_byte(f);
452         ext_len = get_byte(f);
453 #ifdef DEBUG
454         printf("gif: ext_len1=%d\n", ext_len);
455 #endif
456     }
457     return 0;
458 }
459
460 static int gif_read_header1(GifState *s)
461 {
462     ByteIOContext *f = s->f;
463     uint8_t sig[6];
464     int ret, v, n;
465     int has_global_palette;
466
467     /* read gif signature */
468     ret = get_buffer(f, sig, 6);
469     if (ret != 6)
470         return -1;
471     if (memcmp(sig, gif87a_sig, 6) != 0 &&
472         memcmp(sig, gif89a_sig, 6) != 0)
473         return -1;
474
475     /* read screen header */
476     s->transparent_color_index = -1;
477     s->screen_width = get_le16(f);
478     s->screen_height = get_le16(f);
479     if(   (unsigned)s->screen_width  > 32767
480        || (unsigned)s->screen_height > 32767){
481         av_log(NULL, AV_LOG_ERROR, "picture size too large\n");
482         return -1;
483     }
484
485     v = get_byte(f);
486     s->color_resolution = ((v & 0x70) >> 4) + 1;
487     has_global_palette = (v & 0x80);
488     s->bits_per_pixel = (v & 0x07) + 1;
489     s->background_color_index = get_byte(f);
490     get_byte(f);                /* ignored */
491 #ifdef DEBUG
492     printf("gif: screen_w=%d screen_h=%d bpp=%d global_palette=%d\n",
493            s->screen_width, s->screen_height, s->bits_per_pixel,
494            has_global_palette);
495 #endif
496     if (has_global_palette) {
497         n = 1 << s->bits_per_pixel;
498         get_buffer(f, s->global_palette, n * 3);
499     }
500     return 0;
501 }
502
503 static int gif_parse_next_image(GifState *s)
504 {
505     ByteIOContext *f = s->f;
506     int ret, code;
507
508     for (;;) {
509         code = url_fgetc(f);
510 #ifdef DEBUG
511         printf("gif: code=%02x '%c'\n", code, code);
512 #endif
513         switch (code) {
514         case ',':
515             if (gif_read_image(s) < 0)
516                 return AVERROR_IO;
517             ret = 0;
518             goto the_end;
519         case ';':
520             /* end of image */
521             ret = AVERROR_IO;
522             goto the_end;
523         case '!':
524             if (gif_read_extension(s) < 0)
525                 return AVERROR_IO;
526             break;
527         case EOF:
528         default:
529             /* error or errneous EOF */
530             ret = AVERROR_IO;
531             goto the_end;
532         }
533     }
534   the_end:
535     return ret;
536 }
537
538 static int gif_read_header(AVFormatContext * s1,
539                            AVFormatParameters * ap)
540 {
541     GifState *s = s1->priv_data;
542     ByteIOContext *f = &s1->pb;
543     AVStream *st;
544
545     s->f = f;
546     if (gif_read_header1(s) < 0)
547         return -1;
548
549     /* allocate image buffer */
550     s->image_linesize = s->screen_width * 3;
551     s->image_buf = av_malloc(s->screen_height * s->image_linesize);
552     if (!s->image_buf)
553         return -ENOMEM;
554     s->pix_fmt = PIX_FMT_RGB24;
555     /* now we are ready: build format streams */
556     st = av_new_stream(s1, 0);
557     if (!st)
558         return -1;
559
560     st->codec->codec_type = CODEC_TYPE_VIDEO;
561     st->codec->codec_id = CODEC_ID_RAWVIDEO;
562     st->codec->time_base.den = 5;
563     st->codec->time_base.num = 1;
564     /* XXX: check if screen size is always valid */
565     st->codec->width = s->screen_width;
566     st->codec->height = s->screen_height;
567     st->codec->pix_fmt = PIX_FMT_RGB24;
568     return 0;
569 }
570
571 static int gif_read_packet(AVFormatContext * s1,
572                            AVPacket * pkt)
573 {
574     GifState *s = s1->priv_data;
575     int ret;
576
577     ret = gif_parse_next_image(s);
578     if (ret < 0)
579         return ret;
580
581     /* XXX: avoid copying */
582     if (av_new_packet(pkt, s->screen_width * s->screen_height * 3)) {
583         return AVERROR_IO;
584     }
585     pkt->stream_index = 0;
586     memcpy(pkt->data, s->image_buf, s->screen_width * s->screen_height * 3);
587     return 0;
588 }
589
590 static int gif_read_close(AVFormatContext *s1)
591 {
592     GifState *s = s1->priv_data;
593     av_free(s->image_buf);
594     return 0;
595 }
596
597 /* read gif as image */
598 static int gif_read(ByteIOContext *f,
599                     int (*alloc_cb)(void *opaque, AVImageInfo *info), void *opaque)
600 {
601     GifState s1, *s = &s1;
602     AVImageInfo info1, *info = &info1;
603     int ret;
604
605     memset(s, 0, sizeof(GifState));
606     s->f = f;
607     if (gif_read_header1(s) < 0)
608         return -1;
609     info->width = s->screen_width;
610     info->height = s->screen_height;
611     info->pix_fmt = PIX_FMT_PAL8;
612     ret = alloc_cb(opaque, info);
613     if (ret)
614         return ret;
615     s->image_buf = info->pict.data[0];
616     s->image_linesize = info->pict.linesize[0];
617     s->image_palette = (uint32_t *)info->pict.data[1];
618
619     if (gif_parse_next_image(s) < 0)
620         return -1;
621     return 0;
622 }
623
624 AVInputFormat gif_demuxer =
625 {
626     "gif",
627     "gif format",
628     sizeof(GifState),
629     gif_video_probe,
630     gif_read_header,
631     gif_read_packet,
632     gif_read_close,
633 };
634
635 AVImageFormat gif_image_format = {
636     "gif",
637     "gif",
638     gif_image_probe,
639     gif_read,
640     (1 << PIX_FMT_PAL8),
641 #ifdef CONFIG_GIF_MUXER
642     gif_write,
643 #endif
644 };