static int parse_bintree(Indeo3DecodeContext *ctx, AVCodecContext *avctx,

                         Plane *plane, int code, Cell *ref_cell,

                         const int depth, const int strip_width)

{

    Cell    curr_cell;

    int     bytes_used;



    if (depth <= 0) {

        av_log(avctx, AV_LOG_ERROR, "Stack overflow (corrupted binary tree)!\n");

        return AVERROR_INVALIDDATA; // unwind recursion

    }



    curr_cell = *ref_cell; // clone parent cell

    if (code == H_SPLIT) {

        SPLIT_CELL(ref_cell->height, curr_cell.height);

        ref_cell->ypos   += curr_cell.height;

        ref_cell->height -= curr_cell.height;

    } else if (code == V_SPLIT) {

        if (curr_cell.width > strip_width) {

            /* split strip */

            curr_cell.width = (curr_cell.width <= (strip_width << 1) ? 1 : 2) * strip_width;

        } else

            SPLIT_CELL(ref_cell->width, curr_cell.width);

        ref_cell->xpos  += curr_cell.width;

        ref_cell->width -= curr_cell.width;

    }



    while (1) { /* loop until return */

        RESYNC_BITSTREAM;

        switch (code = get_bits(&ctx->gb, 2)) {

        case H_SPLIT:

        case V_SPLIT:

            if (parse_bintree(ctx, avctx, plane, code, &curr_cell, depth - 1, strip_width))

                return AVERROR_INVALIDDATA;

            break;

        case INTRA_NULL:

            if (!curr_cell.tree) { /* MC tree INTRA code */

                curr_cell.mv_ptr = 0; /* mark the current strip as INTRA */

                curr_cell.tree   = 1; /* enter the VQ tree */

            } else { /* VQ tree NULL code */

                RESYNC_BITSTREAM;

                code = get_bits(&ctx->gb, 2);

                if (code >= 2) {

                    av_log(avctx, AV_LOG_ERROR, "Invalid VQ_NULL code: %d\n", code);

                    return AVERROR_INVALIDDATA;

                }

                if (code == 1)

                    av_log(avctx, AV_LOG_ERROR, "SkipCell procedure not implemented yet!\n");



                CHECK_CELL

                copy_cell(ctx, plane, &curr_cell);

                return 0;

            }

            break;

        case INTER_DATA:

            if (!curr_cell.tree) { /* MC tree INTER code */

                /* get motion vector index and setup the pointer to the mv set */

                if (!ctx->need_resync)

                    ctx->next_cell_data = &ctx->gb.buffer[(get_bits_count(&ctx->gb) + 7) >> 3];

                curr_cell.mv_ptr = &ctx->mc_vectors[*(ctx->next_cell_data++) << 1];

                curr_cell.tree   = 1; /* enter the VQ tree */

                UPDATE_BITPOS(8);

            } else { /* VQ tree DATA code */

                if (!ctx->need_resync)

                    ctx->next_cell_data = &ctx->gb.buffer[(get_bits_count(&ctx->gb) + 7) >> 3];



                CHECK_CELL

                bytes_used = decode_cell(ctx, avctx, plane, &curr_cell,

                                         ctx->next_cell_data, ctx->last_byte);

                if (bytes_used < 0)

                    return AVERROR_INVALIDDATA;



                UPDATE_BITPOS(bytes_used << 3);

                ctx->next_cell_data += bytes_used;

                return 0;

            }

            break;

        }

    }//while



    return 0;

}

static int parse_bintree(Indeo3DecodeContext *ctx, AVCodecContext *avctx,

                         Plane *plane, int code, Cell *ref_cell,

                         const int depth, const int strip_width)

{

    Cell    curr_cell;

    int     bytes_used;



    if (depth <= 0) {

        av_log(avctx, AV_LOG_ERROR, "Stack overflow (corrupted binary tree)!\n");

        return AVERROR_INVALIDDATA; 

    }



    curr_cell = *ref_cell; 

    if (code == H_SPLIT) {

        SPLIT_CELL(ref_cell->height, curr_cell.height);

        ref_cell->ypos   += curr_cell.height;

        ref_cell->height -= curr_cell.height;

    } else if (code == V_SPLIT) {

        if (curr_cell.width > strip_width) {

            

            curr_cell.width = (curr_cell.width <= (strip_width << 1) ? 1 : 2) * strip_width;

        } else

            SPLIT_CELL(ref_cell->width, curr_cell.width);

        ref_cell->xpos  += curr_cell.width;

        ref_cell->width -= curr_cell.width;

    }



    while (1) { 

        RESYNC_BITSTREAM;

        switch (code = get_bits(&ctx->gb, 2)) {

        case H_SPLIT:

        case V_SPLIT:

            if (parse_bintree(ctx, avctx, plane, code, &curr_cell, depth - 1, strip_width))

                return AVERROR_INVALIDDATA;

            break;

        case INTRA_NULL:

            if (!curr_cell.tree) { 

                curr_cell.mv_ptr = 0; 

                curr_cell.tree   = 1; 

            } else { 

                RESYNC_BITSTREAM;

                code = get_bits(&ctx->gb, 2);

                if (code >= 2) {

                    av_log(avctx, AV_LOG_ERROR, "Invalid VQ_NULL code: %d\n", code);

                    return AVERROR_INVALIDDATA;

                }

                if (code == 1)

                    av_log(avctx, AV_LOG_ERROR, "SkipCell procedure not implemented yet!\n");



                CHECK_CELL

                copy_cell(ctx, plane, &curr_cell);

                return 0;

            }

            break;

        case INTER_DATA:

            if (!curr_cell.tree) { 

                

                if (!ctx->need_resync)

                    ctx->next_cell_data = &ctx->gb.buffer[(get_bits_count(&ctx->gb) + 7) >> 3];

                curr_cell.mv_ptr = &ctx->mc_vectors[*(ctx->next_cell_data++) << 1];

                curr_cell.tree   = 1; 

                UPDATE_BITPOS(8);

            } else { 

                if (!ctx->need_resync)

                    ctx->next_cell_data = &ctx->gb.buffer[(get_bits_count(&ctx->gb) + 7) >> 3];



                CHECK_CELL

                bytes_used = decode_cell(ctx, avctx, plane, &curr_cell,

                                         ctx->next_cell_data, ctx->last_byte);

                if (bytes_used < 0)

                    return AVERROR_INVALIDDATA;



                UPDATE_BITPOS(bytes_used << 3);

                ctx->next_cell_data += bytes_used;

                return 0;

            }

            break;

        }

    }



    return 0;

}

static int FUNC_0(Indeo3DecodeContext *VAR_0, AVCodecContext *VAR_1,

                         Plane *VAR_2, int VAR_3, Cell *VAR_4,

                         const int VAR_5, const int VAR_6)

{

    Cell    curr_cell;

    int     VAR_7;



    if (VAR_5 <= 0) {

        av_log(VAR_1, AV_LOG_ERROR, "Stack overflow (corrupted binary tree)!\n");

        return AVERROR_INVALIDDATA; 

    }



    curr_cell = *VAR_4; 

    if (VAR_3 == H_SPLIT) {

        SPLIT_CELL(VAR_4->height, curr_cell.height);

        VAR_4->ypos   += curr_cell.height;

        VAR_4->height -= curr_cell.height;

    } else if (VAR_3 == V_SPLIT) {

        if (curr_cell.width > VAR_6) {

            

            curr_cell.width = (curr_cell.width <= (VAR_6 << 1) ? 1 : 2) * VAR_6;

        } else

            SPLIT_CELL(VAR_4->width, curr_cell.width);

        VAR_4->xpos  += curr_cell.width;

        VAR_4->width -= curr_cell.width;

    }



    while (1) { 

        RESYNC_BITSTREAM;

        switch (VAR_3 = get_bits(&VAR_0->gb, 2)) {

        case H_SPLIT:

        case V_SPLIT:

            if (FUNC_0(VAR_0, VAR_1, VAR_2, VAR_3, &curr_cell, VAR_5 - 1, VAR_6))

                return AVERROR_INVALIDDATA;

            break;

        case INTRA_NULL:

            if (!curr_cell.tree) { 

                curr_cell.mv_ptr = 0; 

                curr_cell.tree   = 1; 

            } else { 

                RESYNC_BITSTREAM;

                VAR_3 = get_bits(&VAR_0->gb, 2);

                if (VAR_3 >= 2) {

                    av_log(VAR_1, AV_LOG_ERROR, "Invalid VQ_NULL VAR_3: %d\n", VAR_3);

                    return AVERROR_INVALIDDATA;

                }

                if (VAR_3 == 1)

                    av_log(VAR_1, AV_LOG_ERROR, "SkipCell procedure not implemented yet!\n");



                CHECK_CELL

                copy_cell(VAR_0, VAR_2, &curr_cell);

                return 0;

            }

            break;

        case INTER_DATA:

            if (!curr_cell.tree) { 

                

                if (!VAR_0->need_resync)

                    VAR_0->next_cell_data = &VAR_0->gb.buffer[(get_bits_count(&VAR_0->gb) + 7) >> 3];

                curr_cell.mv_ptr = &VAR_0->mc_vectors[*(VAR_0->next_cell_data++) << 1];

                curr_cell.tree   = 1; 

                UPDATE_BITPOS(8);

            } else { 

                if (!VAR_0->need_resync)

                    VAR_0->next_cell_data = &VAR_0->gb.buffer[(get_bits_count(&VAR_0->gb) + 7) >> 3];



                CHECK_CELL

                VAR_7 = decode_cell(VAR_0, VAR_1, VAR_2, &curr_cell,

                                         VAR_0->next_cell_data, VAR_0->last_byte);

                if (VAR_7 < 0)

                    return AVERROR_INVALIDDATA;



                UPDATE_BITPOS(VAR_7 << 3);

                VAR_0->next_cell_data += VAR_7;

                return 0;

            }

            break;

        }

    }



    return 0;

}

static int FUNC_0(Indeo3DecodeContext *VAR_0, AVCodecContext *VAR_1,
Plane *VAR_2, int VAR_3, Cell *VAR_4,
const int VAR_5, const int VAR_6)
{ Cell    curr_cell; int     VAR_7; if (VAR_5 <= 0) { av_log(VAR_1, AV_LOG_ERROR, "Stack overflow (corrupted binary tree)!\n"); return AVERROR_INVALIDDATA; } curr_cell = *VAR_4; if (VAR_3 == H_SPLIT) { SPLIT_CELL(VAR_4->height, curr_cell.height); VAR_4->ypos   += curr_cell.height; VAR_4->height -= curr_cell.height; } else if (VAR_3 == V_SPLIT) { if (curr_cell.width > VAR_6) { curr_cell.width = (curr_cell.width <= (VAR_6 << 1) ? 1 : 2) * VAR_6; } else SPLIT_CELL(VAR_4->width, curr_cell.width); VAR_4->xpos  += curr_cell.width; VAR_4->width -= curr_cell.width; } while (1) { RESYNC_BITSTREAM; switch (VAR_3 = get_bits(&VAR_0->gb, 2)) { case H_SPLIT:
case V_SPLIT:
if (FUNC_0(VAR_0, VAR_1, VAR_2, VAR_3, &curr_cell, VAR_5 - 1, VAR_6))
return AVERROR_INVALIDDATA; break; case INTRA_NULL:
if (!curr_cell.tree) { curr_cell.mv_ptr = 0; curr_cell.tree   = 1; } else { RESYNC_BITSTREAM; VAR_3 = get_bits(&VAR_0->gb, 2); if (VAR_3 >= 2) { av_log(VAR_1, AV_LOG_ERROR, "Invalid VQ_NULL VAR_3: %d\n", VAR_3); return AVERROR_INVALIDDATA; } if (VAR_3 == 1)
av_log(VAR_1, AV_LOG_ERROR, "SkipCell procedure not implemented yet!\n"); CHECK_CELL
copy_cell(VAR_0, VAR_2, &curr_cell); return 0; } break; case INTER_DATA:
if (!curr_cell.tree) { if (!VAR_0->need_resync)
VAR_0->next_cell_data = &VAR_0->gb.buffer[(get_bits_count(&VAR_0->gb) + 7) >> 3]; curr_cell.mv_ptr = &VAR_0->mc_vectors[*(VAR_0->next_cell_data++) << 1]; curr_cell.tree   = 1; UPDATE_BITPOS(8); } else { if (!VAR_0->need_resync)
VAR_0->next_cell_data = &VAR_0->gb.buffer[(get_bits_count(&VAR_0->gb) + 7) >> 3]; CHECK_CELL
VAR_7 = decode_cell(VAR_0, VAR_1, VAR_2, &curr_cell,
VAR_0->next_cell_data, VAR_0->last_byte); if (VAR_7 < 0)
return AVERROR_INVALIDDATA; UPDATE_BITPOS(VAR_7 << 3); VAR_0->next_cell_data += VAR_7; return 0; } break; } } return 0; }