/*
 * DVD subtitle encoding for ffmpeg
 * 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"

#undef NDEBUG
#include <assert.h>

// 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];
            assert(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 encode_dvd_subtitles(uint8_t *outbuf, int outbuf_size,
                                const AVSubtitle *h)
{
    uint8_t *q, *qq;
    int object_id;
    int offset1[20], offset2[20];
    int i, imax, color, alpha, rects = h->num_rects;
    unsigned long hmax;
    unsigned long hist[256];
    int           cmap[256];

    if (rects == 0 || h->rects == NULL)
        return -1;
    if (rects > 20)
        rects = 20;

    // analyze bitmaps, compress to 4 colors
    for (i=0; i<256; ++i) {
        hist[i] = 0;
        cmap[i] = 0;
    }
    for (object_id = 0; object_id < rects; object_id++)
        for (i=0; i<h->rects[object_id]->w*h->rects[object_id]->h; ++i) {
            color = h->rects[object_id]->pict.data[0][i];
            // only count non-transparent pixels
            alpha = ((uint32_t*)h->rects[object_id]->pict.data[1])[color] >> 24;
            hist[color] += alpha;
        }
    for (color=3;; --color) {
        hmax = 0;
        imax = 0;
        for (i=0; i<256; ++i)
            if (hist[i] > hmax) {
                imax = i;
                hmax = hist[i];
            }
        if (hmax == 0)
            break;
        if (color == 0)
            color = 3;
        av_log(NULL, AV_LOG_DEBUG, "dvd_subtitle hist[%d]=%ld -> col %d\n",
               imax, hist[imax], color);
        cmap[imax] = color;
        hist[imax] = 0;
    }


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

    // 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*rects + 2);
    *q++ = 0x03; // palette - 4 nibbles
    *q++ = 0x03; *q++ = 0x7f;
    *q++ = 0x04; // alpha - 4 nibbles
    *q++ = 0xf0; *q++ = 0x00;
    //*q++ = 0x0f; *q++ = 0xff;

    // XXX not sure if more than one rect can really be encoded..
    // 12 bytes per rect
    for (object_id = 0; object_id < rects; object_id++) {
        int x2 = h->rects[object_id]->x + h->rects[object_id]->w - 1;
        int y2 = h->rects[object_id]->y + h->rects[object_id]->h - 1;

        *q++ = 0x05;
        // x1 x2 -> 6 nibbles
        *q++ = h->rects[object_id]->x >> 4;
        *q++ = (h->rects[object_id]->x << 4) | ((x2 >> 8) & 0xf);
        *q++ = x2;
        // y1 y2 -> 6 nibbles
        *q++ = h->rects[object_id]->y >> 4;
        *q++ = (h->rects[object_id]->y << 4) | ((y2 >> 8) & 0xf);
        *q++ = y2;

        *q++ = 0x06;
        // offset1, offset2
        bytestream_put_be16(&q, offset1[object_id]);
        bytestream_put_be16(&q, offset2[object_id]);
    }
    *q++ = 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=%td\n", q - outbuf);
    return q - outbuf;
}

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

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

AVCodec dvdsub_encoder = {
    "dvdsub",
    CODEC_TYPE_SUBTITLE,
    CODEC_ID_DVD_SUBTITLE,
    0,
    NULL,
    dvdsub_encode,
    .long_name = NULL_IF_CONFIG_SMALL("DVD subtitles"),
};
