/*
 * Megalux Frame demuxer
 * Copyright (c) 2010 Peter Ross <pross@xvid.org>
 *
 * This file is part of FFmpeg.
 *
 * FFmpeg 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.
 *
 * FFmpeg 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 FFmpeg; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

/**
 * @file
 * Megalux Frame demuxer
 */

#include "libavutil/intreadwrite.h"
#include "avformat.h"
#include "riff.h"

static const AVCodecTag frm_pix_fmt_tags[] = {
    { PIX_FMT_RGB555, 1 },
    { PIX_FMT_BGR32,  2 },
    { PIX_FMT_RGB24,  3 },
    { PIX_FMT_BGR0,   4 },
    { PIX_FMT_BGR0,   5 },
};

typedef struct {
    int count;
} FrmContext;

static int frm_read_probe(AVProbeData *p)
{
    if (p->buf_size > 8 &&
        p->buf[0] == 'F' && p->buf[1] == 'R' && p->buf[2] == 'M' &&
        AV_RL16(&p->buf[4]) && AV_RL16(&p->buf[6]))
        return AVPROBE_SCORE_MAX / 4;
    return 0;
}

static int frm_read_header(AVFormatContext *avctx)
{
    AVIOContext *pb = avctx->pb;
    AVStream *st = avformat_new_stream(avctx, 0);
    if (!st)
        return AVERROR(ENOMEM);

    st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
    st->codec->codec_id   = AV_CODEC_ID_RAWVIDEO;
    avio_skip(pb, 3);

    st->codec->pix_fmt    = ff_codec_get_id(frm_pix_fmt_tags, avio_r8(pb));
    if (!st->codec->pix_fmt)
        return AVERROR_INVALIDDATA;

    st->codec->codec_tag  = 0;
    st->codec->width      = avio_rl16(pb);
    st->codec->height     = avio_rl16(pb);
    return 0;
}

static int frm_read_packet(AVFormatContext *avctx, AVPacket *pkt)
{
    FrmContext *s = avctx->priv_data;
    AVCodecContext *stc = avctx->streams[0]->codec;
    int packet_size, ret;

    if (s->count)
        return AVERROR_EOF;

    packet_size = avpicture_get_size(stc->pix_fmt, stc->width, stc->height);
    if (packet_size < 0)
        return AVERROR_INVALIDDATA;

    ret = av_get_packet(avctx->pb, pkt, packet_size);
    if (ret < 0)
        return ret;

    pkt->stream_index = 0;
    s->count++;

    return 0;
}

AVInputFormat ff_frm_demuxer = {
    .name           = "frm",
    .priv_data_size = sizeof(FrmContext),
    .long_name      = NULL_IF_CONFIG_SMALL("Megalux Frame"),
    .read_probe     = frm_read_probe,
    .read_header    = frm_read_header,
    .read_packet    = frm_read_packet,
};
