/*
 * 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->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%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.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));
    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_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),
};
