/*
 * 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];
    char *palette_str;
    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->data[1];
    uint32_t color;
    int x, y, i, j, match, d, best_d, av_uninit(best_j);
    uint8_t *p = r->data[0];

    for (y = 0; y < r->h; y++) {
        for (x = 0; x < r->w; x++)
            count[*(p++)]++;
        p += r->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->data[0];
    q = dst->data[0] + (src->x - dst->x) +
                            (src->y - dst->y) * dst->linesize[0];
    for (y = 0; y < src->h; y++) {
        for (x = 0; x < src->w; x++)
            *(q++) = cmap[*(p++)];
        p += src->linesize[0] - src->w;
        q += dst->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;
        }

#if FF_API_AVPICTURE
FF_DISABLE_DEPRECATION_WARNINGS
    for (i = 0; i < rects; i++)
        if (!h->rects[i]->data[0]) {
            AVSubtitleRect *rect = h->rects[i];
            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

    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.data    [0] = vrect_data;
        vrect.linesize[0] = vrect.w;
        for (i = 0; i < rects; i++) {
            build_color_map(avctx, cmap, (uint32_t *)h->rects[i]->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]->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%06"PRIx32"@@%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.data[0], vrect.w * 2,
                   vrect.w, (vrect.h + 1) >> 1, cmap);
    offset2 = q - outbuf;
    dvd_encode_rle(&q, vrect.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));
    if (dvdc->palette_str) {
        ff_dvdsub_parse_palette(dvdc->global_palette, dvdc->palette_str);
    } else {
        memcpy(dvdc->global_palette, default_palette, sizeof(dvdc->global_palette));
    }

    av_bprint_init(&extradata, 0, AV_BPRINT_SIZE_AUTOMATIC);
    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[] = {
    {"palette", "set the global palette", OFFSET(palette_str), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, SE },
    {"even_rows_fix", "Make number of rows even (workaround for some players)", OFFSET(even_rows_fix), AV_OPT_TYPE_BOOL, {.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),
};
