/*
 * WavPack demuxer
 * Copyright (c) 2006,2011 Konstantin Shishkov
 *
 * 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
 */

#include "libavutil/channel_layout.h"
#include "libavutil/intreadwrite.h"
#include "libavutil/dict.h"
#include "avformat.h"
#include "internal.h"
#include "apetag.h"
#include "id3v1.h"
#include "wv.h"

enum WV_FLAGS {
    WV_MONO   = 0x0004,
    WV_HYBRID = 0x0008,
    WV_JOINT  = 0x0010,
    WV_CROSSD = 0x0020,
    WV_HSHAPE = 0x0040,
    WV_FLOAT  = 0x0080,
    WV_INT32  = 0x0100,
    WV_HBR    = 0x0200,
    WV_HBAL   = 0x0400,
    WV_MCINIT = 0x0800,
    WV_MCEND  = 0x1000,
    WV_DSD    = 0x80000000,
};

static const int wv_rates[16] = {
     6000,  8000,  9600, 11025, 12000, 16000,  22050, 24000,
    32000, 44100, 48000, 64000, 88200, 96000, 192000,    -1
};

typedef struct WVContext {
    uint8_t block_header[WV_HEADER_SIZE];
    WvHeader header;
    int rate, chan, bpp;
    uint32_t chmask;
    int multichannel;
    int block_parsed;
    int64_t pos;

    int64_t apetag_start;
} WVContext;

static int wv_probe(const AVProbeData *p)
{
    /* check file header */
    if (p->buf_size <= 32)
        return 0;
    if (AV_RL32(&p->buf[0]) == MKTAG('w', 'v', 'p', 'k') &&
        AV_RL32(&p->buf[4]) >= 24 &&
        AV_RL32(&p->buf[4]) <= WV_BLOCK_LIMIT &&
        AV_RL16(&p->buf[8]) >= 0x402 &&
        AV_RL16(&p->buf[8]) <= 0x410)
        return AVPROBE_SCORE_MAX;
    else
        return 0;
}

static int wv_read_block_header(AVFormatContext *ctx, AVIOContext *pb)
{
    WVContext *wc = ctx->priv_data;
    int ret;
    int rate, rate_x, bpp, chan;
    uint32_t chmask, flags;

    wc->pos = avio_tell(pb);

    /* don't return bogus packets with the ape tag data */
    if (wc->apetag_start && wc->pos >= wc->apetag_start)
        return AVERROR_EOF;

    ret = avio_read(pb, wc->block_header, WV_HEADER_SIZE);
    if (ret != WV_HEADER_SIZE)
        return (ret < 0) ? ret : AVERROR_EOF;

    ret = ff_wv_parse_header(&wc->header, wc->block_header);
    if (ret < 0) {
        av_log(ctx, AV_LOG_ERROR, "Invalid block header.\n");
        return ret;
    }

    if (wc->header.version < 0x402 || wc->header.version > 0x410) {
        avpriv_report_missing_feature(ctx, "WV version 0x%03X",
                                      wc->header.version);
        return AVERROR_PATCHWELCOME;
    }

    /* Blocks with zero samples don't contain actual audio information
     * and should be ignored */
    if (!wc->header.samples)
        return 0;
    // parse flags
    flags  = wc->header.flags;
    rate_x = (flags & WV_DSD) ? 4 : 1;
    bpp    = (flags & WV_DSD) ? 0 : ((flags & 3) + 1) << 3;
    chan   = 1 + !(flags & WV_MONO);
    chmask = flags & WV_MONO ? AV_CH_LAYOUT_MONO : AV_CH_LAYOUT_STEREO;
    rate   = wv_rates[(flags >> 23) & 0xF];
    wc->multichannel = !(wc->header.initial && wc->header.final);
    if (wc->multichannel) {
        chan   = wc->chan;
        chmask = wc->chmask;
    }
    if ((rate == -1 || !chan || flags & WV_DSD) && !wc->block_parsed) {
        int64_t block_end = avio_tell(pb) + wc->header.blocksize;
        if (!(pb->seekable & AVIO_SEEKABLE_NORMAL)) {
            av_log(ctx, AV_LOG_ERROR,
                   "Cannot determine additional parameters\n");
            return AVERROR_INVALIDDATA;
        }
        while (avio_tell(pb) < block_end && !avio_feof(pb)) {
            int id, size;
            id   = avio_r8(pb);
            size = (id & 0x80) ? avio_rl24(pb) : avio_r8(pb);
            size <<= 1;
            if (id & 0x40)
                size--;
            switch (id & 0x3F) {
            case 0xD:
                if (size <= 1) {
                    av_log(ctx, AV_LOG_ERROR,
                           "Insufficient channel information\n");
                    return AVERROR_INVALIDDATA;
                }
                chan = avio_r8(pb);
                switch (size - 2) {
                case 0:
                    chmask = avio_r8(pb);
                    break;
                case 1:
                    chmask = avio_rl16(pb);
                    break;
                case 2:
                    chmask = avio_rl24(pb);
                    break;
                case 3:
                    chmask = avio_rl32(pb);
                    break;
                case 4:
                    avio_skip(pb, 1);
                    chan  |= (avio_r8(pb) & 0xF) << 8;
                    chan  += 1;
                    chmask = avio_rl24(pb);
                    break;
                case 5:
                    avio_skip(pb, 1);
                    chan  |= (avio_r8(pb) & 0xF) << 8;
                    chan  += 1;
                    chmask = avio_rl32(pb);
                    break;
                default:
                    av_log(ctx, AV_LOG_ERROR,
                           "Invalid channel info size %d\n", size);
                    return AVERROR_INVALIDDATA;
                }
                break;
            case 0xE:
                if (size <= 1) {
                    av_log(ctx, AV_LOG_ERROR,
                           "Invalid DSD block\n");
                    return AVERROR_INVALIDDATA;
                }
                rate_x = 1U << (avio_r8(pb) & 0x1f);
                if (size)
                    avio_skip(pb, size-1);
                break;
            case 0x27:
                rate = avio_rl24(pb);
                break;
            default:
                avio_skip(pb, size);
            }
            if (id & 0x40)
                avio_skip(pb, 1);
        }
        if (rate == -1) {
            av_log(ctx, AV_LOG_ERROR,
                   "Cannot determine custom sampling rate\n");
            return AVERROR_INVALIDDATA;
        }
        avio_seek(pb, block_end - wc->header.blocksize, SEEK_SET);
    }
    if (!wc->bpp)
        wc->bpp    = bpp;
    if (!wc->chan)
        wc->chan   = chan;
    if (!wc->chmask)
        wc->chmask = chmask;
    if (!wc->rate)
        wc->rate   = rate * rate_x;

    if (flags && bpp != wc->bpp) {
        av_log(ctx, AV_LOG_ERROR,
               "Bits per sample differ, this block: %i, header block: %i\n",
               bpp, wc->bpp);
        return AVERROR_INVALIDDATA;
    }
    if (flags && !wc->multichannel && chan != wc->chan) {
        av_log(ctx, AV_LOG_ERROR,
               "Channels differ, this block: %i, header block: %i\n",
               chan, wc->chan);
        return AVERROR_INVALIDDATA;
    }
    if (flags && rate != -1 && !(flags & WV_DSD) && rate * rate_x != wc->rate) {
        av_log(ctx, AV_LOG_ERROR,
               "Sampling rate differ, this block: %i, header block: %i\n",
               rate * rate_x, wc->rate);
        return AVERROR_INVALIDDATA;
    }
    return 0;
}

static int wv_read_header(AVFormatContext *s)
{
    AVIOContext *pb = s->pb;
    WVContext *wc = s->priv_data;
    AVStream *st;
    int ret;

    wc->block_parsed = 0;
    for (;;) {
        if ((ret = wv_read_block_header(s, pb)) < 0)
            return ret;
        if (!wc->header.samples)
            avio_skip(pb, wc->header.blocksize);
        else
            break;
    }

    /* now we are ready: build format streams */
    st = avformat_new_stream(s, NULL);
    if (!st)
        return AVERROR(ENOMEM);
    if ((ret = ff_alloc_extradata(st->codecpar, 2)) < 0)
        return ret;
    AV_WL16(st->codecpar->extradata, wc->header.version);
    st->codecpar->codec_type            = AVMEDIA_TYPE_AUDIO;
    st->codecpar->codec_id              = AV_CODEC_ID_WAVPACK;
    st->codecpar->channels              = wc->chan;
    st->codecpar->channel_layout        = wc->chmask;
    st->codecpar->sample_rate           = wc->rate;
    st->codecpar->bits_per_coded_sample = wc->bpp;
    avpriv_set_pts_info(st, 64, 1, wc->rate);
    st->start_time = 0;
    if (wc->header.total_samples != 0xFFFFFFFFu)
        st->duration = wc->header.total_samples;

    if (s->pb->seekable & AVIO_SEEKABLE_NORMAL) {
        int64_t cur = avio_tell(s->pb);
        wc->apetag_start = ff_ape_parse_tag(s);
        if (!av_dict_get(s->metadata, "", NULL, AV_DICT_IGNORE_SUFFIX))
            ff_id3v1_read(s);
        avio_seek(s->pb, cur, SEEK_SET);
    }

    return 0;
}

static int wv_read_packet(AVFormatContext *s, AVPacket *pkt)
{
    WVContext *wc = s->priv_data;
    int ret;
    int off;
    int64_t pos;
    uint32_t block_samples;

    if (avio_feof(s->pb))
        return AVERROR_EOF;
    if (wc->block_parsed) {
        if ((ret = wv_read_block_header(s, s->pb)) < 0)
            return ret;
    }

    pos = wc->pos;
    if ((ret = av_new_packet(pkt, wc->header.blocksize + WV_HEADER_SIZE)) < 0)
        return ret;
    memcpy(pkt->data, wc->block_header, WV_HEADER_SIZE);
    ret = avio_read(s->pb, pkt->data + WV_HEADER_SIZE, wc->header.blocksize);
    if (ret != wc->header.blocksize) {
        return AVERROR(EIO);
    }
    while (!(wc->header.flags & WV_FLAG_FINAL_BLOCK)) {
        if ((ret = wv_read_block_header(s, s->pb)) < 0) {
            return ret;
        }

        off = pkt->size;
        if ((ret = av_grow_packet(pkt, WV_HEADER_SIZE + wc->header.blocksize)) < 0) {
            return ret;
        }
        memcpy(pkt->data + off, wc->block_header, WV_HEADER_SIZE);

        ret = avio_read(s->pb, pkt->data + off + WV_HEADER_SIZE, wc->header.blocksize);
        if (ret != wc->header.blocksize) {
            return (ret < 0) ? ret : AVERROR_EOF;
        }
    }
    pkt->stream_index = 0;
    pkt->pos          = pos;
    wc->block_parsed  = 1;
    pkt->pts          = wc->header.block_idx;
    block_samples     = wc->header.samples;
    if (block_samples > INT32_MAX)
        av_log(s, AV_LOG_WARNING,
               "Too many samples in block: %"PRIu32"\n", block_samples);
    else
        pkt->duration = block_samples;

    return 0;
}

AVInputFormat ff_wv_demuxer = {
    .name           = "wv",
    .long_name      = NULL_IF_CONFIG_SMALL("WavPack"),
    .priv_data_size = sizeof(WVContext),
    .read_probe     = wv_probe,
    .read_header    = wv_read_header,
    .read_packet    = wv_read_packet,
    .flags          = AVFMT_GENERIC_INDEX,
};
