On Mon, Mar 10, 2014 at 06:00:55PM +0100, Vittorio Giovara wrote:
> From: Paul B Mahol <[email protected]>
> 
> Signed-off-by: Vittorio Giovara <[email protected]>
> ---
>  Changelog                |   1 +
>  doc/general.texi         |   2 +
>  libavformat/Makefile     |   1 +
>  libavformat/allformats.c |   1 +
>  libavformat/smush.c      | 241 
> +++++++++++++++++++++++++++++++++++++++++++++++
>  libavformat/version.h    |   2 +-
>  6 files changed, 247 insertions(+), 1 deletion(-)
>  create mode 100644 libavformat/smush.c
> 
> diff --git a/libavformat/smush.c b/libavformat/smush.c
> new file mode 100644
> index 0000000..6cd77cf
> --- /dev/null
> +++ b/libavformat/smush.c
> @@ -0,0 +1,241 @@
> +/*
> + * LucasArts Smush demuxer
> + * Copyright (c) 2006 Cyril Zorin
> + *
> + * This file is part of Libav.
> + *
> + * Libav is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU Lesser General Public
> + * License as published by the Free Software Foundation; either
> + * version 2.1 of the License, or (at your option) any later version.
> + *
> + * Libav is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> + * Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public
> + * License along with Libav; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 
> USA
> + */
> +
> +#include "libavutil/intreadwrite.h"
> +#include "avformat.h"
> +#include "internal.h"
> +#include "avio.h"
> +
> +typedef struct {
> +    int version;
> +    int audio_stream_index;
> +    int video_stream_index;
> +} SMUSHContext;
> +
> +static int smush_read_probe(AVProbeData *p)
> +{
> +    if (((AV_RL32(p->buf) == MKTAG('S', 'A', 'N', 'M') &&
> +          AV_RL32(p->buf + 8) == MKTAG('S', 'H', 'D', 'R')) ||
> +         (AV_RL32(p->buf) == MKTAG('A', 'N', 'I', 'M') &&
> +          AV_RL32(p->buf + 8) == MKTAG('A', 'H', 'D', 'R')))) {

valign maybe?

> +        return AVPROBE_SCORE_MAX;
> +    }
> +
> +    return 0;
> +}
> +
> +static int smush_read_header(AVFormatContext *ctx)
> +{
> +    SMUSHContext *smush = ctx->priv_data;
> +    AVIOContext *pb = ctx->pb;
> +    AVStream *vst, *ast;
> +    uint32_t magic, nframes, size, subversion, i;
> +    uint32_t width = 0, height = 0, got_audio = 0, read = 0;
> +    uint32_t sample_rate, channels, palette[256];
> +
> +    magic = avio_rb32(pb);
> +    avio_skip(pb, 4); // skip movie size
> +
> +    if (magic == MKBETAG('A', 'N', 'I', 'M')) {
> +        if (avio_rb32(pb) != MKBETAG('A', 'H', 'D', 'R'))
> +            return AVERROR_INVALIDDATA;
> +
> +        size = avio_rb32(pb);
> +        if (size < 3 * 256 + 6)
> +            return AVERROR_INVALIDDATA;
> +
> +        smush->version = 0;
> +        subversion     = avio_rl16(pb);
> +        nframes        = avio_rl16(pb);
> +
> +        avio_skip(pb, 2); // skip pad
> +
> +        for (i = 0; i < 256; i++)
> +            palette[i] = avio_rb24(pb);
> +
> +        avio_skip(pb, size - (3 * 256 + 6));
> +    } else if (magic == MKBETAG('S', 'A', 'N', 'M')) {
> +        if (avio_rb32(pb) != MKBETAG('S', 'H', 'D', 'R'))
> +            return AVERROR_INVALIDDATA;
> +
> +        size = avio_rb32(pb);
> +        if (size < 14)
> +            return AVERROR_INVALIDDATA;
> +
> +        smush->version = 1;
> +        subversion = avio_rl16(pb);

git?

> +        nframes = avio_rl32(pb);
> +        avio_skip(pb, 2); // skip pad
> +        width  = avio_rl16(pb);
> +        height = avio_rl16(pb);
> +        avio_skip(pb, 2); // skip pad
> +        avio_skip(pb, size - 14);
> +
> +        if (avio_rb32(pb) != MKBETAG('F', 'L', 'H', 'D'))
> +            return AVERROR_INVALIDDATA;
> +
> +        size = avio_rb32(pb);
> +        while (!got_audio && ((read + 8) < size)) {
> +            uint32_t sig, chunk_size;
> +
> +            if (pb->eof_reached)
> +                return AVERROR_EOF;
> +
> +            sig        = avio_rb32(pb);
> +            chunk_size = avio_rb32(pb);
> +            read      += 8;
> +            switch (sig) {
> +            case MKBETAG('W', 'a', 'v', 'e'):
> +                got_audio   = 1;
> +                sample_rate = avio_rl32(pb);
> +                channels    = avio_rl32(pb);
> +                avio_skip(pb, chunk_size - 8);
> +                read += chunk_size;
> +                break;
> +            case MKBETAG('B', 'l', '1', '6'):
> +            case MKBETAG('A', 'N', 'N', 'O'):
> +                avio_skip(pb, chunk_size);
> +                read += chunk_size;
> +                break;
> +            default:
> +                return AVERROR_INVALIDDATA;
> +                break;
> +            }
> +        }
> +
> +        avio_skip(pb, size - read);
> +    } else {
> +        av_log(ctx, AV_LOG_ERROR, "Wrong magic\n");
> +        return AVERROR_INVALIDDATA;
> +    }

Maybe validate nframes/channels/sample_rate being nonzero?

> +
> +    vst = avformat_new_stream(ctx, 0);
> +    if (!vst)
> +        return AVERROR(ENOMEM);
> +
> +    smush->video_stream_index = vst->index;
> +
> +    vst->start_time        = 0;
> +    vst->duration          =
> +    vst->nb_frames         = nframes;
> +    vst->codec->codec_type = AVMEDIA_TYPE_VIDEO;
> +    vst->codec->codec_id   = AV_CODEC_ID_SANM;
> +    vst->codec->codec_tag  = 0;
> +    vst->codec->width      = width;
> +    vst->codec->height     = height;
> +
> +    avpriv_set_pts_info(vst, 64, 66667, 1000000);

May I WTF and suggest 15 fps instead?

[...]

the rest looks good enough
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to