/*
 * DivX (XSUB) subtitle encoder
 * Copyright (c) 2005 DivX, Inc.
 * Copyright (c) 2009 Bjorn Axelsson
 *
 * 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 "avcodec.h"
#include "bytestream.h"
#include "put_bits.h"

/**
 * Number of pixels to pad left and right.
 *
 * The official encoder pads the subtitles with two pixels on either side,
 * but until we find out why, we won't do it (we will pad to have width
 * divisible by 2 though).
 */
#define PADDING 0
#define PADDING_COLOR 0

/**
 * Encode a single color run. At most 16 bits will be used.
 * @param len   length of the run, values > 255 mean "until end of line", may not be < 0.
 * @param color color to encode, only the lowest two bits are used and all others must be 0.
 */
static void put_xsub_rle(PutBitContext *pb, int len, int color)
{
    if (len <= 255)
        put_bits(pb, 2 + ((ff_log2_tab[len] >> 1) << 2), len);
    else
        put_bits(pb, 14, 0);
    put_bits(pb, 2, color);
}

/**
 * Encode a 4-color bitmap with XSUB rle.
 *
 * The encoded bitmap may be wider than the source bitmap due to padding.
 */
static int xsub_encode_rle(PutBitContext *pb, const uint8_t *bitmap,
                           int linesize, int w, int h)
{
    int x0, x1, y, len, color = PADDING_COLOR;

    for (y = 0; y < h; y++) {
        x0 = 0;
        while (x0 < w) {
            // Make sure we have enough room for at least one run and padding
            if (pb->size_in_bits - put_bits_count(pb) < 7*8)
                return -1;

            x1 = x0;
            color = bitmap[x1++] & 3;
            while (x1 < w && (bitmap[x1] & 3) == color)
                x1++;
            len = x1 - x0;
            if (PADDING && x0 == 0) {
                if (color == PADDING_COLOR) {
                    len += PADDING;
                    x0  -= PADDING;
                } else
                    put_xsub_rle(pb, PADDING, PADDING_COLOR);
            }

            // Run can't be longer than 255, unless it is the rest of a row
            if (x1 == w && color == PADDING_COLOR) {
                len += PADDING + (w&1);
            } else
                len = FFMIN(len, 255);
            put_xsub_rle(pb, len, color);

            x0 += len;
        }
        if (color != PADDING_COLOR && (PADDING + (w&1)))
            put_xsub_rle(pb, PADDING + (w&1), PADDING_COLOR);

        avpriv_align_put_bits(pb);

        bitmap += linesize;
    }

    return 0;
}

static int make_tc(uint64_t ms, int *tc)
{
    static const int tc_divs[3] = { 1000, 60, 60 };
    int i;
    for (i=0; i<3; i++) {
        tc[i] = ms % tc_divs[i];
        ms /= tc_divs[i];
    }
    tc[3] = ms;
    return ms > 99;
}

static int xsub_encode(AVCodecContext *avctx, unsigned char *buf,
                       int bufsize, const AVSubtitle *h)
{
    uint64_t startTime = h->pts / 1000; // FIXME: need better solution...
    uint64_t endTime = startTime + h->end_display_time - h->start_display_time;
    int start_tc[4], end_tc[4];
    uint8_t *hdr = buf + 27; // Point behind the timestamp
    uint8_t *rlelenptr;
    uint16_t width, height;
    int i;
    PutBitContext pb;

    if (bufsize < 27 + 7*2 + 4*3) {
        av_log(avctx, AV_LOG_ERROR, "Buffer too small for XSUB header.\n");
        return -1;
    }

    // TODO: support multiple rects
    if (h->num_rects != 1)
        av_log(avctx, AV_LOG_WARNING, "Only single rects supported (%d in subtitle.)\n", h->num_rects);

#if FF_API_AVPICTURE
FF_DISABLE_DEPRECATION_WARNINGS
    if (!h->rects[0]->data[0]) {
        AVSubtitleRect *rect = h->rects[0];
        int j;
        for (j = 0; j < 4; j++) {
            rect->data[j] = rect->pict.data[j];
            rect->linesize[j] = rect->pict.linesize[j];
        }
    }
FF_ENABLE_DEPRECATION_WARNINGS
#endif

    // TODO: render text-based subtitles into bitmaps
    if (!h->rects[0]->data[0] || !h->rects[0]->data[1]) {
        av_log(avctx, AV_LOG_WARNING, "No subtitle bitmap available.\n");
        return -1;
    }

    // TODO: color reduction, similar to dvdsub encoder
    if (h->rects[0]->nb_colors > 4)
        av_log(avctx, AV_LOG_WARNING, "No more than 4 subtitle colors supported (%d found.)\n", h->rects[0]->nb_colors);

    // TODO: Palette swapping if color zero is not transparent
    if (((uint32_t *)h->rects[0]->data[1])[0] & 0xff000000)
        av_log(avctx, AV_LOG_WARNING, "Color index 0 is not transparent. Transparency will be messed up.\n");

    if (make_tc(startTime, start_tc) || make_tc(endTime, end_tc)) {
        av_log(avctx, AV_LOG_WARNING, "Time code >= 100 hours.\n");
        return -1;
    }

    snprintf(buf, 28,
        "[%02d:%02d:%02d.%03d-%02d:%02d:%02d.%03d]",
        start_tc[3], start_tc[2], start_tc[1], start_tc[0],
        end_tc[3],   end_tc[2],   end_tc[1],   end_tc[0]);

    // Width and height must probably be multiples of 2.
    // 2 pixels required on either side of subtitle.
    // Possibly due to limitations of hardware renderers.
    // TODO: check if the bitmap is already padded
    width  = FFALIGN(h->rects[0]->w, 2) + PADDING * 2;
    height = FFALIGN(h->rects[0]->h, 2);

    bytestream_put_le16(&hdr, width);
    bytestream_put_le16(&hdr, height);
    bytestream_put_le16(&hdr, h->rects[0]->x);
    bytestream_put_le16(&hdr, h->rects[0]->y);
    bytestream_put_le16(&hdr, h->rects[0]->x + width -1);
    bytestream_put_le16(&hdr, h->rects[0]->y + height -1);

    rlelenptr = hdr; // Will store length of first field here later.
    hdr+=2;

    // Palette
    for (i=0; i<4; i++)
        bytestream_put_be24(&hdr, ((uint32_t *)h->rects[0]->data[1])[i]);

    // Bitmap
    // RLE buffer. Reserve 2 bytes for possible padding after the last row.
    init_put_bits(&pb, hdr, bufsize - (hdr - buf) - 2);
    if (xsub_encode_rle(&pb, h->rects[0]->data[0],
                        h->rects[0]->linesize[0] * 2,
                        h->rects[0]->w, (h->rects[0]->h + 1) >> 1))
        return -1;
    bytestream_put_le16(&rlelenptr, put_bits_count(&pb) >> 3); // Length of first field

    if (xsub_encode_rle(&pb, h->rects[0]->data[0] + h->rects[0]->linesize[0],
                        h->rects[0]->linesize[0] * 2,
                        h->rects[0]->w, h->rects[0]->h >> 1))
        return -1;

    // Enforce total height to be a multiple of 2
    if (h->rects[0]->h & 1) {
        put_xsub_rle(&pb, h->rects[0]->w, PADDING_COLOR);
        avpriv_align_put_bits(&pb);
    }

    flush_put_bits(&pb);

    return hdr - buf + put_bits_count(&pb)/8;
}

static av_cold int xsub_encoder_init(AVCodecContext *avctx)
{
    if (!avctx->codec_tag)
        avctx->codec_tag = MKTAG('D','X','S','B');

    avctx->bits_per_coded_sample = 4;

    return 0;
}

AVCodec ff_xsub_encoder = {
    .name       = "xsub",
    .long_name  = NULL_IF_CONFIG_SMALL("DivX subtitles (XSUB)"),
    .type       = AVMEDIA_TYPE_SUBTITLE,
    .id         = AV_CODEC_ID_XSUB,
    .init       = xsub_encoder_init,
    .encode_sub = xsub_encode,
};
