static void dvbsub_parse_region_segment(AVCodecContext *avctx,

                                        const uint8_t *buf, int buf_size)

{

    DVBSubContext *ctx = avctx->priv_data;



    const uint8_t *buf_end = buf + buf_size;

    int region_id, object_id;

    int av_unused version;

    DVBSubRegion *region;

    DVBSubObject *object;

    DVBSubObjectDisplay *display;

    int fill;



    if (buf_size < 10)




    region_id = *buf++;



    region = get_region(ctx, region_id);



    if (!region) {

        region = av_mallocz(sizeof(DVBSubRegion));





        region->id = region_id;

        region->version = -1;



        region->next = ctx->region_list;

        ctx->region_list = region;

    }



    version = ((*buf)>>4) & 15;

    fill = ((*buf++) >> 3) & 1;



    region->width = AV_RB16(buf);

    buf += 2;

    region->height = AV_RB16(buf);

    buf += 2;



    if (region->width * region->height != region->buf_size) {

        av_free(region->pbuf);



        region->buf_size = region->width * region->height;



        region->pbuf = av_malloc(region->buf_size);



        fill = 1;

        region->dirty = 0;

    }



    region->depth = 1 << (((*buf++) >> 2) & 7);

    if(region->depth<2 || region->depth>8){

        av_log(avctx, AV_LOG_ERROR, "region depth %d is invalid\n", region->depth);

        region->depth= 4;

    }

    region->clut = *buf++;



    if (region->depth == 8) {

        region->bgcolor = *buf++;

        buf += 1;

    } else {

        buf += 1;



        if (region->depth == 4)

            region->bgcolor = (((*buf++) >> 4) & 15);

        else

            region->bgcolor = (((*buf++) >> 2) & 3);

    }



    av_dlog(avctx, "Region %d, (%dx%d)\n", region_id, region->width, region->height);



    if (fill) {

        memset(region->pbuf, region->bgcolor, region->buf_size);

        av_dlog(avctx, "Fill region (%d)\n", region->bgcolor);

    }



    delete_region_display_list(ctx, region);



    while (buf + 5 < buf_end) {

        object_id = AV_RB16(buf);

        buf += 2;



        object = get_object(ctx, object_id);



        if (!object) {

            object = av_mallocz(sizeof(DVBSubObject));



            object->id = object_id;

            object->next = ctx->object_list;

            ctx->object_list = object;

        }



        object->type = (*buf) >> 6;



        display = av_mallocz(sizeof(DVBSubObjectDisplay));



        display->object_id = object_id;

        display->region_id = region_id;



        display->x_pos = AV_RB16(buf) & 0xfff;

        buf += 2;

        display->y_pos = AV_RB16(buf) & 0xfff;

        buf += 2;



        if ((object->type == 1 || object->type == 2) && buf+1 < buf_end) {

            display->fgcolor = *buf++;

            display->bgcolor = *buf++;

        }



        display->region_list_next = region->display_list;

        region->display_list = display;



        display->object_list_next = object->display_list;

        object->display_list = display;

    }

}