LCOV - code coverage report
Current view: top level - libavformat - swfdec.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 102 353 28.9 %
Date: 2017-12-17 04:34:43 Functions: 5 7 71.4 %

          Line data    Source code
       1             : /*
       2             :  * Flash Compatible Streaming Format demuxer
       3             :  * Copyright (c) 2000 Fabrice Bellard
       4             :  * Copyright (c) 2003 Tinic Uro
       5             :  *
       6             :  * This file is part of FFmpeg.
       7             :  *
       8             :  * FFmpeg is free software; you can redistribute it and/or
       9             :  * modify it under the terms of the GNU Lesser General Public
      10             :  * License as published by the Free Software Foundation; either
      11             :  * version 2.1 of the License, or (at your option) any later version.
      12             :  *
      13             :  * FFmpeg is distributed in the hope that it will be useful,
      14             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      15             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      16             :  * Lesser General Public License for more details.
      17             :  *
      18             :  * You should have received a copy of the GNU Lesser General Public
      19             :  * License along with FFmpeg; if not, write to the Free Software
      20             :  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
      21             :  */
      22             : 
      23             : #include "config.h"
      24             : 
      25             : #if CONFIG_ZLIB
      26             : #include <zlib.h>
      27             : #endif
      28             : 
      29             : #include "libavutil/avassert.h"
      30             : #include "libavutil/channel_layout.h"
      31             : #include "libavutil/imgutils.h"
      32             : #include "libavutil/internal.h"
      33             : #include "libavutil/intreadwrite.h"
      34             : #include "libavcodec/get_bits.h"
      35             : #include "swf.h"
      36             : 
      37             : static const AVCodecTag swf_audio_codec_tags[] = {
      38             :     { AV_CODEC_ID_PCM_S16LE,  0x00 },
      39             :     { AV_CODEC_ID_ADPCM_SWF,  0x01 },
      40             :     { AV_CODEC_ID_MP3,        0x02 },
      41             :     { AV_CODEC_ID_PCM_S16LE,  0x03 },
      42             : //  { AV_CODEC_ID_NELLYMOSER, 0x06 },
      43             :     { AV_CODEC_ID_NONE,          0 },
      44             : };
      45             : 
      46        2213 : static int get_swf_tag(AVIOContext *pb, int *len_ptr)
      47             : {
      48             :     int tag, len;
      49             : 
      50        2213 :     if (avio_feof(pb))
      51          29 :         return AVERROR_EOF;
      52             : 
      53        2184 :     tag = avio_rl16(pb);
      54        2184 :     len = tag & 0x3f;
      55        2184 :     tag = tag >> 6;
      56        2184 :     if (len == 0x3f) {
      57         700 :         len = avio_rl32(pb);
      58             :     }
      59        2184 :     *len_ptr = len;
      60        2184 :     return tag;
      61             : }
      62             : 
      63             : 
      64        6130 : static int swf_probe(AVProbeData *p)
      65             : {
      66             :     GetBitContext gb;
      67             :     int len, xmin, xmax, ymin, ymax;
      68             : 
      69        6130 :     if(p->buf_size < 15)
      70           0 :         return 0;
      71             : 
      72             :     /* check file header */
      73        6130 :     if (   AV_RB24(p->buf) != AV_RB24("CWS")
      74        6130 :         && AV_RB24(p->buf) != AV_RB24("FWS"))
      75        6128 :         return 0;
      76             : 
      77           2 :     if (   AV_RB24(p->buf) == AV_RB24("CWS")
      78           0 :         && p->buf[3] <= 20)
      79           0 :         return AVPROBE_SCORE_MAX / 4 + 1;
      80             : 
      81           2 :     if (init_get_bits8(&gb, p->buf + 3, p->buf_size - 3) < 0)
      82           0 :         return 0;
      83             : 
      84           2 :     skip_bits(&gb, 40);
      85           2 :     len = get_bits(&gb, 5);
      86           2 :     if (!len)
      87           0 :         return 0;
      88           2 :     xmin = get_bits_long(&gb, len);
      89           2 :     xmax = get_bits_long(&gb, len);
      90           2 :     ymin = get_bits_long(&gb, len);
      91           2 :     ymax = get_bits_long(&gb, len);
      92           2 :     if (xmin || ymin || !xmax || !ymax)
      93           0 :         return 0;
      94             : 
      95           2 :     if (p->buf[3] >= 20 || xmax < 16 || ymax < 16)
      96           0 :         return AVPROBE_SCORE_MAX / 4;
      97             : 
      98           2 :     return AVPROBE_SCORE_MAX;
      99             : }
     100             : 
     101             : #if CONFIG_ZLIB
     102           0 : static int zlib_refill(void *opaque, uint8_t *buf, int buf_size)
     103             : {
     104           0 :     AVFormatContext *s = opaque;
     105           0 :     SWFContext *swf = s->priv_data;
     106           0 :     z_stream *z = &swf->zstream;
     107             :     int ret;
     108             : 
     109           0 : retry:
     110           0 :     if (!z->avail_in) {
     111           0 :         int n = avio_read(s->pb, swf->zbuf_in, ZBUF_SIZE);
     112           0 :         if (n < 0)
     113           0 :             return n;
     114           0 :         z->next_in  = swf->zbuf_in;
     115           0 :         z->avail_in = n;
     116             :     }
     117             : 
     118           0 :     z->next_out  = buf;
     119           0 :     z->avail_out = buf_size;
     120             : 
     121           0 :     ret = inflate(z, Z_NO_FLUSH);
     122           0 :     if (ret == Z_STREAM_END)
     123           0 :         return AVERROR_EOF;
     124           0 :     if (ret != Z_OK)
     125           0 :         return AVERROR(EINVAL);
     126             : 
     127           0 :     if (buf_size - z->avail_out == 0)
     128           0 :         goto retry;
     129             : 
     130           0 :     return buf_size - z->avail_out;
     131             : }
     132             : #endif
     133             : 
     134           2 : static int swf_read_header(AVFormatContext *s)
     135             : {
     136           2 :     SWFContext *swf = s->priv_data;
     137           2 :     AVIOContext *pb = s->pb;
     138             :     int nbits, len, tag;
     139             : 
     140           2 :     tag = avio_rb32(pb) & 0xffffff00;
     141           2 :     avio_rl32(pb);
     142             : 
     143           2 :     if (tag == MKBETAG('C', 'W', 'S', 0)) {
     144           0 :         av_log(s, AV_LOG_INFO, "SWF compressed file detected\n");
     145             : #if CONFIG_ZLIB
     146           0 :         swf->zbuf_in  = av_malloc(ZBUF_SIZE);
     147           0 :         swf->zbuf_out = av_malloc(ZBUF_SIZE);
     148           0 :         swf->zpb = avio_alloc_context(swf->zbuf_out, ZBUF_SIZE, 0, s,
     149             :                                       zlib_refill, NULL, NULL);
     150           0 :         if (!swf->zbuf_in || !swf->zbuf_out || !swf->zpb)
     151           0 :             return AVERROR(ENOMEM);
     152           0 :         swf->zpb->seekable = 0;
     153           0 :         if (inflateInit(&swf->zstream) != Z_OK) {
     154           0 :             av_log(s, AV_LOG_ERROR, "Unable to init zlib context\n");
     155           0 :             return AVERROR(EINVAL);
     156             :         }
     157           0 :         pb = swf->zpb;
     158             : #else
     159             :         av_log(s, AV_LOG_ERROR, "zlib support is required to read SWF compressed files\n");
     160             :         return AVERROR(EIO);
     161             : #endif
     162           2 :     } else if (tag != MKBETAG('F', 'W', 'S', 0))
     163           0 :         return AVERROR(EIO);
     164             :     /* skip rectangle size */
     165           2 :     nbits = avio_r8(pb) >> 3;
     166           2 :     len = (4 * nbits - 3 + 7) / 8;
     167           2 :     avio_skip(pb, len);
     168           2 :     swf->frame_rate = avio_rl16(pb); /* 8.8 fixed */
     169           2 :     avio_rl16(pb); /* frame count */
     170             : 
     171           2 :     swf->samples_per_frame = 0;
     172           2 :     s->ctx_flags |= AVFMTCTX_NOHEADER;
     173           2 :     return 0;
     174             : }
     175             : 
     176           0 : static AVStream *create_new_audio_stream(AVFormatContext *s, int id, int info)
     177             : {
     178             :     int sample_rate_code, sample_size_code;
     179           0 :     AVStream *ast = avformat_new_stream(s, NULL);
     180           0 :     if (!ast)
     181           0 :         return NULL;
     182           0 :     ast->id = id;
     183           0 :     if (info & 1) {
     184           0 :         ast->codecpar->channels       = 2;
     185           0 :         ast->codecpar->channel_layout = AV_CH_LAYOUT_STEREO;
     186             :     } else {
     187           0 :         ast->codecpar->channels       = 1;
     188           0 :         ast->codecpar->channel_layout = AV_CH_LAYOUT_MONO;
     189             :     }
     190           0 :     ast->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
     191           0 :     ast->codecpar->codec_id   = ff_codec_get_id(swf_audio_codec_tags, info>>4 & 15);
     192           0 :     ast->need_parsing = AVSTREAM_PARSE_FULL;
     193           0 :     sample_rate_code = info>>2 & 3;
     194           0 :     sample_size_code = info>>1 & 1;
     195           0 :     if (!sample_size_code && ast->codecpar->codec_id == AV_CODEC_ID_PCM_S16LE)
     196           0 :         ast->codecpar->codec_id = AV_CODEC_ID_PCM_U8;
     197           0 :     ast->codecpar->sample_rate = 44100 >> (3 - sample_rate_code);
     198           0 :     avpriv_set_pts_info(ast, 64, 1, ast->codecpar->sample_rate);
     199           0 :     return ast;
     200             : }
     201             : 
     202         729 : static int swf_read_packet(AVFormatContext *s, AVPacket *pkt)
     203             : {
     204         729 :     SWFContext *swf = s->priv_data;
     205         729 :     AVIOContext *pb = s->pb;
     206         729 :     AVStream *vst = NULL, *ast = NULL, *st = 0;
     207             :     int tag, len, i, frame, v, res;
     208             : 
     209             : #if CONFIG_ZLIB
     210         729 :     if (swf->zpb)
     211           0 :         pb = swf->zpb;
     212             : #endif
     213             : 
     214        1484 :     for(;;) {
     215        2213 :         uint64_t pos = avio_tell(pb);
     216        2213 :         tag = get_swf_tag(pb, &len);
     217        2213 :         if (tag < 0)
     218          29 :             return tag;
     219        2184 :         if (len < 0) {
     220           0 :             av_log(s, AV_LOG_ERROR, "invalid tag length: %d\n", len);
     221           0 :             return AVERROR_INVALIDDATA;
     222             :         }
     223        2184 :         if (tag == TAG_VIDEOSTREAM) {
     224          28 :             int ch_id = avio_rl16(pb);
     225          28 :             len -= 2;
     226             : 
     227          28 :             for (i=0; i<s->nb_streams; i++) {
     228          26 :                 st = s->streams[i];
     229          26 :                 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && st->id == ch_id)
     230          26 :                     goto skip;
     231             :             }
     232             : 
     233           2 :             avio_rl16(pb);
     234           2 :             avio_rl16(pb);
     235           2 :             avio_rl16(pb);
     236           2 :             avio_r8(pb);
     237             :             /* Check for FLV1 */
     238           2 :             vst = avformat_new_stream(s, NULL);
     239           2 :             if (!vst)
     240           0 :                 return AVERROR(ENOMEM);
     241           2 :             vst->id = ch_id;
     242           2 :             vst->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
     243           2 :             vst->codecpar->codec_id = ff_codec_get_id(ff_swf_codec_tags, avio_r8(pb));
     244           2 :             avpriv_set_pts_info(vst, 16, 256, swf->frame_rate);
     245           2 :             len -= 8;
     246        2156 :         } else if (tag == TAG_STREAMHEAD || tag == TAG_STREAMHEAD2) {
     247             :             /* streaming found */
     248             : 
     249           0 :             for (i=0; i<s->nb_streams; i++) {
     250           0 :                 st = s->streams[i];
     251           0 :                 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && st->id == -1)
     252           0 :                     goto skip;
     253             :             }
     254             : 
     255           0 :             avio_r8(pb);
     256           0 :             v = avio_r8(pb);
     257           0 :             swf->samples_per_frame = avio_rl16(pb);
     258           0 :             ast = create_new_audio_stream(s, -1, v); /* -1 to avoid clash with video stream ch_id */
     259           0 :             if (!ast)
     260           0 :                 return AVERROR(ENOMEM);
     261           0 :             len -= 4;
     262        2156 :         } else if (tag == TAG_DEFINESOUND) {
     263             :             /* audio stream */
     264           0 :             int ch_id = avio_rl16(pb);
     265             : 
     266           0 :             for (i=0; i<s->nb_streams; i++) {
     267           0 :                 st = s->streams[i];
     268           0 :                 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && st->id == ch_id)
     269           0 :                     goto skip;
     270             :             }
     271             : 
     272             :             // FIXME: The entire audio stream is stored in a single chunk/tag. Normally,
     273             :             // these are smaller audio streams in DEFINESOUND tags, but it's technically
     274             :             // possible they could be huge. Break it up into multiple packets if it's big.
     275           0 :             v = avio_r8(pb);
     276           0 :             ast = create_new_audio_stream(s, ch_id, v);
     277           0 :             if (!ast)
     278           0 :                 return AVERROR(ENOMEM);
     279           0 :             ast->duration = avio_rl32(pb); // number of samples
     280           0 :             if (((v>>4) & 15) == 2) { // MP3 sound data record
     281           0 :                 ast->skip_samples = avio_rl16(pb);
     282           0 :                 len -= 2;
     283             :             }
     284           0 :             len -= 7;
     285           0 :             if ((res = av_get_packet(pb, pkt, len)) < 0)
     286           0 :                 return res;
     287           0 :             pkt->pos = pos;
     288           0 :             pkt->stream_index = ast->index;
     289           0 :             return pkt->size;
     290        2156 :         } else if (tag == TAG_VIDEOFRAME) {
     291         700 :             int ch_id = avio_rl16(pb);
     292         700 :             len -= 2;
     293         700 :             for(i=0; i<s->nb_streams; i++) {
     294         700 :                 st = s->streams[i];
     295         700 :                 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && st->id == ch_id) {
     296         700 :                     frame = avio_rl16(pb);
     297         700 :                     len -= 2;
     298         700 :                     if (len <= 0)
     299           0 :                         goto skip;
     300         700 :                     if ((res = av_get_packet(pb, pkt, len)) < 0)
     301           0 :                         return res;
     302         700 :                     pkt->pos = pos;
     303         700 :                     pkt->pts = frame;
     304         700 :                     pkt->stream_index = st->index;
     305         700 :                     return pkt->size;
     306             :                 }
     307             :             }
     308        1456 :         } else if (tag == TAG_DEFINEBITSLOSSLESS || tag == TAG_DEFINEBITSLOSSLESS2) {
     309             : #if CONFIG_ZLIB
     310             :             long out_len;
     311           0 :             uint8_t *buf = NULL, *zbuf = NULL, *pal;
     312           0 :             uint32_t colormap[AVPALETTE_COUNT] = {0};
     313           0 :             const int alpha_bmp = tag == TAG_DEFINEBITSLOSSLESS2;
     314           0 :             const int colormapbpp = 3 + alpha_bmp;
     315           0 :             int linesize, colormapsize = 0;
     316             : 
     317           0 :             const int ch_id   = avio_rl16(pb);
     318           0 :             const int bmp_fmt = avio_r8(pb);
     319           0 :             const int width   = avio_rl16(pb);
     320           0 :             const int height  = avio_rl16(pb);
     321             :             int pix_fmt;
     322             : 
     323           0 :             len -= 2+1+2+2;
     324             : 
     325           0 :             switch (bmp_fmt) {
     326           0 :             case 3: // PAL-8
     327           0 :                 linesize = width;
     328           0 :                 colormapsize = avio_r8(pb) + 1;
     329           0 :                 len--;
     330           0 :                 break;
     331           0 :             case 4: // RGB15
     332           0 :                 linesize = width * 2;
     333           0 :                 break;
     334           0 :             case 5: // RGB24 (0RGB)
     335           0 :                 linesize = width * 4;
     336           0 :                 break;
     337           0 :             default:
     338           0 :                 av_log(s, AV_LOG_ERROR, "invalid bitmap format %d, skipped\n", bmp_fmt);
     339           0 :                 goto bitmap_end_skip;
     340             :             }
     341             : 
     342           0 :             linesize = FFALIGN(linesize, 4);
     343             : 
     344           0 :             if (av_image_check_size(width, height, 0, s) < 0 ||
     345           0 :                 linesize >= INT_MAX / height ||
     346           0 :                 linesize * height >= INT_MAX - colormapsize * colormapbpp) {
     347           0 :                 av_log(s, AV_LOG_ERROR, "invalid frame size %dx%d\n", width, height);
     348           0 :                 goto bitmap_end_skip;
     349             :             }
     350             : 
     351           0 :             out_len = colormapsize * colormapbpp + linesize * height;
     352             : 
     353             :             ff_dlog(s, "bitmap: ch=%d fmt=%d %dx%d (linesize=%d) len=%d->%ld pal=%d\n",
     354             :                     ch_id, bmp_fmt, width, height, linesize, len, out_len, colormapsize);
     355             : 
     356           0 :             zbuf = av_malloc(len);
     357           0 :             buf  = av_malloc(out_len);
     358           0 :             if (!zbuf || !buf) {
     359           0 :                 res = AVERROR(ENOMEM);
     360           0 :                 goto bitmap_end;
     361             :             }
     362             : 
     363           0 :             len = avio_read(pb, zbuf, len);
     364           0 :             if (len < 0 || (res = uncompress(buf, &out_len, zbuf, len)) != Z_OK) {
     365           0 :                 av_log(s, AV_LOG_WARNING, "Failed to uncompress one bitmap\n");
     366           0 :                 goto bitmap_end_skip;
     367             :             }
     368             : 
     369           0 :             for (i = 0; i < s->nb_streams; i++) {
     370           0 :                 st = s->streams[i];
     371           0 :                 if (st->codecpar->codec_id == AV_CODEC_ID_RAWVIDEO && st->id == -3)
     372           0 :                     break;
     373             :             }
     374           0 :             if (i == s->nb_streams) {
     375           0 :                 vst = avformat_new_stream(s, NULL);
     376           0 :                 if (!vst) {
     377           0 :                     res = AVERROR(ENOMEM);
     378           0 :                     goto bitmap_end;
     379             :                 }
     380           0 :                 vst->id = -3; /* -3 to avoid clash with video stream and audio stream */
     381           0 :                 vst->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
     382           0 :                 vst->codecpar->codec_id = AV_CODEC_ID_RAWVIDEO;
     383           0 :                 avpriv_set_pts_info(vst, 64, 256, swf->frame_rate);
     384           0 :                 st = vst;
     385             :             }
     386             : 
     387           0 :             if ((res = av_new_packet(pkt, out_len - colormapsize * colormapbpp)) < 0)
     388           0 :                 goto bitmap_end;
     389           0 :             if (!st->codecpar->width && !st->codecpar->height) {
     390           0 :                 st->codecpar->width  = width;
     391           0 :                 st->codecpar->height = height;
     392             :             } else {
     393           0 :                 ff_add_param_change(pkt, 0, 0, 0, width, height);
     394             :             }
     395           0 :             pkt->pos = pos;
     396           0 :             pkt->stream_index = st->index;
     397             : 
     398           0 :             if (linesize * height > pkt->size) {
     399           0 :                 res = AVERROR_INVALIDDATA;
     400           0 :                 av_packet_unref(pkt);
     401           0 :                 goto bitmap_end;
     402             :             }
     403             : 
     404           0 :             switch (bmp_fmt) {
     405           0 :             case 3:
     406           0 :                 pix_fmt = AV_PIX_FMT_PAL8;
     407           0 :                 for (i = 0; i < colormapsize; i++)
     408           0 :                     if (alpha_bmp)  colormap[i] = buf[3]<<24 | AV_RB24(buf + 4*i);
     409           0 :                     else            colormap[i] = 0xffU <<24 | AV_RB24(buf + 3*i);
     410           0 :                 pal = av_packet_new_side_data(pkt, AV_PKT_DATA_PALETTE, AVPALETTE_SIZE);
     411           0 :                 if (!pal) {
     412           0 :                     res = AVERROR(ENOMEM);
     413           0 :                     goto bitmap_end;
     414             :                 }
     415           0 :                 memcpy(pal, colormap, AVPALETTE_SIZE);
     416           0 :                 break;
     417           0 :             case 4:
     418           0 :                 pix_fmt = AV_PIX_FMT_RGB555;
     419           0 :                 break;
     420           0 :             case 5:
     421           0 :                 pix_fmt = alpha_bmp ? AV_PIX_FMT_ARGB : AV_PIX_FMT_0RGB;
     422           0 :                 break;
     423           0 :             default:
     424           0 :                 av_assert0(0);
     425             :             }
     426           0 :             if (st->codecpar->format != AV_PIX_FMT_NONE && st->codecpar->format != pix_fmt) {
     427           0 :                 av_log(s, AV_LOG_ERROR, "pixel format change unsupported\n");
     428             :             } else
     429           0 :                 st->codecpar->format = pix_fmt;
     430             : 
     431           0 :             memcpy(pkt->data, buf + colormapsize*colormapbpp, linesize * height);
     432             : 
     433           0 :             res = pkt->size;
     434             : 
     435           0 : bitmap_end:
     436           0 :             av_freep(&zbuf);
     437           0 :             av_freep(&buf);
     438           0 :             return res;
     439           0 : bitmap_end_skip:
     440           0 :             av_freep(&zbuf);
     441           0 :             av_freep(&buf);
     442             : #else
     443             :             av_log(s, AV_LOG_ERROR, "this file requires zlib support compiled in\n");
     444             : #endif
     445        1456 :         } else if (tag == TAG_STREAMBLOCK) {
     446           0 :             for (i = 0; i < s->nb_streams; i++) {
     447           0 :                 st = s->streams[i];
     448           0 :                 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && st->id == -1) {
     449           0 :                     if (st->codecpar->codec_id == AV_CODEC_ID_MP3) {
     450           0 :                         avio_skip(pb, 4);
     451           0 :                         len -= 4;
     452           0 :                         if (len <= 0)
     453           0 :                             goto skip;
     454           0 :                         if ((res = av_get_packet(pb, pkt, len)) < 0)
     455           0 :                             return res;
     456             :                     } else { // ADPCM, PCM
     457           0 :                         if (len <= 0)
     458           0 :                             goto skip;
     459           0 :                         if ((res = av_get_packet(pb, pkt, len)) < 0)
     460           0 :                             return res;
     461             :                     }
     462           0 :                     pkt->pos          = pos;
     463           0 :                     pkt->stream_index = st->index;
     464           0 :                     return pkt->size;
     465             :                 }
     466             :             }
     467        1456 :         } else if (tag == TAG_JPEG2) {
     468           0 :             for (i=0; i<s->nb_streams; i++) {
     469           0 :                 st = s->streams[i];
     470           0 :                 if (st->codecpar->codec_id == AV_CODEC_ID_MJPEG && st->id == -2)
     471           0 :                     break;
     472             :             }
     473           0 :             if (i == s->nb_streams) {
     474           0 :                 vst = avformat_new_stream(s, NULL);
     475           0 :                 if (!vst)
     476           0 :                     return AVERROR(ENOMEM);
     477           0 :                 vst->id = -2; /* -2 to avoid clash with video stream and audio stream */
     478           0 :                 vst->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
     479           0 :                 vst->codecpar->codec_id = AV_CODEC_ID_MJPEG;
     480           0 :                 avpriv_set_pts_info(vst, 64, 256, swf->frame_rate);
     481           0 :                 st = vst;
     482             :             }
     483           0 :             avio_rl16(pb); /* BITMAP_ID */
     484           0 :             len -= 2;
     485           0 :             if (len < 4)
     486           0 :                 goto skip;
     487           0 :             if ((res = av_new_packet(pkt, len)) < 0)
     488           0 :                 return res;
     489           0 :             if (avio_read(pb, pkt->data, 4) != 4) {
     490           0 :                 av_packet_unref(pkt);
     491           0 :                 return AVERROR_INVALIDDATA;
     492             :             }
     493           0 :             if (AV_RB32(pkt->data) == 0xffd8ffd9 ||
     494           0 :                 AV_RB32(pkt->data) == 0xffd9ffd8) {
     495             :                 /* old SWF files containing SOI/EOI as data start */
     496             :                 /* files created by swink have reversed tag */
     497           0 :                 pkt->size -= 4;
     498           0 :                 memset(pkt->data+pkt->size, 0, 4);
     499           0 :                 res = avio_read(pb, pkt->data, pkt->size);
     500             :             } else {
     501           0 :                 res = avio_read(pb, pkt->data + 4, pkt->size - 4);
     502           0 :                 if (res >= 0)
     503           0 :                     res += 4;
     504             :             }
     505           0 :             if (res != pkt->size) {
     506           0 :                 if (res < 0) {
     507           0 :                     av_packet_unref(pkt);
     508           0 :                     return res;
     509             :                 }
     510           0 :                 av_shrink_packet(pkt, res);
     511             :             }
     512             : 
     513           0 :             pkt->pos = pos;
     514           0 :             pkt->stream_index = st->index;
     515           0 :             return pkt->size;
     516             :         } else {
     517        1456 :             av_log(s, AV_LOG_DEBUG, "Unknown tag: %d\n", tag);
     518             :         }
     519        1484 :     skip:
     520        1484 :         if(len<0)
     521           0 :             av_log(s, AV_LOG_WARNING, "Clipping len %d\n", len);
     522        1484 :         len = FFMAX(0, len);
     523        1484 :         avio_skip(pb, len);
     524             :     }
     525             : }
     526             : 
     527             : #if CONFIG_ZLIB
     528           2 : static av_cold int swf_read_close(AVFormatContext *avctx)
     529             : {
     530           2 :     SWFContext *s = avctx->priv_data;
     531           2 :     inflateEnd(&s->zstream);
     532           2 :     av_freep(&s->zbuf_in);
     533           2 :     av_freep(&s->zbuf_out);
     534           2 :     avio_context_free(&s->zpb);
     535           2 :     return 0;
     536             : }
     537             : #endif
     538             : 
     539             : AVInputFormat ff_swf_demuxer = {
     540             :     .name           = "swf",
     541             :     .long_name      = NULL_IF_CONFIG_SMALL("SWF (ShockWave Flash)"),
     542             :     .priv_data_size = sizeof(SWFContext),
     543             :     .read_probe     = swf_probe,
     544             :     .read_header    = swf_read_header,
     545             :     .read_packet    = swf_read_packet,
     546             : #if CONFIG_ZLIB
     547             :     .read_close     = swf_read_close,
     548             : #endif
     549             : };

Generated by: LCOV version 1.13