/*
 * DVB subtitle encoding
 * Copyright (c) 2005 Fabrice Bellard
 *
 * 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 "libavutil/colorspace.h"

typedef struct DVBSubtitleContext {
    int object_version;
} DVBSubtitleContext;

#define PUTBITS2(val)\
{\
    bitbuf |= (val) << bitcnt;\
    bitcnt -= 2;\
    if (bitcnt < 0) {\
        bitcnt = 6;\
        *q++ = bitbuf;\
        bitbuf = 0;\
    }\
}

static int dvb_encode_rle2(uint8_t **pq, int buf_size,
                           const uint8_t *bitmap, int linesize,
                           int w, int h)
{
    uint8_t *q, *line_begin;
    unsigned int bitbuf;
    int bitcnt;
    int x, y, len, x1, v, color;

    q = *pq;

    for(y = 0; y < h; y++) {
        // Worst case line is 3 bits per value + 4 bytes overhead
        if (buf_size * 8 < w * 3 + 32)
            return AVERROR_BUFFER_TOO_SMALL;
        line_begin = q;
        *q++ = 0x10;
        bitbuf = 0;
        bitcnt = 6;

        x = 0;
        while (x < w) {
            x1 = x;
            color = bitmap[x1++];
            while (x1 < w && bitmap[x1] == color)
                x1++;
            len = x1 - x;
            if (color == 0 && len == 2) {
                PUTBITS2(0);
                PUTBITS2(0);
                PUTBITS2(1);
            } else if (len >= 3 && len <= 10) {
                v = len - 3;
                PUTBITS2(0);
                PUTBITS2((v >> 2) | 2);
                PUTBITS2(v & 3);
                PUTBITS2(color);
            } else if (len >= 12 && len <= 27) {
                v = len - 12;
                PUTBITS2(0);
                PUTBITS2(0);
                PUTBITS2(2);
                PUTBITS2(v >> 2);
                PUTBITS2(v & 3);
                PUTBITS2(color);
            } else if (len >= 29) {
                /* length = 29 ... 284 */
                if (len > 284)
                    len = 284;
                v = len - 29;
                PUTBITS2(0);
                PUTBITS2(0);
                PUTBITS2(3);
                PUTBITS2((v >> 6));
                PUTBITS2((v >> 4) & 3);
                PUTBITS2((v >> 2) & 3);
                PUTBITS2(v & 3);
                PUTBITS2(color);
            } else {
                PUTBITS2(color);
                if (color == 0) {
                    PUTBITS2(1);
                }
                len = 1;
            }
            x += len;
        }
        /* end of line */
        PUTBITS2(0);
        PUTBITS2(0);
        PUTBITS2(0);
        if (bitcnt != 6) {
            *q++ = bitbuf;
        }
        *q++ = 0xf0;
        bitmap += linesize;
        buf_size -= q - line_begin;
    }
    len = q - *pq;
    *pq = q;
    return len;
}

#define PUTBITS4(val)\
{\
    bitbuf |= (val) << bitcnt;\
    bitcnt -= 4;\
    if (bitcnt < 0) {\
        bitcnt = 4;\
        *q++ = bitbuf;\
        bitbuf = 0;\
    }\
}

/* some DVB decoders only implement 4 bits/pixel */
static int dvb_encode_rle4(uint8_t **pq, int buf_size,
                           const uint8_t *bitmap, int linesize,
                           int w, int h)
{
    uint8_t *q, *line_begin;
    unsigned int bitbuf;
    int bitcnt;
    int x, y, len, x1, v, color;

    q = *pq;

    for(y = 0; y < h; y++) {
        // Worst case line is 6 bits per value, + 4 bytes overhead
        if (buf_size * 8 < w * 6 + 32)
            return AVERROR_BUFFER_TOO_SMALL;
        line_begin = q;
        *q++ = 0x11;
        bitbuf = 0;
        bitcnt = 4;

        x = 0;
        while (x < w) {
            x1 = x;
            color = bitmap[x1++];
            while (x1 < w && bitmap[x1] == color)
                x1++;
            len = x1 - x;
            if (color == 0 && len == 2) {
                PUTBITS4(0);
                PUTBITS4(0xd);
            } else if (color == 0 && (len >= 3 && len <= 9)) {
                PUTBITS4(0);
                PUTBITS4(len - 2);
            } else if (len >= 4 && len <= 7) {
                PUTBITS4(0);
                PUTBITS4(8 + len - 4);
                PUTBITS4(color);
            } else if (len >= 9 && len <= 24) {
                PUTBITS4(0);
                PUTBITS4(0xe);
                PUTBITS4(len - 9);
                PUTBITS4(color);
            } else if (len >= 25) {
                if (len > 280)
                    len = 280;
                v = len - 25;
                PUTBITS4(0);
                PUTBITS4(0xf);
                PUTBITS4(v >> 4);
                PUTBITS4(v & 0xf);
                PUTBITS4(color);
            } else {
                PUTBITS4(color);
                if (color == 0) {
                    PUTBITS4(0xc);
                }
                len = 1;
            }
            x += len;
        }
        /* end of line */
        PUTBITS4(0);
        PUTBITS4(0);
        if (bitcnt != 4) {
            *q++ = bitbuf;
        }
        *q++ = 0xf0;
        bitmap += linesize;
        buf_size -= q - line_begin;
    }
    len = q - *pq;
    *pq = q;
    return len;
}

static int dvb_encode_rle8(uint8_t **pq, int buf_size,
                           const uint8_t *bitmap, int linesize,
                           int w, int h)
{
    uint8_t *q, *line_begin;
    int x, y, len, x1, color;

    q = *pq;

    for (y = 0; y < h; y++) {
        // Worst case line is 12 bits per value, + 3 bytes overhead
        if (buf_size * 8 < w * 12 + 24)
            return AVERROR_BUFFER_TOO_SMALL;
        line_begin = q;
        *q++ = 0x12;

        x = 0;
        while (x < w) {
            x1 = x;
            color = bitmap[x1++];
            while (x1 < w && bitmap[x1] == color)
                x1++;
            len = x1 - x;
            if (len == 1 && color) {
                // 00000001 to 11111111           1 pixel in colour x
                *q++ = color;
            } else {
                if (color == 0x00) {
                    // 00000000 0LLLLLLL          L pixels (1-127) in colour 0 (L > 0)
                    len = FFMIN(len, 127);
                    *q++ = 0x00;
                    *q++ = len;
                } else if (len > 2) {
                    // 00000000 1LLLLLLL CCCCCCCC L pixels (3-127) in colour C (L > 2)
                    len = FFMIN(len, 127);
                    *q++ = 0x00;
                    *q++ = 0x80+len;
                    *q++ = color;
                }
                else if (len == 2) {
                    *q++ = color;
                    *q++ = color;
                } else {
                    *q++ = color;
                    len = 1;
                }
            }
            x += len;
        }
        /* end of line */
        // 00000000 end of 8-bit/pixel_code_string
        *q++ = 0x00;
        *q++ = 0xf0;
        bitmap += linesize;
        buf_size -= q - line_begin;
    }
    len = q - *pq;
    *pq = q;
    return len;
}

static int encode_dvb_subtitles(AVCodecContext *avctx,
                                uint8_t *outbuf, int buf_size,
                                const AVSubtitle *h)
{
    DVBSubtitleContext *s = avctx->priv_data;
    uint8_t *q, *pseg_len;
    int page_id, region_id, clut_id, object_id, i, bpp_index, page_state;


    q = outbuf;

    page_id = 1;

    if (h->num_rects && !h->rects)
        return AVERROR(EINVAL);

    if (avctx->width > 0 && avctx->height > 0) {
        if (buf_size < 11)
            return AVERROR_BUFFER_TOO_SMALL;
        /* display definition segment */
        *q++ = 0x0f; /* sync_byte */
        *q++ = 0x14; /* segment_type */
        bytestream_put_be16(&q, page_id);
        pseg_len = q;
        q += 2; /* segment length */
        *q++ = 0x00; /* dds version number & display window flag */
        bytestream_put_be16(&q, avctx->width - 1); /* display width */
        bytestream_put_be16(&q, avctx->height - 1); /* display height */
        bytestream_put_be16(&pseg_len, q - pseg_len - 2);
        buf_size -= 11;
    }

    /* page composition segment */

    if (buf_size < 8 + h->num_rects * 6)
        return AVERROR_BUFFER_TOO_SMALL;
    *q++ = 0x0f; /* sync_byte */
    *q++ = 0x10; /* segment_type */
    bytestream_put_be16(&q, page_id);
    pseg_len = q;
    q += 2; /* segment length */
    *q++ = 30; /* page_timeout (seconds) */
    page_state = 2; /* mode change */
    /* page_version = 0 + page_state */
    *q++ = (s->object_version << 4) | (page_state << 2) | 3;

    for (region_id = 0; region_id < h->num_rects; region_id++) {
        *q++ = region_id;
        *q++ = 0xff; /* reserved */
        bytestream_put_be16(&q, h->rects[region_id]->x); /* left pos */
        bytestream_put_be16(&q, h->rects[region_id]->y); /* top pos */
    }

    bytestream_put_be16(&pseg_len, q - pseg_len - 2);
    buf_size -= 8 + h->num_rects * 6;

    if (h->num_rects) {
        for (clut_id = 0; clut_id < h->num_rects; clut_id++) {
            if (buf_size < 6 + h->rects[clut_id]->nb_colors * 6)
                return AVERROR_BUFFER_TOO_SMALL;

            /* CLUT segment */

            if (h->rects[clut_id]->nb_colors <= 4) {
                /* 2 bpp, some decoders do not support it correctly */
                bpp_index = 0;
            } else if (h->rects[clut_id]->nb_colors <= 16) {
                /* 4 bpp, standard encoding */
                bpp_index = 1;
            } else if (h->rects[clut_id]->nb_colors <= 256) {
                /* 8 bpp, standard encoding */
                bpp_index = 2;
            } else {
                return AVERROR(EINVAL);
            }


            /* CLUT segment */
            *q++ = 0x0f; /* sync byte */
            *q++ = 0x12; /* CLUT definition segment */
            bytestream_put_be16(&q, page_id);
            pseg_len = q;
            q += 2; /* segment length */
            *q++ = clut_id;
            *q++ = (0 << 4) | 0xf; /* version = 0 */

            for(i = 0; i < h->rects[clut_id]->nb_colors; i++) {
                *q++ = i; /* clut_entry_id */
                *q++ = (1 << (7 - bpp_index)) | (0xf << 1) | 1; /* 2 bits/pixel full range */
                {
                    int a, r, g, b;
                    uint32_t x= ((uint32_t*)h->rects[clut_id]->data[1])[i];
                    a = (x >> 24) & 0xff;
                    r = (x >> 16) & 0xff;
                    g = (x >>  8) & 0xff;
                    b = (x >>  0) & 0xff;

                    *q++ = RGB_TO_Y_CCIR(r, g, b);
                    *q++ = RGB_TO_V_CCIR(r, g, b, 0);
                    *q++ = RGB_TO_U_CCIR(r, g, b, 0);
                    *q++ = 255 - a;
                }
            }

            bytestream_put_be16(&pseg_len, q - pseg_len - 2);
            buf_size -= 6 + h->rects[clut_id]->nb_colors * 6;
        }
    }

    if (buf_size < h->num_rects * 22)
        return AVERROR_BUFFER_TOO_SMALL;
    for (region_id = 0; region_id < h->num_rects; region_id++) {

        /* region composition segment */

        if (h->rects[region_id]->nb_colors <= 4) {
            /* 2 bpp, some decoders do not support it correctly */
            bpp_index = 0;
        } else if (h->rects[region_id]->nb_colors <= 16) {
            /* 4 bpp, standard encoding */
            bpp_index = 1;
        } else if (h->rects[region_id]->nb_colors <= 256) {
            /* 8 bpp, standard encoding */
            bpp_index = 2;
        } else {
            return AVERROR(EINVAL);
        }

        *q++ = 0x0f; /* sync_byte */
        *q++ = 0x11; /* segment_type */
        bytestream_put_be16(&q, page_id);
        pseg_len = q;
        q += 2; /* segment length */
        *q++ = region_id;
        *q++ = (s->object_version << 4) | (0 << 3) | 0x07; /* version , no fill */
        bytestream_put_be16(&q, h->rects[region_id]->w); /* region width */
        bytestream_put_be16(&q, h->rects[region_id]->h); /* region height */
        *q++ = ((1 + bpp_index) << 5) | ((1 + bpp_index) << 2) | 0x03;
        *q++ = region_id; /* clut_id == region_id */
        *q++ = 0; /* 8 bit fill colors */
        *q++ = 0x03; /* 4 bit and 2 bit fill colors */

        bytestream_put_be16(&q, region_id); /* object_id == region_id */
        *q++ = (0 << 6) | (0 << 4);
        *q++ = 0;
        *q++ = 0xf0;
        *q++ = 0;

        bytestream_put_be16(&pseg_len, q - pseg_len - 2);
    }
    buf_size -= h->num_rects * 22;

    if (h->num_rects) {

        for (object_id = 0; object_id < h->num_rects; object_id++) {
            int (*dvb_encode_rle)(uint8_t **pq, int buf_size,
                                  const uint8_t *bitmap, int linesize,
                                  int w, int h);

            if (buf_size < 13)
                return AVERROR_BUFFER_TOO_SMALL;

            /* bpp_index maths */
            if (h->rects[object_id]->nb_colors <= 4) {
                /* 2 bpp, some decoders do not support it correctly */
                dvb_encode_rle = dvb_encode_rle2;
            } else if (h->rects[object_id]->nb_colors <= 16) {
                /* 4 bpp, standard encoding */
                dvb_encode_rle = dvb_encode_rle4;
            } else if (h->rects[object_id]->nb_colors <= 256) {
                /* 8 bpp, standard encoding */
                dvb_encode_rle = dvb_encode_rle8;
            } else {
                return AVERROR(EINVAL);
            }

            /* Object Data segment */
            *q++ = 0x0f; /* sync byte */
            *q++ = 0x13;
            bytestream_put_be16(&q, page_id);
            pseg_len = q;
            q += 2; /* segment length */

            bytestream_put_be16(&q, object_id);
            *q++ = (s->object_version << 4) | (0 << 2) | (0 << 1) | 1; /* version = 0,
                                                                       onject_coding_method,
                                                                       non_modifying_color_flag */
            {
                uint8_t *ptop_field_len, *pbottom_field_len, *top_ptr, *bottom_ptr;
                int ret;

                ptop_field_len = q;
                q += 2;
                pbottom_field_len = q;
                q += 2;
                buf_size -= 13;

                top_ptr = q;
                ret = dvb_encode_rle(&q, buf_size,
                                     h->rects[object_id]->data[0],
                                     h->rects[object_id]->w * 2,
                                     h->rects[object_id]->w,
                                     h->rects[object_id]->h >> 1);
                if (ret < 0)
                    return ret;
                buf_size -= ret;
                bottom_ptr = q;
                ret = dvb_encode_rle(&q, buf_size,
                                     h->rects[object_id]->data[0] + h->rects[object_id]->w,
                                     h->rects[object_id]->w * 2,
                                     h->rects[object_id]->w,
                                     h->rects[object_id]->h >> 1);
                if (ret < 0)
                    return ret;
                buf_size -= ret;

                bytestream_put_be16(&ptop_field_len, bottom_ptr - top_ptr);
                bytestream_put_be16(&pbottom_field_len, q - bottom_ptr);
            }

            bytestream_put_be16(&pseg_len, q - pseg_len - 2);
        }
    }

    /* end of display set segment */

    if (buf_size < 6)
        return AVERROR_BUFFER_TOO_SMALL;
    *q++ = 0x0f; /* sync_byte */
    *q++ = 0x80; /* segment_type */
    bytestream_put_be16(&q, page_id);
    pseg_len = q;
    q += 2; /* segment length */

    bytestream_put_be16(&pseg_len, q - pseg_len - 2);
    buf_size -= 6;

    s->object_version = (s->object_version + 1) & 0xf;
    return q - outbuf;
}

static int dvbsub_encode(AVCodecContext *avctx,
                         unsigned char *buf, int buf_size,
                         const AVSubtitle *sub)
{
    int ret;

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

AVCodec ff_dvbsub_encoder = {
    .name           = "dvbsub",
    .long_name      = NULL_IF_CONFIG_SMALL("DVB subtitles"),
    .type           = AVMEDIA_TYPE_SUBTITLE,
    .id             = AV_CODEC_ID_DVB_SUBTITLE,
    .priv_data_size = sizeof(DVBSubtitleContext),
    .encode_sub     = dvbsub_encode,
};
