Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

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