/*
 * Animated GIF muxer
 * Copyright (c) 2000 Fabrice Bellard
 *
 * first version by Francois Revol <revol@free.fr>
 *
 * 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 "avformat.h"
#include "internal.h"
#include "libavutil/avassert.h"
#include "libavutil/imgutils.h"
#include "libavutil/log.h"
#include "libavutil/opt.h"

/* XXX: random value that shouldn't be taken into effect if there is no
 * transparent color in the palette (the transparency bit will be set to 0) */
#define DEFAULT_TRANSPARENCY_INDEX 0x1f

static int get_palette_transparency_index(const uint32_t *palette)
{
    int transparent_color_index = -1;
    unsigned i, smallest_alpha = 0xff;

    if (!palette)
        return -1;

    for (i = 0; i < AVPALETTE_COUNT; i++) {
        const uint32_t v = palette[i];
        if (v >> 24 < smallest_alpha) {
            smallest_alpha = v >> 24;
            transparent_color_index = i;
        }
    }
    return smallest_alpha < 128 ? transparent_color_index : -1;
}

static int gif_image_write_header(AVIOContext *pb, const AVCodecContext *avctx,
                                  int loop_count, uint32_t *palette)
{
    int i;
    int64_t aspect = 0;
    const AVRational sar = avctx->sample_aspect_ratio;

    if (sar.num > 0 && sar.den > 0) {
        aspect = sar.num * 64LL / sar.den - 15;
        if (aspect < 0 || aspect > 255)
            aspect = 0;
    }

    avio_write(pb, "GIF", 3);
    avio_write(pb, "89a", 3);
    avio_wl16(pb, avctx->width);
    avio_wl16(pb, avctx->height);

    if (palette) {
        const int bcid = get_palette_transparency_index(palette);

        avio_w8(pb, 0xf7); /* flags: global clut, 256 entries */
        avio_w8(pb, bcid < 0 ? DEFAULT_TRANSPARENCY_INDEX : bcid); /* background color index */
        avio_w8(pb, aspect);
        for (i = 0; i < 256; i++) {
            const uint32_t v = palette[i] & 0xffffff;
            avio_wb24(pb, v);
        }
    } else {
        avio_w8(pb, 0); /* flags */
        avio_w8(pb, 0); /* background color index */
        avio_w8(pb, aspect);
    }


    if (loop_count >= 0 ) {
        /* "NETSCAPE EXTENSION" for looped animation GIF */
        avio_w8(pb, 0x21); /* GIF Extension code */
        avio_w8(pb, 0xff); /* Application Extension Label */
        avio_w8(pb, 0x0b); /* Length of Application Block */
        avio_write(pb, "NETSCAPE2.0", sizeof("NETSCAPE2.0") - 1);
        avio_w8(pb, 0x03); /* Length of Data Sub-Block */
        avio_w8(pb, 0x01);
        avio_wl16(pb, (uint16_t)loop_count);
        avio_w8(pb, 0x00); /* Data Sub-block Terminator */
    }

    avio_flush(pb);
    return 0;
}

typedef struct GIFContext {
    AVClass *class;
    int loop;
    int last_delay;
    AVPacket *prev_pkt;
    int duration;
} GIFContext;

static int gif_write_header(AVFormatContext *s)
{
    GIFContext *gif = s->priv_data;
    AVCodecContext *video_enc;
    uint32_t palette[AVPALETTE_COUNT];

    if (s->nb_streams != 1 ||
        s->streams[0]->codec->codec_type != AVMEDIA_TYPE_VIDEO ||
        s->streams[0]->codec->codec_id   != AV_CODEC_ID_GIF) {
        av_log(s, AV_LOG_ERROR,
               "GIF muxer supports only a single video GIF stream.\n");
        return AVERROR(EINVAL);
    }

    video_enc = s->streams[0]->codec;

    avpriv_set_pts_info(s->streams[0], 64, 1, 100);
    if (avpriv_set_systematic_pal2(palette, video_enc->pix_fmt) < 0) {
        av_assert0(video_enc->pix_fmt == AV_PIX_FMT_PAL8);
        /* delay header writing: we wait for the first palette to put it
         * globally */
    } else {
        gif_image_write_header(s->pb, video_enc, gif->loop, palette);
    }

    return 0;
}

static int flush_packet(AVFormatContext *s, AVPacket *new)
{
    GIFContext *gif = s->priv_data;
    int size, bcid;
    AVIOContext *pb = s->pb;
    const uint32_t *palette;
    AVPacket *pkt = gif->prev_pkt;

    if (!pkt)
        return 0;

    /* Mark one colour as transparent if the input palette contains at least
     * one colour that is more than 50% transparent. */
    palette = (uint32_t*)av_packet_get_side_data(pkt, AV_PKT_DATA_PALETTE, &size);
    if (palette && size != AVPALETTE_SIZE) {
        av_log(s, AV_LOG_ERROR, "Invalid palette extradata\n");
        return AVERROR_INVALIDDATA;
    }
    bcid = get_palette_transparency_index(palette);

    if (new && new->pts != AV_NOPTS_VALUE)
        gif->duration = av_clip_uint16(new->pts - gif->prev_pkt->pts);
    else if (!new && gif->last_delay >= 0)
        gif->duration = gif->last_delay;

    /* graphic control extension block */
    avio_w8(pb, 0x21);
    avio_w8(pb, 0xf9);
    avio_w8(pb, 0x04); /* block size */
    avio_w8(pb, 1<<2 | (bcid >= 0));
    avio_wl16(pb, gif->duration);
    avio_w8(pb, bcid < 0 ? DEFAULT_TRANSPARENCY_INDEX : bcid);
    avio_w8(pb, 0x00);

    avio_write(pb, pkt->data, pkt->size);

    av_free_packet(gif->prev_pkt);
    if (new)
        av_copy_packet(gif->prev_pkt, new);

    return 0;
}

static int gif_write_packet(AVFormatContext *s, AVPacket *pkt)
{
    GIFContext *gif = s->priv_data;
    const AVCodecContext *video_enc = s->streams[0]->codec;

    if (!gif->prev_pkt) {
        gif->prev_pkt = av_malloc(sizeof(*gif->prev_pkt));
        if (!gif->prev_pkt)
            return AVERROR(ENOMEM);

        /* Write the first palette as global palette */
        if (video_enc->pix_fmt == AV_PIX_FMT_PAL8) {
            int size;
            void *palette = av_packet_get_side_data(pkt, AV_PKT_DATA_PALETTE, &size);

            if (!palette) {
                av_log(s, AV_LOG_ERROR, "PAL8 packet is missing palette in extradata\n");
                return AVERROR_INVALIDDATA;
            }
            if (size != AVPALETTE_SIZE) {
                av_log(s, AV_LOG_ERROR, "Invalid palette extradata\n");
                return AVERROR_INVALIDDATA;
            }
            gif_image_write_header(s->pb, video_enc, gif->loop, palette);
        }

        return av_copy_packet(gif->prev_pkt, pkt);
    }
    return flush_packet(s, pkt);
}

static int gif_write_trailer(AVFormatContext *s)
{
    GIFContext *gif = s->priv_data;
    AVIOContext *pb = s->pb;

    flush_packet(s, NULL);
    av_freep(&gif->prev_pkt);
    avio_w8(pb, 0x3b);

    return 0;
}

#define OFFSET(x) offsetof(GIFContext, x)
#define ENC AV_OPT_FLAG_ENCODING_PARAM
static const AVOption options[] = {
    { "loop", "Number of times to loop the output: -1 - no loop, 0 - infinite loop", OFFSET(loop),
      AV_OPT_TYPE_INT, { .i64 = 0 }, -1, 65535, ENC },
    { "final_delay", "Force delay (in centiseconds) after the last frame", OFFSET(last_delay),
      AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 65535, ENC },
    { NULL },
};

static const AVClass gif_muxer_class = {
    .class_name = "GIF muxer",
    .item_name  = av_default_item_name,
    .version    = LIBAVUTIL_VERSION_INT,
    .option     = options,
};

AVOutputFormat ff_gif_muxer = {
    .name           = "gif",
    .long_name      = NULL_IF_CONFIG_SMALL("GIF Animation"),
    .mime_type      = "image/gif",
    .extensions     = "gif",
    .priv_data_size = sizeof(GIFContext),
    .audio_codec    = AV_CODEC_ID_NONE,
    .video_codec    = AV_CODEC_ID_GIF,
    .write_header   = gif_write_header,
    .write_packet   = gif_write_packet,
    .write_trailer  = gif_write_trailer,
    .priv_class     = &gif_muxer_class,
    .flags          = AVFMT_VARIABLE_FPS,
};
