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;



    if (rects == 0 || h->rects == NULL)







    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;


            global_palette_hits[0] -= h->rects[i]->w * h->rects[i]->h;





        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.pict.data    [0] = vrect_data;

        vrect.pict.linesize[0] = vrect.w;

        for (i = 0; i < rects; i++) {

            build_color_map(avctx, cmap, (uint32_t *)h->rects[i]->pict.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]->pict.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.pict.data[0], vrect.w * 2,

                   vrect.w, (vrect.h + 1) >> 1, cmap);

    offset2 = q - outbuf;

    dvd_encode_rle(&q, vrect.pict.data[0] + vrect.w, vrect.w * 2,

                   vrect.w, vrect.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 + 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++ = 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);

    ret = q - outbuf;



fail:

    av_free(vrect_data);

    return ret;

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;



    if (rects == 0 || h->rects == NULL)







    vrect = *h->rects[0];



    if (rects > 1) {

        







        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;



        

        global_palette_hits[0] = vrect.w * vrect.h;


            global_palette_hits[0] -= h->rects[i]->w * h->rects[i]->h;





        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.pict.data    [0] = vrect_data;

        vrect.pict.linesize[0] = vrect.w;

        for (i = 0; i < rects; i++) {

            build_color_map(avctx, cmap, (uint32_t *)h->rects[i]->pict.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]->pict.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");



    

    q = outbuf + 4;

    offset1 = q - outbuf;

    

    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.pict.data[0], vrect.w * 2,

                   vrect.w, (vrect.h + 1) >> 1, cmap);

    offset2 = q - outbuf;

    dvd_encode_rle(&q, vrect.pict.data[0] + vrect.w, vrect.w * 2,

                   vrect.w, vrect.h >> 1, cmap);



    

    qq = outbuf + 2;

    bytestream_put_be16(&qq, q - outbuf);



    

    bytestream_put_be16(&q, (h->start_display_time*90) >> 10);

    bytestream_put_be16(&q, (q - outbuf)  + 8 + 12 + 2);

    *q++ = 0x03; 

    *q++ = (out_palette[3] << 4) | out_palette[2];

    *q++ = (out_palette[1] << 4) | out_palette[0];

    *q++ = 0x04; 

    *q++ = (out_alpha[3] & 0xF0) | (out_alpha[2] >> 4);

    *q++ = (out_alpha[1] & 0xF0) | (out_alpha[0] >> 4);



    

    x2 = vrect.x + vrect.w - 1;

    y2 = vrect.y + vrect.h - 1;



    *q++ = 0x05;

    

    *q++ = vrect.x >> 4;

    *q++ = (vrect.x << 4) | ((x2 >> 8) & 0xf);

    *q++ = x2;

    

    *q++ = vrect.y >> 4;

    *q++ = (vrect.y << 4) | ((y2 >> 8) & 0xf);

    *q++ = y2;



    *q++ = 0x06;

    

    bytestream_put_be16(&q, offset1);

    bytestream_put_be16(&q, offset2);



    *q++ = 0x01; 

    *q++ = 0xff; 



    

    bytestream_put_be16(&q, (h->end_display_time*90) >> 10);

    bytestream_put_be16(&q, (q - outbuf) - 2 );

    *q++ = 0x02; 

    *q++ = 0xff; 



    qq = outbuf;

    bytestream_put_be16(&qq, q - outbuf);



    av_log(NULL, AV_LOG_DEBUG, "subtitle_packet size=%td\n", q - outbuf);

    ret = q - outbuf;



fail:

    av_free(vrect_data);

    return ret;

static int FUNC_0(AVCodecContext *VAR_0,

                                uint8_t *VAR_1, int VAR_2,

                                const AVSubtitle *VAR_3)

{

    DVDSubtitleContext *dvdc = VAR_0->priv_data;

    uint8_t *q, *qq;

    int VAR_4, VAR_5;

    int VAR_6, VAR_7 = VAR_3->num_rects, VAR_8;

    unsigned VAR_9[33] = { 0 };

    int VAR_10[256];

    int VAR_11[4];

    int VAR_12[4];

    AVSubtitleRect vrect;

    uint8_t *vrect_data = NULL;

    int VAR_13, VAR_14;



    if (VAR_7 == 0 || VAR_3->VAR_7 == NULL)







    vrect = *VAR_3->VAR_7[0];



    if (VAR_7 > 1) {

        







        int VAR_15 = VAR_3->VAR_7[0]->x, VAR_16 = VAR_15 + VAR_3->VAR_7[0]->w;

        int VAR_17 = VAR_3->VAR_7[0]->y, VAR_18 = VAR_17 + VAR_3->VAR_7[0]->VAR_3;

        for (VAR_6 = 1; VAR_6 < VAR_7; VAR_6++) {

            VAR_15 = FFMIN(VAR_15, VAR_3->VAR_7[VAR_6]->x);

            VAR_17 = FFMIN(VAR_17, VAR_3->VAR_7[VAR_6]->y);

            VAR_16 = FFMAX(VAR_16, VAR_3->VAR_7[VAR_6]->x + VAR_3->VAR_7[VAR_6]->w);

            VAR_18 = FFMAX(VAR_18, VAR_3->VAR_7[VAR_6]->y + VAR_3->VAR_7[VAR_6]->VAR_3);


        vrect.x = VAR_15;

        vrect.y = VAR_17;

        vrect.w = VAR_16 - VAR_15;

        vrect.VAR_3 = VAR_18 - VAR_17;

        if ((VAR_8 = av_image_check_size(vrect.w, vrect.VAR_3, 0, VAR_0)) < 0)

            return VAR_8;



        

        VAR_9[0] = vrect.w * vrect.VAR_3;


            VAR_9[0] -= VAR_3->VAR_7[VAR_6]->w * VAR_3->VAR_7[VAR_6]->VAR_3;





        count_colors(VAR_0, VAR_9, VAR_3->VAR_7[VAR_6]);

    select_palette(VAR_0, VAR_11, VAR_12, VAR_9);



    if (VAR_7 > 1) {

        if (!(vrect_data = av_calloc(vrect.w, vrect.VAR_3)))

            return AVERROR(ENOMEM);

        vrect.pict.data    [0] = vrect_data;

        vrect.pict.linesize[0] = vrect.w;

        for (VAR_6 = 0; VAR_6 < VAR_7; VAR_6++) {

            build_color_map(VAR_0, VAR_10, (uint32_t *)VAR_3->VAR_7[VAR_6]->pict.data[1],

                            VAR_11, VAR_12);

            copy_rectangle(&vrect, VAR_3->VAR_7[VAR_6], VAR_10);


        for (VAR_6 = 0; VAR_6 < 4; VAR_6++)

            VAR_10[VAR_6] = VAR_6;

    } else {

        build_color_map(VAR_0, VAR_10, (uint32_t *)VAR_3->VAR_7[0]->pict.data[1],

                        VAR_11, VAR_12);




    av_log(VAR_0, AV_LOG_DEBUG, "Selected palette:");

    for (VAR_6 = 0; VAR_6 < 4; VAR_6++)

        av_log(VAR_0, AV_LOG_DEBUG, " 0x%06x@@%02x (0x%x,0x%x)",

               dvdc->global_palette[VAR_11[VAR_6]], VAR_12[VAR_6],

               VAR_11[VAR_6], VAR_12[VAR_6] >> 4);

    av_log(VAR_0, AV_LOG_DEBUG, "\n");



    

    q = VAR_1 + 4;

    VAR_4 = q - VAR_1;

    

    if ((q - VAR_1) + vrect.w * vrect.VAR_3 / 2 + 17 + 21 > VAR_2) {

        av_log(NULL, AV_LOG_ERROR, "dvd_subtitle too big\n");

        VAR_8 = AVERROR_BUFFER_TOO_SMALL;

        goto fail;


    dvd_encode_rle(&q, vrect.pict.data[0], vrect.w * 2,

                   vrect.w, (vrect.VAR_3 + 1) >> 1, VAR_10);

    VAR_5 = q - VAR_1;

    dvd_encode_rle(&q, vrect.pict.data[0] + vrect.w, vrect.w * 2,

                   vrect.w, vrect.VAR_3 >> 1, VAR_10);



    

    qq = VAR_1 + 2;

    bytestream_put_be16(&qq, q - VAR_1);



    

    bytestream_put_be16(&q, (VAR_3->start_display_time*90) >> 10);

    bytestream_put_be16(&q, (q - VAR_1)  + 8 + 12 + 2);

    *q++ = 0x03; 

    *q++ = (VAR_11[3] << 4) | VAR_11[2];

    *q++ = (VAR_11[1] << 4) | VAR_11[0];

    *q++ = 0x04; 

    *q++ = (VAR_12[3] & 0xF0) | (VAR_12[2] >> 4);

    *q++ = (VAR_12[1] & 0xF0) | (VAR_12[0] >> 4);



    

    VAR_13 = vrect.x + vrect.w - 1;

    VAR_14 = vrect.y + vrect.VAR_3 - 1;



    *q++ = 0x05;

    

    *q++ = vrect.x >> 4;

    *q++ = (vrect.x << 4) | ((VAR_13 >> 8) & 0xf);

    *q++ = VAR_13;

    

    *q++ = vrect.y >> 4;

    *q++ = (vrect.y << 4) | ((VAR_14 >> 8) & 0xf);

    *q++ = VAR_14;



    *q++ = 0x06;

    

    bytestream_put_be16(&q, VAR_4);

    bytestream_put_be16(&q, VAR_5);



    *q++ = 0x01; 

    *q++ = 0xff; 



    

    bytestream_put_be16(&q, (VAR_3->end_display_time*90) >> 10);

    bytestream_put_be16(&q, (q - VAR_1) - 2 );

    *q++ = 0x02; 

    *q++ = 0xff; 



    qq = VAR_1;

    bytestream_put_be16(&qq, q - VAR_1);



    av_log(NULL, AV_LOG_DEBUG, "subtitle_packet size=%td\n", q - VAR_1);

    VAR_8 = q - VAR_1;



fail:

    av_free(vrect_data);

    return VAR_8;

static int FUNC_0(AVCodecContext *VAR_0,
uint8_t *VAR_1, int VAR_2,
const AVSubtitle *VAR_3)
{ DVDSubtitleContext *dvdc = VAR_0->priv_data; uint8_t *q, *qq; int VAR_4, VAR_5; int VAR_6, VAR_7 = VAR_3->num_rects, VAR_8; unsigned VAR_9[33] = { 0 }; int VAR_10[256]; int VAR_11[4]; int VAR_12[4]; AVSubtitleRect vrect; uint8_t *vrect_data = NULL; int VAR_13, VAR_14; if (VAR_7 == 0 || VAR_3->VAR_7 == NULL)
vrect = *VAR_3->VAR_7[0]; if (VAR_7 > 1) { int VAR_15 = VAR_3->VAR_7[0]->x, VAR_16 = VAR_15 + VAR_3->VAR_7[0]->w; int VAR_17 = VAR_3->VAR_7[0]->y, VAR_18 = VAR_17 + VAR_3->VAR_7[0]->VAR_3; for (VAR_6 = 1; VAR_6 < VAR_7; VAR_6++) { VAR_15 = FFMIN(VAR_15, VAR_3->VAR_7[VAR_6]->x); VAR_17 = FFMIN(VAR_17, VAR_3->VAR_7[VAR_6]->y); VAR_16 = FFMAX(VAR_16, VAR_3->VAR_7[VAR_6]->x + VAR_3->VAR_7[VAR_6]->w); VAR_18 = FFMAX(VAR_18, VAR_3->VAR_7[VAR_6]->y + VAR_3->VAR_7[VAR_6]->VAR_3); vrect.x = VAR_15; vrect.y = VAR_17; vrect.w = VAR_16 - VAR_15; vrect.VAR_3 = VAR_18 - VAR_17; if ((VAR_8 = av_image_check_size(vrect.w, vrect.VAR_3, 0, VAR_0)) < 0)
return VAR_8; VAR_9[0] = vrect.w * vrect.VAR_3; VAR_9[0] -= VAR_3->VAR_7[VAR_6]->w * VAR_3->VAR_7[VAR_6]->VAR_3; count_colors(VAR_0, VAR_9, VAR_3->VAR_7[VAR_6]); select_palette(VAR_0, VAR_11, VAR_12, VAR_9); if (VAR_7 > 1) { if (!(vrect_data = av_calloc(vrect.w, vrect.VAR_3)))
return AVERROR(ENOMEM); vrect.pict.data    [0] = vrect_data; vrect.pict.linesize[0] = vrect.w; for (VAR_6 = 0; VAR_6 < VAR_7; VAR_6++) { build_color_map(VAR_0, VAR_10, (uint32_t *)VAR_3->VAR_7[VAR_6]->pict.data[1],
VAR_11, VAR_12); copy_rectangle(&vrect, VAR_3->VAR_7[VAR_6], VAR_10); for (VAR_6 = 0; VAR_6 < 4; VAR_6++) VAR_10[VAR_6] = VAR_6; } else { build_color_map(VAR_0, VAR_10, (uint32_t *)VAR_3->VAR_7[0]->pict.data[1],
VAR_11, VAR_12); av_log(VAR_0, AV_LOG_DEBUG, "Selected palette:"); for (VAR_6 = 0; VAR_6 < 4; VAR_6++) av_log(VAR_0, AV_LOG_DEBUG, " 0x%06x@@%02x (0x%x,0x%x)",
dvdc->global_palette[VAR_11[VAR_6]], VAR_12[VAR_6],
VAR_11[VAR_6], VAR_12[VAR_6] >> 4); av_log(VAR_0, AV_LOG_DEBUG, "\n"); q = VAR_1 + 4; VAR_4 = q - VAR_1; if ((q - VAR_1) + vrect.w * vrect.VAR_3 / 2 + 17 + 21 > VAR_2) { av_log(NULL, AV_LOG_ERROR, "dvd_subtitle too big\n"); VAR_8 = AVERROR_BUFFER_TOO_SMALL; goto fail; dvd_encode_rle(&q, vrect.pict.data[0], vrect.w * 2,
vrect.w, (vrect.VAR_3 + 1) >> 1, VAR_10); VAR_5 = q - VAR_1; dvd_encode_rle(&q, vrect.pict.data[0] + vrect.w, vrect.w * 2,
vrect.w, vrect.VAR_3 >> 1, VAR_10); qq = VAR_1 + 2; bytestream_put_be16(&qq, q - VAR_1); bytestream_put_be16(&q, (VAR_3->start_display_time*90) >> 10); bytestream_put_be16(&q, (q - VAR_1)  + 8 + 12 + 2); *q++ = 0x03; *q++ = (VAR_11[3] << 4) | VAR_11[2]; *q++ = (VAR_11[1] << 4) | VAR_11[0]; *q++ = 0x04; *q++ = (VAR_12[3] & 0xF0) | (VAR_12[2] >> 4); *q++ = (VAR_12[1] & 0xF0) | (VAR_12[0] >> 4); VAR_13 = vrect.x + vrect.w - 1; VAR_14 = vrect.y + vrect.VAR_3 - 1; *q++ = 0x05; *q++ = vrect.x >> 4; *q++ = (vrect.x << 4) | ((VAR_13 >> 8) & 0xf); *q++ = VAR_13; *q++ = vrect.y >> 4; *q++ = (vrect.y << 4) | ((VAR_14 >> 8) & 0xf); *q++ = VAR_14; *q++ = 0x06; bytestream_put_be16(&q, VAR_4); bytestream_put_be16(&q, VAR_5); *q++ = 0x01; *q++ = 0xff; bytestream_put_be16(&q, (VAR_3->end_display_time*90) >> 10); bytestream_put_be16(&q, (q - VAR_1) - 2 ); *q++ = 0x02; *q++ = 0xff; qq = VAR_1; bytestream_put_be16(&qq, q - VAR_1); av_log(NULL, AV_LOG_DEBUG, "subtitle_packet size=%td\n", q - VAR_1); VAR_8 = q - VAR_1; fail:
av_free(vrect_data); return VAR_8;