static void dvbsub_parse_pixel_data_block(AVCodecContext *avctx, DVBSubObjectDisplay *display,

                                          const uint8_t *buf, int buf_size, int top_bottom, int non_mod)

{

    DVBSubContext *ctx = avctx->priv_data;



    DVBSubRegion *region = get_region(ctx, display->region_id);

    const uint8_t *buf_end = buf + buf_size;

    uint8_t *pbuf;

    int x_pos, y_pos;

    int i;



    uint8_t map2to4[] = { 0x0,  0x7,  0x8,  0xf};

    uint8_t map2to8[] = {0x00, 0x77, 0x88, 0xff};

    uint8_t map4to8[] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,

                         0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff};

    uint8_t *map_table;



#if 0

    av_dlog(avctx, "DVB pixel block size %d, %s field:\n", buf_size,

            top_bottom ? "bottom" : "top");



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

        if (i % 16 == 0)

            av_dlog(avctx, "0x%8p: ", buf+i);



        av_dlog(avctx, "%02x ", buf[i]);

        if (i % 16 == 15)

            av_dlog(avctx, "\n");

    }



    if (i % 16)

        av_dlog(avctx, "\n");

#endif



    if (region == 0)

        return;



    pbuf = region->pbuf;

    region->dirty = 1;



    x_pos = display->x_pos;

    y_pos = display->y_pos;



    if ((y_pos & 1) != top_bottom)

        y_pos++;



    while (buf < buf_end) {

        if (x_pos > region->width || y_pos > region->height) {

            av_log(avctx, AV_LOG_ERROR, "Invalid object location!\n");

            return;

        }



        switch (*buf++) {

        case 0x10:

            if (region->depth == 8)

                map_table = map2to8;

            else if (region->depth == 4)

                map_table = map2to4;

            else

                map_table = NULL;



            x_pos += dvbsub_read_2bit_string(pbuf + (y_pos * region->width) + x_pos,

                                                region->width - x_pos, &buf, buf_end - buf,

                                                non_mod, map_table);

            break;

        case 0x11:

            if (region->depth < 4) {

                av_log(avctx, AV_LOG_ERROR, "4-bit pixel string in %d-bit region!\n", region->depth);

                return;

            }



            if (region->depth == 8)

                map_table = map4to8;

            else

                map_table = NULL;



            x_pos += dvbsub_read_4bit_string(pbuf + (y_pos * region->width) + x_pos,

                                                region->width - x_pos, &buf, buf_end - buf,

                                                non_mod, map_table);

            break;

        case 0x12:

            if (region->depth < 8) {

                av_log(avctx, AV_LOG_ERROR, "8-bit pixel string in %d-bit region!\n", region->depth);

                return;

            }



            x_pos += dvbsub_read_8bit_string(pbuf + (y_pos * region->width) + x_pos,

                                                region->width - x_pos, &buf, buf_end - buf,

                                                non_mod, NULL);

            break;



        case 0x20:

            map2to4[0] = (*buf) >> 4;

            map2to4[1] = (*buf++) & 0xf;

            map2to4[2] = (*buf) >> 4;

            map2to4[3] = (*buf++) & 0xf;

            break;

        case 0x21:

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

                map2to8[i] = *buf++;

            break;

        case 0x22:

            for (i = 0; i < 16; i++)

                map4to8[i] = *buf++;

            break;



        case 0xf0:

            x_pos = display->x_pos;

            y_pos += 2;

            break;

        default:

            av_log(avctx, AV_LOG_INFO, "Unknown/unsupported pixel block 0x%x\n", *(buf-1));

        }

    }



}
