/*
 * DVD subtitle encoding
 * Copyright (c) 2005 Wolfram Gloger
 *
 * 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 "internal.h"
#include "libavutil/avassert.h"
#include "libavutil/bprint.h"
#include "libavutil/imgutils.h"
#include "libavutil/opt.h"

typedef struct {
    AVClass *class;
    uint32_t global_palette[16];
    int even_rows_fix;
} DVDSubtitleContext;

// ncnt is the nibble counter
#define PUTNIBBLE(val)\
do {\
    if (ncnt++ & 1)\
        *q++ = bitbuf | ((val) & 0x0f);\
    else\
        bitbuf = (val) << 4;\
} while(0)

static void dvd_encode_rle(uint8_t **pq,
                           const uint8_t *bitmap, int linesize,
                           int w, int h,
                           const int cmap[256])
{
    uint8_t *q;
    unsigned int bitbuf = 0;
    int ncnt;
    int x, y, len, color;

    q = *pq;

    for (y = 0; y < h; ++y) {
        ncnt = 0;
        for(x = 0; x < w; x += len) {
            color = bitmap[x];
            for (len=1; x+len < w; ++len)
                if (bitmap[x+len] != color)
                    break;
            color = cmap[color];
            av_assert0(color < 4);
            if (len < 0x04) {
                PUTNIBBLE((len << 2)|color);
            } else if (len < 0x10) {
                PUTNIBBLE(len >> 2);
                PUTNIBBLE((len << 2)|color);
            } else if (len < 0x40) {
                PUTNIBBLE(0);
                PUTNIBBLE(len >> 2);
                PUTNIBBLE((len << 2)|color);
            } else if (x+len == w) {
                PUTNIBBLE(0);
                PUTNIBBLE(0);
                PUTNIBBLE(0);
                PUTNIBBLE(color);
            } else {
                if (len > 0xff)
                    len = 0xff;
                PUTNIBBLE(0);
                PUTNIBBLE(len >> 6);
                PUTNIBBLE(len >> 2);
                PUTNIBBLE((len << 2)|color);
            }
        }
        /* end of line */
        if (ncnt & 1)
            PUTNIBBLE(0);
        bitmap += linesize;
    }

    *pq = q;
}

static int color_distance(uint32_t a, uint32_t b)
{
    int r = 0, d, i;
    int alpha_a = 8, alpha_b = 8;

    for (i = 24; i >= 0; i -= 8) {
        d = alpha_a * (int)((a >> i) & 0xFF) -
            alpha_b * (int)((b >> i) & 0xFF);
        r += d * d;
        alpha_a = a >> 28;
        alpha_b = b >> 28;
    }
    return r;
}

/**
 * Count colors used in a rectangle, quantizing alpha and grouping by
 * nearest global palette entry.
 */
static void count_colors(AVCodecContext *avctx, unsigned hits[33],
                         const AVSubtitleRect *r)
{
    DVDSubtitleContext *dvdc = avctx->priv_data;
    unsigned count[256] = { 0 };
    uint32_t *palette = (uint32_t *)r->pict.data[1];
    uint32_t color;
    int x, y, i, j, match, d, best_d, av_uninit(best_j);
    uint8_t *p = r->pict.data[0];

    for (y = 0; y < r->h; y++) {
        for (x = 0; x < r->w; x++)
            count[*(p++)]++;
        p += r->pict.linesize[0] - r->w;
    }
    for (i = 0; i < 256; i++) {
        if (!count[i]) /* avoid useless search */
            continue;
        color = palette[i];
        /* 0: transparent, 1-16: semi-transparent, 17-33 opaque */
        match = color < 0x33000000 ? 0 : color < 0xCC000000 ? 1 : 17;
        if (match) {
            best_d = INT_MAX;
            for (j = 0; j < 16; j++) {
                d = color_distance(0xFF000000 | color,
                                   0xFF000000 | dvdc->global_palette[j]);
                if (d < best_d) {
                    best_d = d;
                    best_j = j;
                }
            }
            match += best_j;
        }
        hits[match] += count[i];
    }
}

static void select_palette(AVCodecContext *avctx, int out_palette[4],
                           int out_alpha[4], unsigned hits[33])
{
    DVDSubtitleContext *dvdc = avctx->priv_data;
    int i, j, bright, mult;
    uint32_t color;
    int selected[4] = { 0 };
    uint32_t pseudopal[33] = { 0 };
    uint32_t refcolor[3] = { 0x00000000, 0xFFFFFFFF, 0xFF000000 };

    /* Bonus for transparent: if the rectangle fits tightly the text, the
       background color can be quite rare, but it would be ugly without it */
    hits[0] *= 16;
    /* Bonus for bright colors */
    for (i = 0; i < 16; i++) {
        if (!(hits[1 + i] + hits[17 + i]))
            continue; /* skip unused colors to gain time */
        color = dvdc->global_palette[i];
        bright = 0;
        for (j = 0; j < 3; j++, color >>= 8)
            bright += (color & 0xFF) < 0x40 || (color & 0xFF) >= 0xC0;
        mult = 2 + FFMIN(bright, 2);
        hits[ 1 + i] *= mult;
        hits[17 + i] *= mult;
    }

    /* Select four most frequent colors */
    for (i = 0; i < 4; i++) {
        for (j = 0; j < 33; j++)
            if (hits[j] > hits[selected[i]])
                selected[i] = j;
        hits[selected[i]] = 0;
    }

    /* Order the colors like in most DVDs:
       0: background, 1: foreground, 2: outline */
    for (i = 0; i < 16; i++) {
        pseudopal[ 1 + i] = 0x80000000 | dvdc->global_palette[i];
        pseudopal[17 + i] = 0xFF000000 | dvdc->global_palette[i];
    }
    for (i = 0; i < 3; i++) {
        int best_d = color_distance(refcolor[i], pseudopal[selected[i]]);
        for (j = i + 1; j < 4; j++) {
            int d = color_distance(refcolor[i], pseudopal[selected[j]]);
            if (d < best_d) {
                FFSWAP(int, selected[i], selected[j]);
                best_d = d;
            }
        }
    }

    /* Output */
    for (i = 0; i < 4; i++) {
        out_palette[i] = selected[i] ? (selected[i] - 1) & 0xF : 0;
        out_alpha  [i] = !selected[i] ? 0 : selected[i] < 17 ? 0x80 : 0xFF;
    }
}

static void build_color_map(AVCodecContext *avctx, int cmap[],
                            const uint32_t palette[],
                            const int out_palette[], unsigned int const out_alpha[])
{
    DVDSubtitleContext *dvdc = avctx->priv_data;
    int i, j, d, best_d;
    uint32_t pseudopal[4];

    for (i = 0; i < 4; i++)
        pseudopal[i] = (out_alpha[i] << 24) |
                       dvdc->global_palette[out_palette[i]];
    for (i = 0; i < 256; i++) {
        best_d = INT_MAX;
        for (j = 0; j < 4; j++) {
            d = color_distance(pseudopal[j], palette[i]);
            if (d < best_d) {
                cmap[i] = j;
                best_d = d;
            }
        }
    }
}

static void copy_rectangle(AVSubtitleRect *dst, AVSubtitleRect *src, int cmap[])
{
    int x, y;
    uint8_t *p, *q;

    p = src->pict.data[0];
    q = dst->pict.data[0] + (src->x - dst->x) +
                            (src->y - dst->y) * dst->pict.linesize[0];
    for (y = 0; y < src->h; y++) {
        for (x = 0; x < src->w; x++)
            *(q++) = cmap[*(p++)];
        p += src->pict.linesize[0] - src->w;
        q += dst->pict.linesize[0] - src->w;
    }
}

static int encode_dvd_subtitles(AVCodecContext *avctx,
                                uint8_t *outbuf, int outbuf_size,
                                const AVSubtitle *h)
{
    DVDSubtitleContext *dvdc = avctx->priv_data;
    uint8_t *q, *qq;
    int offset1, offset2;
    int i, rects = h->num_rects, ret;
    unsigned global_palette_hits[33] = { 0 };
    int cmap[256];
    int out_palette[4];
    int out_alpha[4];
    AVSubtitleRect vrect;
    uint8_t *vrect_data = NULL;
    int x2, y2;
    int forced = 0;

    if (rects == 0 || !h->rects)
        return AVERROR(EINVAL);
    for (i = 0; i < rects; i++)
        if (h->rects[i]->type != SUBTITLE_BITMAP) {
            av_log(avctx, AV_LOG_ERROR, "Bitmap subtitle required\n");
            return AVERROR(EINVAL);
        }
    /* Mark this subtitle forced if any of the rectangles is forced. */
    for (i = 0; i < rects; i++)
        if ((h->rects[i]->flags & AV_SUBTITLE_FLAG_FORCED) != 0) {
            forced = 1;
            break;
        }
    vrect = *h->rects[0];

    if (rects > 1) {
        /* DVD subtitles can have only one rectangle: build a virtual
           rectangle containing all actual rectangles.
           The data of the rectangles will be copied later, when the palette
           is decided, because the rectangles may have different palettes. */
        int xmin = h->rects[0]->x, xmax = xmin + h->rects[0]->w;
        int ymin = h->rects[0]->y, ymax = ymin + h->rects[0]->h;
        for (i = 1; i < rects; i++) {
            xmin = FFMIN(xmin, h->rects[i]->x);
            ymin = FFMIN(ymin, h->rects[i]->y);
            xmax = FFMAX(xmax, h->rects[i]->x + h->rects[i]->w);
            ymax = FFMAX(ymax, h->rects[i]->y + h->rects[i]->h);
        }
        vrect.x = xmin;
        vrect.y = ymin;
        vrect.w = xmax - xmin;
        vrect.h = ymax - ymin;
        if ((ret = av_image_check_size(vrect.w, vrect.h, 0, avctx)) < 0)
            return ret;

        /* Count pixels outside the virtual rectangle as transparent */
        global_palette_hits[0] = vrect.w * vrect.h;
        for (i = 0; i < rects; i++)
            global_palette_hits[0] -= h->rects[i]->w * h->rects[i]->h;
    }

    for (i = 0; i < rects; i++)
        count_colors(avctx, global_palette_hits, h->rects[i]);
    select_palette(avctx, out_palette, out_alpha, global_palette_hits);

    if (rects > 1) {
        if (!(vrect_data = av_calloc(vrect.w, vrect.h)))
            return AVERROR(ENOMEM);
        vrect.pict.data    [0] = vrect_data;
        vrect.pict.linesize[0] = vrect.w;
        for (i = 0; i < rects; i++) {
            build_color_map(avctx, cmap, (uint32_t *)h->rects[i]->pict.data[1],
                            out_palette, out_alpha);
            copy_rectangle(&vrect, h->rects[i], cmap);
        }
        for (i = 0; i < 4; i++)
            cmap[i] = i;
    } else {
        build_color_map(avctx, cmap, (uint32_t *)h->rects[0]->pict.data[1],
                        out_palette, out_alpha);
    }

    av_log(avctx, AV_LOG_DEBUG, "Selected palette:");
    for (i = 0; i < 4; i++)
        av_log(avctx, AV_LOG_DEBUG, " 0x%06x@@%02x (0x%x,0x%x)",
               dvdc->global_palette[out_palette[i]], out_alpha[i],
               out_palette[i], out_alpha[i] >> 4);
    av_log(avctx, AV_LOG_DEBUG, "\n");

    // encode data block
    q = outbuf + 4;
    offset1 = q - outbuf;
    // worst case memory requirement: 1 nibble per pixel..
    if ((q - outbuf) + vrect.w * vrect.h / 2 + 17 + 21 > outbuf_size) {
        av_log(NULL, AV_LOG_ERROR, "dvd_subtitle too big\n");
        ret = AVERROR_BUFFER_TOO_SMALL;
        goto fail;
    }
    dvd_encode_rle(&q, vrect.pict.data[0], vrect.w * 2,
                   vrect.w, (vrect.h + 1) >> 1, cmap);
    offset2 = q - outbuf;
    dvd_encode_rle(&q, vrect.pict.data[0] + vrect.w, vrect.w * 2,
                   vrect.w, vrect.h >> 1, cmap);

    if (dvdc->even_rows_fix && (vrect.h & 1)) {
        // Work-around for some players that want the height to be even.
        vrect.h++;
        *q++ = 0x00; // 0x00 0x00 == empty row, i.e. fully transparent
        *q++ = 0x00;
    }

    // set data packet size
    qq = outbuf + 2;
    bytestream_put_be16(&qq, q - outbuf);

    // send start display command
    bytestream_put_be16(&q, (h->start_display_time*90) >> 10);
    bytestream_put_be16(&q, (q - outbuf) /*- 2 */ + 8 + 12 + 2);
    *q++ = 0x03; // palette - 4 nibbles
    *q++ = (out_palette[3] << 4) | out_palette[2];
    *q++ = (out_palette[1] << 4) | out_palette[0];
    *q++ = 0x04; // alpha - 4 nibbles
    *q++ = (out_alpha[3] & 0xF0) | (out_alpha[2] >> 4);
    *q++ = (out_alpha[1] & 0xF0) | (out_alpha[0] >> 4);

    // 12 bytes per rect
    x2 = vrect.x + vrect.w - 1;
    y2 = vrect.y + vrect.h - 1;

    *q++ = 0x05;
    // x1 x2 -> 6 nibbles
    *q++ = vrect.x >> 4;
    *q++ = (vrect.x << 4) | ((x2 >> 8) & 0xf);
    *q++ = x2;
    // y1 y2 -> 6 nibbles
    *q++ = vrect.y >> 4;
    *q++ = (vrect.y << 4) | ((y2 >> 8) & 0xf);
    *q++ = y2;

    *q++ = 0x06;
    // offset1, offset2
    bytestream_put_be16(&q, offset1);
    bytestream_put_be16(&q, offset2);

    *q++ = forced ? 0x00 : 0x01; // start command
    *q++ = 0xff; // terminating command

    // send stop display command last
    bytestream_put_be16(&q, (h->end_display_time*90) >> 10);
    bytestream_put_be16(&q, (q - outbuf) - 2 /*+ 4*/);
    *q++ = 0x02; // set end
    *q++ = 0xff; // terminating command

    qq = outbuf;
    bytestream_put_be16(&qq, q - outbuf);

    av_log(NULL, AV_LOG_DEBUG, "subtitle_packet size=%"PTRDIFF_SPECIFIER"\n", q - outbuf);
    ret = q - outbuf;

fail:
    av_free(vrect_data);
    return ret;
}

static int dvdsub_init(AVCodecContext *avctx)
{
    DVDSubtitleContext *dvdc = avctx->priv_data;
    static const uint32_t default_palette[16] = {
        0x000000, 0x0000FF, 0x00FF00, 0xFF0000,
        0xFFFF00, 0xFF00FF, 0x00FFFF, 0xFFFFFF,
        0x808000, 0x8080FF, 0x800080, 0x80FF80,
        0x008080, 0xFF8080, 0x555555, 0xAAAAAA,
    };
    AVBPrint extradata;
    int i, ret;

    av_assert0(sizeof(dvdc->global_palette) == sizeof(default_palette));
    memcpy(dvdc->global_palette, default_palette, sizeof(dvdc->global_palette));

    av_bprint_init(&extradata, 0, 1);
    if (avctx->width && avctx->height)
        av_bprintf(&extradata, "size: %dx%d\n", avctx->width, avctx->height);
    av_bprintf(&extradata, "palette:");
    for (i = 0; i < 16; i++)
        av_bprintf(&extradata, " %06"PRIx32"%c",
                   dvdc->global_palette[i] & 0xFFFFFF, i < 15 ? ',' : '\n');

    ret = avpriv_bprint_to_extradata(avctx, &extradata);
    if (ret < 0)
        return ret;

    return 0;
}

static int dvdsub_encode(AVCodecContext *avctx,
                         unsigned char *buf, int buf_size,
                         const AVSubtitle *sub)
{
    //DVDSubtitleContext *s = avctx->priv_data;
    int ret;

    ret = encode_dvd_subtitles(avctx, buf, buf_size, sub);
    return ret;
}

#define OFFSET(x) offsetof(DVDSubtitleContext, x)
#define SE AV_OPT_FLAG_SUBTITLE_PARAM | AV_OPT_FLAG_ENCODING_PARAM
static const AVOption options[] = {
    {"even_rows_fix", "Make number of rows even (workaround for some players)", OFFSET(even_rows_fix), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, SE},
    { NULL },
};

static const AVClass dvdsubenc_class = {
    .class_name = "VOBSUB subtitle encoder",
    .item_name  = av_default_item_name,
    .option     = options,
    .version    = LIBAVUTIL_VERSION_INT,
};

AVCodec ff_dvdsub_encoder = {
    .name           = "dvdsub",
    .long_name      = NULL_IF_CONFIG_SMALL("DVD subtitles"),
    .type           = AVMEDIA_TYPE_SUBTITLE,
    .id             = AV_CODEC_ID_DVD_SUBTITLE,
    .init           = dvdsub_init,
    .encode_sub     = dvdsub_encode,
    .priv_class     = &dvdsubenc_class,
    .priv_data_size = sizeof(DVDSubtitleContext),
};
