/*
 * Teletext decoding for ffmpeg
 * Copyright (c) 2005-2010, 2012 Wolfram Gloger
 * Copyright (c) 2013 Marton Balint
 *
 * This library 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 of the License, or (at your option) any later version.
 *
 * This library 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 this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

#include "avcodec.h"
#include "libavcodec/ass.h"
#include "codec_internal.h"
#include "libavcodec/dvbtxt.h"
#include "libavutil/mem.h"
#include "libavutil/opt.h"
#include "libavutil/bprint.h"
#include "libavutil/internal.h"
#include "libavutil/log.h"
#include "libavutil/common.h"

#include <libzvbi.h>

#define TEXT_MAXSZ    (25 * (56 + 1) * 4 + 2)
#define VBI_NB_COLORS 40
#define VBI_TRANSPARENT_BLACK 8
#define RGBA(r,g,b,a) (((a) << 24) | ((r) << 16) | ((g) << 8) | (b))
#define VBI_R(rgba)   (((rgba) >> 0) & 0xFF)
#define VBI_G(rgba)   (((rgba) >> 8) & 0xFF)
#define VBI_B(rgba)   (((rgba) >> 16) & 0xFF)
#define VBI_A(rgba)   (((rgba) >> 24) & 0xFF)
#define MAX_BUFFERED_PAGES 25
#define BITMAP_CHAR_WIDTH  12
#define BITMAP_CHAR_HEIGHT 10
#define MAX_SLICES 64

typedef struct TeletextPage
{
    AVSubtitleRect *sub_rect;
    int pgno;
    int subno;
    int64_t pts;
} TeletextPage;

typedef struct TeletextContext
{
    AVClass        *class;
    char           *pgno;
    int             default_region;
    int             x_offset;
    int             y_offset;
    int             format_id; /* 0 = bitmap, 1 = text/ass, 2 = ass */
    int             chop_top;
    int             sub_duration; /* in msec */
    int             transparent_bg;
    int             opacity;
    int             chop_spaces;

    int             lines_processed;
    TeletextPage    *pages;
    int             nb_pages;
    int64_t         pts;
    int             handler_ret;

    vbi_decoder *   vbi;
    vbi_sliced      sliced[MAX_SLICES];

    int             readorder;
    uint8_t         subtitle_map[2048];
    int             last_pgno;
    int             last_p5;
    int             last_ass_alignment;
} TeletextContext;

static int my_ass_subtitle_header(AVCodecContext *avctx)
{
    int ret = ff_ass_subtitle_header_default(avctx);
    char *new_header;
    uint8_t *event_pos;

    if (ret < 0)
        return ret;

    event_pos = strstr(avctx->subtitle_header, "\r\n[Events]\r\n");
    if (!event_pos)
        return AVERROR_BUG;

    new_header = av_asprintf("%.*s%s%s",
        (int)(event_pos - avctx->subtitle_header), avctx->subtitle_header,
        "Style: "
        "Teletext,"            /* Name */
        "Monospace,11,"        /* Font{name,size} */
        "&Hffffff,&Hffffff,&H0,&H0," /* {Primary,Secondary,Outline,Back}Colour */
        "0,0,0,0,"             /* Bold, Italic, Underline, StrikeOut */
        "160,100,"             /* Scale{X,Y} */
        "0,0,"                 /* Spacing, Angle */
        "3,0.1,0,"             /* BorderStyle, Outline, Shadow */
        "5,1,1,1,"             /* Alignment, Margin[LRV] */
        "0\r\n"                /* Encoding */
        "Style: "
        "Subtitle,"            /* Name */
        "Monospace,16,"        /* Font{name,size} */
        "&Hffffff,&Hffffff,&H0,&H0," /* {Primary,Secondary,Outline,Back}Colour */
        "0,0,0,0,"             /* Bold, Italic, Underline, StrikeOut */
        "100,100,"             /* Scale{X,Y} */
        "0,0,"                 /* Spacing, Angle */
        "1,1,1,"               /* BorderStyle, Outline, Shadow */
        "8,48,48,20,"          /* Alignment, Margin[LRV] */
        "0\r\n"                /* Encoding */
        , event_pos);

    if (!new_header)
        return AVERROR(ENOMEM);

    av_free(avctx->subtitle_header);
    avctx->subtitle_header = new_header;
    avctx->subtitle_header_size = strlen(new_header);
    return 0;
}

static int chop_spaces_utf8(const unsigned char* t, int len)
{
    t += len;
    while (len > 0) {
        if (*--t != ' ' || (len-1 > 0 && *(t-1) & 0x80))
            break;
        --len;
    }
    return len;
}

static void subtitle_rect_free(AVSubtitleRect **sub_rect)
{
    av_freep(&(*sub_rect)->data[0]);
    av_freep(&(*sub_rect)->data[1]);
    av_freep(&(*sub_rect)->ass);
    av_freep(sub_rect);
}

static char *create_ass_text(TeletextContext *ctx, const char *text)
{
    char *dialog;
    AVBPrint buf;

    av_bprint_init(&buf, 0, AV_BPRINT_SIZE_UNLIMITED);
    ff_ass_bprint_text_event(&buf, text, strlen(text), "", 0);
    if (!av_bprint_is_complete(&buf)) {
        av_bprint_finalize(&buf, NULL);
        return NULL;
    }
    dialog = ff_ass_get_dialog(ctx->readorder++, 0, NULL, NULL, buf.str);
    av_bprint_finalize(&buf, NULL);
    return dialog;
}

/* Draw a page as text */
static int gen_sub_text(TeletextContext *ctx, AVSubtitleRect *sub_rect, vbi_page *page, int chop_top)
{
    const char *in;
    AVBPrint buf;
    char *vbi_text = av_malloc(TEXT_MAXSZ);
    int sz;

    if (!vbi_text)
        return AVERROR(ENOMEM);

    sz = vbi_print_page_region(page, vbi_text, TEXT_MAXSZ-1, "UTF-8",
                                   /*table mode*/ TRUE, FALSE,
                                   0,             chop_top,
                                   page->columns, page->rows-chop_top);
    if (sz <= 0) {
        av_log(ctx, AV_LOG_ERROR, "vbi_print error\n");
        av_free(vbi_text);
        return AVERROR_EXTERNAL;
    }
    vbi_text[sz] = '\0';
    in  = vbi_text;
    av_bprint_init(&buf, 0, TEXT_MAXSZ);

    if (ctx->chop_spaces) {
        for (;;) {
            int nl, sz;

            // skip leading spaces and newlines
            in += strspn(in, " \n");
            // compute end of row
            for (nl = 0; in[nl]; ++nl)
                if (in[nl] == '\n' && (nl==0 || !(in[nl-1] & 0x80)))
                    break;
            if (!in[nl])
                break;
            // skip trailing spaces
            sz = chop_spaces_utf8(in, nl);
            av_bprint_append_data(&buf, in, sz);
            av_bprintf(&buf, "\n");
            in += nl;
        }
    } else {
        av_bprintf(&buf, "%s\n", vbi_text);
    }
    av_free(vbi_text);

    if (!av_bprint_is_complete(&buf)) {
        av_bprint_finalize(&buf, NULL);
        return AVERROR(ENOMEM);
    }

    if (buf.len) {
        sub_rect->type = SUBTITLE_ASS;
        sub_rect->ass = create_ass_text(ctx, buf.str);

        if (!sub_rect->ass) {
            av_bprint_finalize(&buf, NULL);
            return AVERROR(ENOMEM);
        }
        av_log(ctx, AV_LOG_DEBUG, "subtext:%s:txetbus\n", sub_rect->ass);
    } else {
        sub_rect->type = SUBTITLE_NONE;
    }
    av_bprint_finalize(&buf, NULL);
    return 0;
}

static void bprint_color(const char *type, AVBPrint *buf, vbi_page *page, unsigned ci)
{
    int r = VBI_R(page->color_map[ci]);
    int g = VBI_G(page->color_map[ci]);
    int b = VBI_B(page->color_map[ci]);
    av_bprintf(buf, "{\\%s&H%02X%02X%02X&}", type, b, g, r);
}

#define IS_TXT_SPACE(ch) ((ch).unicode < 0x0020 || (ch).unicode >= 0xe000 || (ch).unicode == 0x00a0 ||\
                          (ch).size > VBI_DOUBLE_SIZE || (ch).opacity == VBI_TRANSPARENT_SPACE)

static void get_trim_info(vbi_page *page, vbi_char *row, int *leading, int *trailing, int *olen)
{
    int i, len = 0;
    int char_seen = 0;

    *leading = 0;

    for (i = 0; i < page->columns; i++) {
        uint16_t out = IS_TXT_SPACE(row[i]) ? 32 : row[i].unicode;

        if (out == 32 && !char_seen)
            (*leading)++;
        else if (out != 32)
            char_seen = 1, len = i - (*leading) + 1;
    }

    *olen = len;
    *trailing = len > 0 ? page->columns - *leading - len : page->columns;
}

static void decode_string(vbi_page *page, vbi_char *row, AVBPrint *buf,
                          int start, int end, vbi_color *cur_color, vbi_color *cur_back_color)
{
    int i;

    for (i = start; i < end; i++) {
        uint16_t out = IS_TXT_SPACE(row[i]) ? 32 : row[i].unicode;

        if (*cur_color != row[i].foreground) {
            bprint_color("c", buf, page, row[i].foreground);
            *cur_color = row[i].foreground;
        }
        if (*cur_back_color != row[i].background) {
            bprint_color("3c", buf, page, row[i].background);
            *cur_back_color = row[i].background;
        }

        if (out == 32) {
            av_bprintf(buf, "\\h");
        } else if (out == '\\' || out == '{' || out == '}') {
            av_bprintf(buf, "\\%c", (char)out);
        } else {
            char tmp;
            /* convert to utf-8 */
            PUT_UTF8(out, tmp, av_bprint_chars(buf, tmp, 1););
        }
    }
}

/* Draw a page as ass formatted text */
static int gen_sub_ass(TeletextContext *ctx, AVSubtitleRect *sub_rect, vbi_page *page, int chop_top)
{
    int i;
    int leading, trailing, len;
    int last_trailing = -1, last_leading = -1;
    int min_trailing = page->columns, min_leading = page->columns;
    int alignment = 2;
    int vertical_align = -1;
    int can_align_left = 1, can_align_right = 1, can_align_center = 1;
    int is_subtitle_page = ctx->subtitle_map[page->pgno & 0x7ff];
    int empty_lines = 0;
    vbi_color cur_color = VBI_WHITE;
    vbi_color cur_back_color = VBI_BLACK;
    AVBPrint buf;

    av_bprint_init(&buf, 0, AV_BPRINT_SIZE_UNLIMITED);

    for (i = chop_top; i < page->rows; i++) {
        vbi_char *row = page->text + i * page->columns;

        get_trim_info(page, row, &leading, &trailing, &len);

        if (len) {
            if (last_leading != -1 && last_leading != leading || leading > 5)
                can_align_left = 0;
            if (last_trailing != -1 && last_trailing != trailing || trailing > 2)
                can_align_right = 0;
            if (last_trailing != -1 && (FFABS((trailing - leading) - (last_trailing - last_leading)) > 1) || trailing - leading > 4)
                can_align_center = 0;
            last_leading = leading;
            last_trailing = trailing;
            min_leading = FFMIN(leading, min_leading);
            min_trailing = FFMIN(trailing, min_trailing);
        }
    }

    if (!can_align_right && can_align_left && !can_align_center) {
        ctx->last_ass_alignment = alignment = 1;
    } else if (!can_align_right && !can_align_left && can_align_center) {
        ctx->last_ass_alignment = alignment = 2;
    } else if (can_align_right && !can_align_left && !can_align_center) {
        ctx->last_ass_alignment = alignment = 3;
    } else {
        if (ctx->last_ass_alignment == 1 && can_align_left ||
            ctx->last_ass_alignment == 2 && can_align_center ||
            ctx->last_ass_alignment == 3 && can_align_right)
            alignment = ctx->last_ass_alignment;
    }

    for (i = chop_top; i < page->rows; i++) {
        int j;
        vbi_char *row = page->text + i * page->columns;
        int is_transparent_line;

        for (j = 0; j < page->columns; j++)
            if (row[j].opacity != VBI_TRANSPARENT_SPACE)
                break;
        is_transparent_line = (j == page->columns);

        len = is_transparent_line ? 0 : page->columns;
        leading = trailing = is_transparent_line ? page->columns : 0;

        if (is_subtitle_page) {
            if (!is_transparent_line)
                get_trim_info(page, row, &leading, &trailing, &len);

            if (vertical_align == -1 && len) {
                vertical_align = (2 - (av_clip(i + 1, 0, 23) / 8));
                av_bprintf(&buf, "{\\an%d}", alignment + vertical_align * 3);
                if (vertical_align != 2)
                    empty_lines = 0;
            }

            if (len && empty_lines > 1)
                for (empty_lines /= 2; empty_lines > 0; empty_lines--)
                    av_bprintf(&buf, " \\N");

            if (alignment == 1 || alignment == 2 && !can_align_center)
                leading = min_leading;
            if (alignment == 3 || alignment == 2 && !can_align_center)
                trailing = min_trailing;
        }

        if (len || !is_subtitle_page) {
            decode_string(page, row, &buf, leading, page->columns - trailing, &cur_color, &cur_back_color);
            av_bprintf(&buf, " \\N");
            empty_lines = 0;
        } else {
            empty_lines++;
        }
    }

    if (vertical_align == 0)
        for (empty_lines = (empty_lines - 1) / 2; empty_lines > 0; empty_lines--)
            av_bprintf(&buf, " \\N");

    if (!av_bprint_is_complete(&buf)) {
        av_bprint_finalize(&buf, NULL);
        return AVERROR(ENOMEM);
    }

    if (buf.len) {
        sub_rect->type = SUBTITLE_ASS;
        sub_rect->ass = ff_ass_get_dialog(ctx->readorder++, 0, is_subtitle_page ? "Subtitle" : "Teletext", NULL, buf.str);

        if (!sub_rect->ass) {
            av_bprint_finalize(&buf, NULL);
            return AVERROR(ENOMEM);
        }
        av_log(ctx, AV_LOG_DEBUG, "subtext:%s:txetbus\n", sub_rect->ass);
    } else {
        sub_rect->type = SUBTITLE_NONE;
    }
    av_bprint_finalize(&buf, NULL);
    return 0;
}

static void fix_transparency(TeletextContext *ctx, AVSubtitleRect *sub_rect, vbi_page *page,
                             int chop_top, int resx, int resy)
{
    int iy;

    // Hack for transparency, inspired by VLC code...
    for (iy = 0; iy < resy; iy++) {
        uint8_t *pixel = sub_rect->data[0] + iy * sub_rect->linesize[0];
        vbi_char *vc = page->text + (iy / BITMAP_CHAR_HEIGHT + chop_top) * page->columns;
        vbi_char *vcnext = vc + page->columns;
        for (; vc < vcnext; vc++) {
            uint8_t *pixelnext = pixel + BITMAP_CHAR_WIDTH;
            switch (vc->opacity) {
                case VBI_TRANSPARENT_SPACE:
                    memset(pixel, VBI_TRANSPARENT_BLACK, BITMAP_CHAR_WIDTH);
                    break;
                case VBI_OPAQUE:
                    if (!ctx->transparent_bg)
                        break;
                case VBI_SEMI_TRANSPARENT:
                    if (ctx->opacity > 0) {
                        if (ctx->opacity < 255)
                            for(; pixel < pixelnext; pixel++)
                                if (*pixel == vc->background)
                                    *pixel += VBI_NB_COLORS;
                        break;
                    }
                case VBI_TRANSPARENT_FULL:
                    for(; pixel < pixelnext; pixel++)
                        if (*pixel == vc->background)
                            *pixel = VBI_TRANSPARENT_BLACK;
                    break;
            }
            pixel = pixelnext;
        }
    }
}

/* Draw a page as bitmap */
static int gen_sub_bitmap(TeletextContext *ctx, AVSubtitleRect *sub_rect, vbi_page *page, int chop_top)
{
    int resx = page->columns * BITMAP_CHAR_WIDTH;
    int resy = (page->rows - chop_top) * BITMAP_CHAR_HEIGHT;
    uint8_t ci;
    vbi_char *vc = page->text + (chop_top * page->columns);
    vbi_char *vcend = page->text + (page->rows * page->columns);

    for (; vc < vcend; vc++) {
        if (vc->opacity != VBI_TRANSPARENT_SPACE)
            break;
    }

    if (vc >= vcend) {
        av_log(ctx, AV_LOG_DEBUG, "dropping empty page %3x\n", page->pgno);
        sub_rect->type = SUBTITLE_NONE;
        return 0;
    }

    sub_rect->data[0] = av_mallocz(resx * resy);
    sub_rect->linesize[0] = resx;
    if (!sub_rect->data[0])
        return AVERROR(ENOMEM);

    vbi_draw_vt_page_region(page, VBI_PIXFMT_PAL8,
                            sub_rect->data[0], sub_rect->linesize[0],
                            0, chop_top, page->columns, page->rows - chop_top,
                            /*reveal*/ 1, /*flash*/ 1);

    fix_transparency(ctx, sub_rect, page, chop_top, resx, resy);
    sub_rect->x = ctx->x_offset;
    sub_rect->y = ctx->y_offset + chop_top * BITMAP_CHAR_HEIGHT;
    sub_rect->w = resx;
    sub_rect->h = resy;
    sub_rect->nb_colors = ctx->opacity > 0 && ctx->opacity < 255 ? 2 * VBI_NB_COLORS : VBI_NB_COLORS;
    sub_rect->data[1] = av_mallocz(AVPALETTE_SIZE);
    if (!sub_rect->data[1]) {
        av_freep(&sub_rect->data[0]);
        return AVERROR(ENOMEM);
    }
    for (ci = 0; ci < VBI_NB_COLORS; ci++) {
        int r, g, b, a;

        r = VBI_R(page->color_map[ci]);
        g = VBI_G(page->color_map[ci]);
        b = VBI_B(page->color_map[ci]);
        a = VBI_A(page->color_map[ci]);
        ((uint32_t *)sub_rect->data[1])[ci] = RGBA(r, g, b, a);
        ((uint32_t *)sub_rect->data[1])[ci + VBI_NB_COLORS] = RGBA(r, g, b, ctx->opacity);
        ff_dlog(ctx, "palette %0x\n", ((uint32_t *)sub_rect->data[1])[ci]);
    }
    ((uint32_t *)sub_rect->data[1])[VBI_TRANSPARENT_BLACK] = RGBA(0, 0, 0, 0);
    ((uint32_t *)sub_rect->data[1])[VBI_TRANSPARENT_BLACK + VBI_NB_COLORS] = RGBA(0, 0, 0, 0);
    sub_rect->type = SUBTITLE_BITMAP;
    return 0;
}

static void handler(vbi_event *ev, void *user_data)
{
    TeletextContext *ctx = user_data;
    TeletextPage *new_pages;
    vbi_page page;
    int res;
    char pgno_str[12];
    int chop_top;
    int is_subtitle_page = ctx->subtitle_map[ev->ev.ttx_page.pgno & 0x7ff];

    snprintf(pgno_str, sizeof pgno_str, "%03x", ev->ev.ttx_page.pgno);
    av_log(ctx, AV_LOG_DEBUG, "decoded page %s.%02x\n",
           pgno_str, ev->ev.ttx_page.subno & 0xFF);

    if (strcmp(ctx->pgno, "*") && (strcmp(ctx->pgno, "subtitle") || !is_subtitle_page) && !strstr(ctx->pgno, pgno_str))
        return;
    if (ctx->handler_ret < 0)
        return;

    res = vbi_fetch_vt_page(ctx->vbi, &page,
                            ev->ev.ttx_page.pgno,
                            ev->ev.ttx_page.subno,
                            VBI_WST_LEVEL_3p5, 25, TRUE);

    if (!res)
        return;

    chop_top = ctx->chop_top || ((page.rows > 1) && is_subtitle_page);

    av_log(ctx, AV_LOG_DEBUG, "%d x %d page chop:%d\n",
           page.columns, page.rows, chop_top);

    if (ctx->nb_pages < MAX_BUFFERED_PAGES) {
        if ((new_pages = av_realloc_array(ctx->pages, ctx->nb_pages + 1, sizeof(TeletextPage)))) {
            TeletextPage *cur_page = new_pages + ctx->nb_pages;
            ctx->pages = new_pages;
            cur_page->sub_rect = av_mallocz(sizeof(*cur_page->sub_rect));
            cur_page->pts = ctx->pts;
            cur_page->pgno = ev->ev.ttx_page.pgno;
            cur_page->subno = ev->ev.ttx_page.subno;
            if (cur_page->sub_rect) {
                switch (ctx->format_id) {
                    case 0:
                        res = gen_sub_bitmap(ctx, cur_page->sub_rect, &page, chop_top);
                        break;
                    case 1:
                        res = gen_sub_text(ctx, cur_page->sub_rect, &page, chop_top);
                        break;
                    case 2:
                        res = gen_sub_ass(ctx, cur_page->sub_rect, &page, chop_top);
                        break;
                    default:
                        res = AVERROR_BUG;
                        break;
                }
                if (res < 0) {
                    av_freep(&cur_page->sub_rect);
                    ctx->handler_ret = res;
                } else {
                    ctx->pages[ctx->nb_pages++] = *cur_page;
                }
            } else {
                ctx->handler_ret = AVERROR(ENOMEM);
            }
        } else {
            ctx->handler_ret = AVERROR(ENOMEM);
        }
    } else {
        //TODO: If multiple packets contain more than one page, pages may got queued up, and this may happen...
        av_log(ctx, AV_LOG_ERROR, "Buffered too many pages, dropping page %s.\n", pgno_str);
        ctx->handler_ret = AVERROR(ENOSYS);
    }

    vbi_unref_page(&page);
}

static int slice_to_vbi_lines(TeletextContext *ctx, const uint8_t *buf, int size)
{
    int lines = 0;
    while (size >= 2 && lines < MAX_SLICES) {
        int data_unit_id     = buf[0];
        int data_unit_length = buf[1];
        if (data_unit_length + 2 > size)
            return AVERROR_INVALIDDATA;
        if (ff_data_unit_id_is_teletext(data_unit_id)) {
            if (data_unit_length != 0x2c)
                return AVERROR_INVALIDDATA;
            else {
                int line_offset  = buf[2] & 0x1f;
                int field_parity = buf[2] & 0x20;
                uint8_t *p = ctx->sliced[lines].data;
                int i, pmag;
                ctx->sliced[lines].id = VBI_SLICED_TELETEXT_B;
                ctx->sliced[lines].line = (line_offset > 0 ? (line_offset + (field_parity ? 0 : 313)) : 0);
                for (i = 0; i < 42; i++)
                    p[i] = vbi_rev8(buf[4 + i]);
                /* Unfortunately libzvbi does not expose page flags, and
                 * vbi_classify_page only checks MIP, so we have to manually
                 * decode the page flags and store the results. */
                pmag = vbi_unham16p(p);
                if (pmag >= 0 && pmag >> 3 == 0) {   // We found a row 0 header
                    int page = vbi_unham16p(p + 2);
                    int flags1 = vbi_unham16p(p + 6);
                    int flags2 = vbi_unham16p(p + 8);
                    if (page >= 0 && flags1 >= 0 && flags2 >= 0) {
                        int pgno = ((pmag & 7) << 8) + page;
                        // Check for disabled NEWSFLASH flag and enabled SUBTITLE and SUPRESS_HEADER flags
                        ctx->subtitle_map[pgno] = (!(flags1 & 0x40) && flags1 & 0x80 && flags2 & 0x01);
                        // Propagate ERASE_PAGE flag for repeated page headers to work around a libzvbi bug
                        if (ctx->subtitle_map[pgno] && pgno == ctx->last_pgno) {
                            int last_byte9 = vbi_unham8(ctx->last_p5);
                            if (last_byte9 >= 0 && last_byte9 & 0x8) {
                                int byte9 = vbi_unham8(p[5]);
                                if (byte9 >= 0)
                                    p[5] = vbi_ham8(byte9 | 0x8);
                            }
                        }
                        ctx->last_pgno = pgno;
                        ctx->last_p5 = p[5];
                    }
                }
                lines++;
            }
        }
        size -= data_unit_length + 2;
        buf += data_unit_length + 2;
    }
    if (size)
        av_log(ctx, AV_LOG_WARNING, "%d bytes remained after slicing data\n", size);
    return lines;
}

static int teletext_decode_frame(AVCodecContext *avctx, AVSubtitle *sub,
                                 int *got_sub_ptr, const AVPacket *pkt)
{
    TeletextContext *ctx = avctx->priv_data;
    int             ret = 0;

    if (!ctx->vbi) {
        if (!(ctx->vbi = vbi_decoder_new()))
            return AVERROR(ENOMEM);
        if (ctx->default_region != -1) {
            av_log(avctx, AV_LOG_INFO, "Setting default zvbi region to %i\n", ctx->default_region);
            vbi_teletext_set_default_region(ctx->vbi, ctx->default_region);
        }
        if (!vbi_event_handler_register(ctx->vbi, VBI_EVENT_TTX_PAGE, handler, ctx)) {
            vbi_decoder_delete(ctx->vbi);
            ctx->vbi = NULL;
            return AVERROR(ENOMEM);
        }
    }

    if (avctx->pkt_timebase.num && pkt->pts != AV_NOPTS_VALUE)
        ctx->pts = av_rescale_q(pkt->pts, avctx->pkt_timebase, AV_TIME_BASE_Q);

    if (pkt->size) {
        int lines;
        const int full_pes_size = pkt->size + 45; /* PES header is 45 bytes */

        // We allow unreasonably big packets, even if the standard only allows a max size of 1472
        if (full_pes_size < 184 || full_pes_size > 65504 || full_pes_size % 184 != 0)
            return AVERROR_INVALIDDATA;

        ctx->handler_ret = pkt->size;

        if (ff_data_identifier_is_teletext(*pkt->data)) {
            if ((lines = slice_to_vbi_lines(ctx, pkt->data + 1, pkt->size - 1)) < 0)
                return lines;
            ff_dlog(avctx, "ctx=%p buf_size=%d lines=%u pkt_pts=%7.3f\n",
                    ctx, pkt->size, lines, (double)pkt->pts/90000.0);
            if (lines > 0) {
                vbi_decode(ctx->vbi, ctx->sliced, lines, 0.0);
                ctx->lines_processed += lines;
            }
        }
        ctx->pts = AV_NOPTS_VALUE;
        ret = ctx->handler_ret;
    }

    if (ret < 0)
        return ret;

    // is there a subtitle to pass?
    if (ctx->nb_pages) {
        int i;
        sub->format = !!ctx->format_id;
        sub->start_display_time = 0;
        sub->end_display_time = ctx->sub_duration;
        sub->num_rects = 0;
        sub->pts = ctx->pages->pts;

        if (ctx->pages->sub_rect->type != SUBTITLE_NONE) {
            sub->rects = av_malloc(sizeof(*sub->rects));
            if (sub->rects) {
                sub->num_rects = 1;
                sub->rects[0] = ctx->pages->sub_rect;
            } else {
                ret = AVERROR(ENOMEM);
            }
        } else {
            av_log(avctx, AV_LOG_DEBUG, "sending empty sub\n");
            sub->rects = NULL;
        }
        if (!sub->rects) // no rect was passed
            subtitle_rect_free(&ctx->pages->sub_rect);

        for (i = 0; i < ctx->nb_pages - 1; i++)
            ctx->pages[i] = ctx->pages[i + 1];
        ctx->nb_pages--;

        if (ret >= 0)
            *got_sub_ptr = 1;
    } else
        *got_sub_ptr = 0;

    return ret;
}

static int teletext_init_decoder(AVCodecContext *avctx)
{
    TeletextContext *ctx = avctx->priv_data;
    unsigned int maj, min, rev;

    vbi_version(&maj, &min, &rev);
    if (!(maj > 0 || min > 2 || min == 2 && rev >= 26)) {
        av_log(avctx, AV_LOG_ERROR, "decoder needs zvbi version >= 0.2.26.\n");
        return AVERROR_EXTERNAL;
    }

    if (ctx->format_id == 0) {
        avctx->width  = 41 * BITMAP_CHAR_WIDTH;
        avctx->height = 25 * BITMAP_CHAR_HEIGHT;
    }

    ctx->vbi = NULL;
    ctx->pts = AV_NOPTS_VALUE;
    ctx->last_pgno = -1;
    ctx->last_ass_alignment = 2;

    if (ctx->opacity == -1)
        ctx->opacity = ctx->transparent_bg ? 0 : 255;

    av_log(avctx, AV_LOG_VERBOSE, "page filter: %s\n", ctx->pgno);

    switch (ctx->format_id) {
        case 0:
            return 0;
        case 1:
            return ff_ass_subtitle_header_default(avctx);
        case 2:
            return my_ass_subtitle_header(avctx);
    }
    return AVERROR_BUG;
}

static int teletext_close_decoder(AVCodecContext *avctx)
{
    TeletextContext *ctx = avctx->priv_data;

    ff_dlog(avctx, "lines_total=%u\n", ctx->lines_processed);
    while (ctx->nb_pages)
        subtitle_rect_free(&ctx->pages[--ctx->nb_pages].sub_rect);
    av_freep(&ctx->pages);

    vbi_decoder_delete(ctx->vbi);
    ctx->vbi = NULL;
    ctx->pts = AV_NOPTS_VALUE;
    ctx->last_pgno = -1;
    ctx->last_ass_alignment = 2;
    memset(ctx->subtitle_map, 0, sizeof(ctx->subtitle_map));
    if (!(avctx->flags2 & AV_CODEC_FLAG2_RO_FLUSH_NOOP))
        ctx->readorder = 0;
    return 0;
}

static void teletext_flush(AVCodecContext *avctx)
{
    teletext_close_decoder(avctx);
}

#define OFFSET(x) offsetof(TeletextContext, x)
#define SD AV_OPT_FLAG_SUBTITLE_PARAM | AV_OPT_FLAG_DECODING_PARAM
static const AVOption options[] = {
    {"txt_page",        "page numbers to decode, subtitle for subtitles, * for all", OFFSET(pgno),   AV_OPT_TYPE_STRING, {.str = "*"},      0, 0,        SD},
    {"txt_default_region", "default G0 character set used for decoding",     OFFSET(default_region), AV_OPT_TYPE_INT,    {.i64 = -1},      -1, 87,       SD},
    {"txt_chop_top",    "discards the top teletext line",                    OFFSET(chop_top),       AV_OPT_TYPE_INT,    {.i64 = 1},        0, 1,        SD},
    {"txt_format",      "format of the subtitles (bitmap or text or ass)",   OFFSET(format_id),      AV_OPT_TYPE_INT,    {.i64 = 0},        0, 2,        SD,  .unit = "txt_format"},
    {"bitmap",          NULL,                                                0,                      AV_OPT_TYPE_CONST,  {.i64 = 0},        0, 0,        SD,  .unit = "txt_format"},
    {"text",            NULL,                                                0,                      AV_OPT_TYPE_CONST,  {.i64 = 1},        0, 0,        SD,  .unit = "txt_format"},
    {"ass",             NULL,                                                0,                      AV_OPT_TYPE_CONST,  {.i64 = 2},        0, 0,        SD,  .unit = "txt_format"},
    {"txt_left",        "x offset of generated bitmaps",                     OFFSET(x_offset),       AV_OPT_TYPE_INT,    {.i64 = 0},        0, 65535,    SD},
    {"txt_top",         "y offset of generated bitmaps",                     OFFSET(y_offset),       AV_OPT_TYPE_INT,    {.i64 = 0},        0, 65535,    SD},
    {"txt_chop_spaces", "chops leading and trailing spaces from text",       OFFSET(chop_spaces),    AV_OPT_TYPE_INT,    {.i64 = 1},        0, 1,        SD},
    {"txt_duration",    "display duration of teletext pages in msecs",       OFFSET(sub_duration),   AV_OPT_TYPE_INT,    {.i64 = -1},      -1, 86400000, SD},
    {"txt_transparent", "force transparent background of the teletext",      OFFSET(transparent_bg), AV_OPT_TYPE_INT,    {.i64 = 0},        0, 1,        SD},
    {"txt_opacity",     "set opacity of the transparent background",         OFFSET(opacity),        AV_OPT_TYPE_INT,    {.i64 = -1},      -1, 255,      SD},
    { NULL },
};

static const AVClass teletext_class = {
    .class_name = "libzvbi_teletextdec",
    .item_name  = av_default_item_name,
    .option     = options,
    .version    = LIBAVUTIL_VERSION_INT,
};

const FFCodec ff_libzvbi_teletext_decoder = {
    .p.name         = "libzvbi_teletextdec",
    CODEC_LONG_NAME("Libzvbi DVB teletext decoder"),
    .p.type         = AVMEDIA_TYPE_SUBTITLE,
    .p.id           = AV_CODEC_ID_DVB_TELETEXT,
    .p.capabilities = AV_CODEC_CAP_DELAY,
    .p.priv_class   = &teletext_class,
    .p.wrapper_name = "libzvbi",
    .caps_internal  = FF_CODEC_CAP_NOT_INIT_THREADSAFE,
    .priv_data_size = sizeof(TeletextContext),
    .init      = teletext_init_decoder,
    .close     = teletext_close_decoder,
    FF_CODEC_DECODE_SUB_CB(teletext_decode_frame),
    .flush     = teletext_flush,
};
