static int bink_decode_plane(BinkContext *c, AVFrame *frame, GetBitContext *gb,

                             int plane_idx, int is_chroma)

{

    int blk, ret;

    int i, j, bx, by;

    uint8_t *dst, *prev, *ref, *ref_start, *ref_end;

    int v, col[2];

    const uint8_t *scan;

    int xoff, yoff;

    LOCAL_ALIGNED_16(int16_t, block, [64]);

    LOCAL_ALIGNED_16(uint8_t, ublock, [64]);

    LOCAL_ALIGNED_16(int32_t, dctblock, [64]);

    int coordmap[64];



    const int stride = frame->linesize[plane_idx];

    int bw = is_chroma ? (c->avctx->width  + 15) >> 4 : (c->avctx->width  + 7) >> 3;

    int bh = is_chroma ? (c->avctx->height + 15) >> 4 : (c->avctx->height + 7) >> 3;

    int width = c->avctx->width >> is_chroma;



    init_lengths(c, FFMAX(width, 8), bw);

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

        read_bundle(gb, c, i);



    ref_start = c->last->data[plane_idx] ? c->last->data[plane_idx]

                                         : frame->data[plane_idx];

    ref_end   = ref_start

                + (bw - 1 + c->last->linesize[plane_idx] * (bh - 1)) * 8;



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

        coordmap[i] = (i & 7) + (i >> 3) * stride;



    for (by = 0; by < bh; by++) {

        if ((ret = read_block_types(c->avctx, gb, &c->bundle[BINK_SRC_BLOCK_TYPES])) < 0)

            return ret;

        if ((ret = read_block_types(c->avctx, gb, &c->bundle[BINK_SRC_SUB_BLOCK_TYPES])) < 0)

            return ret;

        if ((ret = read_colors(gb, &c->bundle[BINK_SRC_COLORS], c)) < 0)

            return ret;

        if ((ret = read_patterns(c->avctx, gb, &c->bundle[BINK_SRC_PATTERN])) < 0)

            return ret;

        if ((ret = read_motion_values(c->avctx, gb, &c->bundle[BINK_SRC_X_OFF])) < 0)

            return ret;

        if ((ret = read_motion_values(c->avctx, gb, &c->bundle[BINK_SRC_Y_OFF])) < 0)

            return ret;

        if ((ret = read_dcs(c->avctx, gb, &c->bundle[BINK_SRC_INTRA_DC], DC_START_BITS, 0)) < 0)

            return ret;

        if ((ret = read_dcs(c->avctx, gb, &c->bundle[BINK_SRC_INTER_DC], DC_START_BITS, 1)) < 0)

            return ret;

        if ((ret = read_runs(c->avctx, gb, &c->bundle[BINK_SRC_RUN])) < 0)

            return ret;



        if (by == bh)

            break;

        dst  = frame->data[plane_idx]  + 8*by*stride;

        prev = (c->last->data[plane_idx] ? c->last->data[plane_idx]

                                         : frame->data[plane_idx]) + 8*by*stride;

        for (bx = 0; bx < bw; bx++, dst += 8, prev += 8) {

            blk = get_value(c, BINK_SRC_BLOCK_TYPES);

            // 16x16 block type on odd line means part of the already decoded block, so skip it

            if ((by & 1) && blk == SCALED_BLOCK) {

                bx++;

                dst  += 8;

                prev += 8;

                continue;

            }

            switch (blk) {

            case SKIP_BLOCK:

                c->hdsp.put_pixels_tab[1][0](dst, prev, stride, 8);

                break;

            case SCALED_BLOCK:

                blk = get_value(c, BINK_SRC_SUB_BLOCK_TYPES);

                switch (blk) {

                case RUN_BLOCK:

                    scan = bink_patterns[get_bits(gb, 4)];

                    i = 0;

                    do {

                        int run = get_value(c, BINK_SRC_RUN) + 1;



                        i += run;

                        if (i > 64) {

                            av_log(c->avctx, AV_LOG_ERROR, "Run went out of bounds\n");

                            return AVERROR_INVALIDDATA;

                        }

                        if (get_bits1(gb)) {

                            v = get_value(c, BINK_SRC_COLORS);

                            for (j = 0; j < run; j++)

                                ublock[*scan++] = v;

                        } else {

                            for (j = 0; j < run; j++)

                                ublock[*scan++] = get_value(c, BINK_SRC_COLORS);

                        }

                    } while (i < 63);

                    if (i == 63)

                        ublock[*scan++] = get_value(c, BINK_SRC_COLORS);

                    break;

                case INTRA_BLOCK:

                    memset(dctblock, 0, sizeof(*dctblock) * 64);

                    dctblock[0] = get_value(c, BINK_SRC_INTRA_DC);

                    read_dct_coeffs(gb, dctblock, bink_scan, bink_intra_quant, -1);

                    c->binkdsp.idct_put(ublock, 8, dctblock);

                    break;

                case FILL_BLOCK:

                    v = get_value(c, BINK_SRC_COLORS);

                    c->bdsp.fill_block_tab[0](dst, v, stride, 16);

                    break;

                case PATTERN_BLOCK:

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

                        col[i] = get_value(c, BINK_SRC_COLORS);

                    for (j = 0; j < 8; j++) {

                        v = get_value(c, BINK_SRC_PATTERN);

                        for (i = 0; i < 8; i++, v >>= 1)

                            ublock[i + j*8] = col[v & 1];

                    }

                    break;

                case RAW_BLOCK:

                    for (j = 0; j < 8; j++)

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

                            ublock[i + j*8] = get_value(c, BINK_SRC_COLORS);

                    break;

                default:

                    av_log(c->avctx, AV_LOG_ERROR, "Incorrect 16x16 block type %d\n", blk);

                    return AVERROR_INVALIDDATA;

                }

                if (blk != FILL_BLOCK)

                c->binkdsp.scale_block(ublock, dst, stride);

                bx++;

                dst  += 8;

                prev += 8;

                break;

            case MOTION_BLOCK:

                xoff = get_value(c, BINK_SRC_X_OFF);

                yoff = get_value(c, BINK_SRC_Y_OFF);

                ref = prev + xoff + yoff * stride;

                if (ref < ref_start || ref > ref_end) {

                    av_log(c->avctx, AV_LOG_ERROR, "Copy out of bounds @%d, %d\n",

                           bx*8 + xoff, by*8 + yoff);

                    return AVERROR_INVALIDDATA;

                }

                c->hdsp.put_pixels_tab[1][0](dst, ref, stride, 8);

                break;

            case RUN_BLOCK:

                scan = bink_patterns[get_bits(gb, 4)];

                i = 0;

                do {

                    int run = get_value(c, BINK_SRC_RUN) + 1;



                    i += run;

                    if (i > 64) {

                        av_log(c->avctx, AV_LOG_ERROR, "Run went out of bounds\n");

                        return AVERROR_INVALIDDATA;

                    }

                    if (get_bits1(gb)) {

                        v = get_value(c, BINK_SRC_COLORS);

                        for (j = 0; j < run; j++)

                            dst[coordmap[*scan++]] = v;

                    } else {

                        for (j = 0; j < run; j++)

                            dst[coordmap[*scan++]] = get_value(c, BINK_SRC_COLORS);

                    }

                } while (i < 63);

                if (i == 63)

                    dst[coordmap[*scan++]] = get_value(c, BINK_SRC_COLORS);

                break;

            case RESIDUE_BLOCK:

                xoff = get_value(c, BINK_SRC_X_OFF);

                yoff = get_value(c, BINK_SRC_Y_OFF);

                ref = prev + xoff + yoff * stride;

                if (ref < ref_start || ref > ref_end) {

                    av_log(c->avctx, AV_LOG_ERROR, "Copy out of bounds @%d, %d\n",

                           bx*8 + xoff, by*8 + yoff);

                    return AVERROR_INVALIDDATA;

                }

                c->hdsp.put_pixels_tab[1][0](dst, ref, stride, 8);

                c->bdsp.clear_block(block);

                v = get_bits(gb, 7);

                read_residue(gb, block, v);

                c->binkdsp.add_pixels8(dst, block, stride);

                break;

            case INTRA_BLOCK:

                memset(dctblock, 0, sizeof(*dctblock) * 64);

                dctblock[0] = get_value(c, BINK_SRC_INTRA_DC);

                read_dct_coeffs(gb, dctblock, bink_scan, bink_intra_quant, -1);

                c->binkdsp.idct_put(dst, stride, dctblock);

                break;

            case FILL_BLOCK:

                v = get_value(c, BINK_SRC_COLORS);

                c->bdsp.fill_block_tab[1](dst, v, stride, 8);

                break;

            case INTER_BLOCK:

                xoff = get_value(c, BINK_SRC_X_OFF);

                yoff = get_value(c, BINK_SRC_Y_OFF);

                ref = prev + xoff + yoff * stride;

                c->hdsp.put_pixels_tab[1][0](dst, ref, stride, 8);

                memset(dctblock, 0, sizeof(*dctblock) * 64);

                dctblock[0] = get_value(c, BINK_SRC_INTER_DC);

                read_dct_coeffs(gb, dctblock, bink_scan, bink_inter_quant, -1);

                c->binkdsp.idct_add(dst, stride, dctblock);

                break;

            case PATTERN_BLOCK:

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

                    col[i] = get_value(c, BINK_SRC_COLORS);

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

                    v = get_value(c, BINK_SRC_PATTERN);

                    for (j = 0; j < 8; j++, v >>= 1)

                        dst[i*stride + j] = col[v & 1];

                }

                break;

            case RAW_BLOCK:

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

                    memcpy(dst + i*stride, c->bundle[BINK_SRC_COLORS].cur_ptr + i*8, 8);

                c->bundle[BINK_SRC_COLORS].cur_ptr += 64;

                break;

            default:

                av_log(c->avctx, AV_LOG_ERROR, "Unknown block type %d\n", blk);

                return AVERROR_INVALIDDATA;

            }

        }

    }

    if (get_bits_count(gb) & 0x1F) //next plane data starts at 32-bit boundary

        skip_bits_long(gb, 32 - (get_bits_count(gb) & 0x1F));



    return 0;

}

static int bink_decode_plane(BinkContext *c, AVFrame *frame, GetBitContext *gb,

                             int plane_idx, int is_chroma)

{

    int blk, ret;

    int i, j, bx, by;

    uint8_t *dst, *prev, *ref, *ref_start, *ref_end;

    int v, col[2];

    const uint8_t *scan;

    int xoff, yoff;

    LOCAL_ALIGNED_16(int16_t, block, [64]);

    LOCAL_ALIGNED_16(uint8_t, ublock, [64]);

    LOCAL_ALIGNED_16(int32_t, dctblock, [64]);

    int coordmap[64];



    const int stride = frame->linesize[plane_idx];

    int bw = is_chroma ? (c->avctx->width  + 15) >> 4 : (c->avctx->width  + 7) >> 3;

    int bh = is_chroma ? (c->avctx->height + 15) >> 4 : (c->avctx->height + 7) >> 3;

    int width = c->avctx->width >> is_chroma;



    init_lengths(c, FFMAX(width, 8), bw);

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

        read_bundle(gb, c, i);



    ref_start = c->last->data[plane_idx] ? c->last->data[plane_idx]

                                         : frame->data[plane_idx];

    ref_end   = ref_start

                + (bw - 1 + c->last->linesize[plane_idx] * (bh - 1)) * 8;



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

        coordmap[i] = (i & 7) + (i >> 3) * stride;



    for (by = 0; by < bh; by++) {

        if ((ret = read_block_types(c->avctx, gb, &c->bundle[BINK_SRC_BLOCK_TYPES])) < 0)

            return ret;

        if ((ret = read_block_types(c->avctx, gb, &c->bundle[BINK_SRC_SUB_BLOCK_TYPES])) < 0)

            return ret;

        if ((ret = read_colors(gb, &c->bundle[BINK_SRC_COLORS], c)) < 0)

            return ret;

        if ((ret = read_patterns(c->avctx, gb, &c->bundle[BINK_SRC_PATTERN])) < 0)

            return ret;

        if ((ret = read_motion_values(c->avctx, gb, &c->bundle[BINK_SRC_X_OFF])) < 0)

            return ret;

        if ((ret = read_motion_values(c->avctx, gb, &c->bundle[BINK_SRC_Y_OFF])) < 0)

            return ret;

        if ((ret = read_dcs(c->avctx, gb, &c->bundle[BINK_SRC_INTRA_DC], DC_START_BITS, 0)) < 0)

            return ret;

        if ((ret = read_dcs(c->avctx, gb, &c->bundle[BINK_SRC_INTER_DC], DC_START_BITS, 1)) < 0)

            return ret;

        if ((ret = read_runs(c->avctx, gb, &c->bundle[BINK_SRC_RUN])) < 0)

            return ret;



        if (by == bh)

            break;

        dst  = frame->data[plane_idx]  + 8*by*stride;

        prev = (c->last->data[plane_idx] ? c->last->data[plane_idx]

                                         : frame->data[plane_idx]) + 8*by*stride;

        for (bx = 0; bx < bw; bx++, dst += 8, prev += 8) {

            blk = get_value(c, BINK_SRC_BLOCK_TYPES);

            

            if ((by & 1) && blk == SCALED_BLOCK) {

                bx++;

                dst  += 8;

                prev += 8;

                continue;

            }

            switch (blk) {

            case SKIP_BLOCK:

                c->hdsp.put_pixels_tab[1][0](dst, prev, stride, 8);

                break;

            case SCALED_BLOCK:

                blk = get_value(c, BINK_SRC_SUB_BLOCK_TYPES);

                switch (blk) {

                case RUN_BLOCK:

                    scan = bink_patterns[get_bits(gb, 4)];

                    i = 0;

                    do {

                        int run = get_value(c, BINK_SRC_RUN) + 1;



                        i += run;

                        if (i > 64) {

                            av_log(c->avctx, AV_LOG_ERROR, "Run went out of bounds\n");

                            return AVERROR_INVALIDDATA;

                        }

                        if (get_bits1(gb)) {

                            v = get_value(c, BINK_SRC_COLORS);

                            for (j = 0; j < run; j++)

                                ublock[*scan++] = v;

                        } else {

                            for (j = 0; j < run; j++)

                                ublock[*scan++] = get_value(c, BINK_SRC_COLORS);

                        }

                    } while (i < 63);

                    if (i == 63)

                        ublock[*scan++] = get_value(c, BINK_SRC_COLORS);

                    break;

                case INTRA_BLOCK:

                    memset(dctblock, 0, sizeof(*dctblock) * 64);

                    dctblock[0] = get_value(c, BINK_SRC_INTRA_DC);

                    read_dct_coeffs(gb, dctblock, bink_scan, bink_intra_quant, -1);

                    c->binkdsp.idct_put(ublock, 8, dctblock);

                    break;

                case FILL_BLOCK:

                    v = get_value(c, BINK_SRC_COLORS);

                    c->bdsp.fill_block_tab[0](dst, v, stride, 16);

                    break;

                case PATTERN_BLOCK:

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

                        col[i] = get_value(c, BINK_SRC_COLORS);

                    for (j = 0; j < 8; j++) {

                        v = get_value(c, BINK_SRC_PATTERN);

                        for (i = 0; i < 8; i++, v >>= 1)

                            ublock[i + j*8] = col[v & 1];

                    }

                    break;

                case RAW_BLOCK:

                    for (j = 0; j < 8; j++)

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

                            ublock[i + j*8] = get_value(c, BINK_SRC_COLORS);

                    break;

                default:

                    av_log(c->avctx, AV_LOG_ERROR, "Incorrect 16x16 block type %d\n", blk);

                    return AVERROR_INVALIDDATA;

                }

                if (blk != FILL_BLOCK)

                c->binkdsp.scale_block(ublock, dst, stride);

                bx++;

                dst  += 8;

                prev += 8;

                break;

            case MOTION_BLOCK:

                xoff = get_value(c, BINK_SRC_X_OFF);

                yoff = get_value(c, BINK_SRC_Y_OFF);

                ref = prev + xoff + yoff * stride;

                if (ref < ref_start || ref > ref_end) {

                    av_log(c->avctx, AV_LOG_ERROR, "Copy out of bounds @%d, %d\n",

                           bx*8 + xoff, by*8 + yoff);

                    return AVERROR_INVALIDDATA;

                }

                c->hdsp.put_pixels_tab[1][0](dst, ref, stride, 8);

                break;

            case RUN_BLOCK:

                scan = bink_patterns[get_bits(gb, 4)];

                i = 0;

                do {

                    int run = get_value(c, BINK_SRC_RUN) + 1;



                    i += run;

                    if (i > 64) {

                        av_log(c->avctx, AV_LOG_ERROR, "Run went out of bounds\n");

                        return AVERROR_INVALIDDATA;

                    }

                    if (get_bits1(gb)) {

                        v = get_value(c, BINK_SRC_COLORS);

                        for (j = 0; j < run; j++)

                            dst[coordmap[*scan++]] = v;

                    } else {

                        for (j = 0; j < run; j++)

                            dst[coordmap[*scan++]] = get_value(c, BINK_SRC_COLORS);

                    }

                } while (i < 63);

                if (i == 63)

                    dst[coordmap[*scan++]] = get_value(c, BINK_SRC_COLORS);

                break;

            case RESIDUE_BLOCK:

                xoff = get_value(c, BINK_SRC_X_OFF);

                yoff = get_value(c, BINK_SRC_Y_OFF);

                ref = prev + xoff + yoff * stride;

                if (ref < ref_start || ref > ref_end) {

                    av_log(c->avctx, AV_LOG_ERROR, "Copy out of bounds @%d, %d\n",

                           bx*8 + xoff, by*8 + yoff);

                    return AVERROR_INVALIDDATA;

                }

                c->hdsp.put_pixels_tab[1][0](dst, ref, stride, 8);

                c->bdsp.clear_block(block);

                v = get_bits(gb, 7);

                read_residue(gb, block, v);

                c->binkdsp.add_pixels8(dst, block, stride);

                break;

            case INTRA_BLOCK:

                memset(dctblock, 0, sizeof(*dctblock) * 64);

                dctblock[0] = get_value(c, BINK_SRC_INTRA_DC);

                read_dct_coeffs(gb, dctblock, bink_scan, bink_intra_quant, -1);

                c->binkdsp.idct_put(dst, stride, dctblock);

                break;

            case FILL_BLOCK:

                v = get_value(c, BINK_SRC_COLORS);

                c->bdsp.fill_block_tab[1](dst, v, stride, 8);

                break;

            case INTER_BLOCK:

                xoff = get_value(c, BINK_SRC_X_OFF);

                yoff = get_value(c, BINK_SRC_Y_OFF);

                ref = prev + xoff + yoff * stride;

                c->hdsp.put_pixels_tab[1][0](dst, ref, stride, 8);

                memset(dctblock, 0, sizeof(*dctblock) * 64);

                dctblock[0] = get_value(c, BINK_SRC_INTER_DC);

                read_dct_coeffs(gb, dctblock, bink_scan, bink_inter_quant, -1);

                c->binkdsp.idct_add(dst, stride, dctblock);

                break;

            case PATTERN_BLOCK:

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

                    col[i] = get_value(c, BINK_SRC_COLORS);

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

                    v = get_value(c, BINK_SRC_PATTERN);

                    for (j = 0; j < 8; j++, v >>= 1)

                        dst[i*stride + j] = col[v & 1];

                }

                break;

            case RAW_BLOCK:

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

                    memcpy(dst + i*stride, c->bundle[BINK_SRC_COLORS].cur_ptr + i*8, 8);

                c->bundle[BINK_SRC_COLORS].cur_ptr += 64;

                break;

            default:

                av_log(c->avctx, AV_LOG_ERROR, "Unknown block type %d\n", blk);

                return AVERROR_INVALIDDATA;

            }

        }

    }

    if (get_bits_count(gb) & 0x1F) 

        skip_bits_long(gb, 32 - (get_bits_count(gb) & 0x1F));



    return 0;

}

static int FUNC_0(BinkContext *VAR_0, AVFrame *VAR_1, GetBitContext *VAR_2,

                             int VAR_3, int VAR_4)

{

    int VAR_5, VAR_6;

    int VAR_7, VAR_8, VAR_9, VAR_10;

    uint8_t *dst, *prev, *ref, *ref_start, *ref_end;

    int VAR_11, VAR_12[2];

    const uint8_t *VAR_13;

    int VAR_14, VAR_15;

    LOCAL_ALIGNED_16(int16_t, block, [64]);

    LOCAL_ALIGNED_16(uint8_t, ublock, [64]);

    LOCAL_ALIGNED_16(int32_t, dctblock, [64]);

    int VAR_16[64];



    const int VAR_17 = VAR_1->linesize[VAR_3];

    int VAR_18 = VAR_4 ? (VAR_0->avctx->VAR_20  + 15) >> 4 : (VAR_0->avctx->VAR_20  + 7) >> 3;

    int VAR_19 = VAR_4 ? (VAR_0->avctx->height + 15) >> 4 : (VAR_0->avctx->height + 7) >> 3;

    int VAR_20 = VAR_0->avctx->VAR_20 >> VAR_4;



    init_lengths(VAR_0, FFMAX(VAR_20, 8), VAR_18);

    for (VAR_7 = 0; VAR_7 < BINK_NB_SRC; VAR_7++)

        read_bundle(VAR_2, VAR_0, VAR_7);



    ref_start = VAR_0->last->data[VAR_3] ? VAR_0->last->data[VAR_3]

                                         : VAR_1->data[VAR_3];

    ref_end   = ref_start

                + (VAR_18 - 1 + VAR_0->last->linesize[VAR_3] * (VAR_19 - 1)) * 8;



    for (VAR_7 = 0; VAR_7 < 64; VAR_7++)

        VAR_16[VAR_7] = (VAR_7 & 7) + (VAR_7 >> 3) * VAR_17;



    for (VAR_10 = 0; VAR_10 < VAR_19; VAR_10++) {

        if ((VAR_6 = read_block_types(VAR_0->avctx, VAR_2, &VAR_0->bundle[BINK_SRC_BLOCK_TYPES])) < 0)

            return VAR_6;

        if ((VAR_6 = read_block_types(VAR_0->avctx, VAR_2, &VAR_0->bundle[BINK_SRC_SUB_BLOCK_TYPES])) < 0)

            return VAR_6;

        if ((VAR_6 = read_colors(VAR_2, &VAR_0->bundle[BINK_SRC_COLORS], VAR_0)) < 0)

            return VAR_6;

        if ((VAR_6 = read_patterns(VAR_0->avctx, VAR_2, &VAR_0->bundle[BINK_SRC_PATTERN])) < 0)

            return VAR_6;

        if ((VAR_6 = read_motion_values(VAR_0->avctx, VAR_2, &VAR_0->bundle[BINK_SRC_X_OFF])) < 0)

            return VAR_6;

        if ((VAR_6 = read_motion_values(VAR_0->avctx, VAR_2, &VAR_0->bundle[BINK_SRC_Y_OFF])) < 0)

            return VAR_6;

        if ((VAR_6 = read_dcs(VAR_0->avctx, VAR_2, &VAR_0->bundle[BINK_SRC_INTRA_DC], DC_START_BITS, 0)) < 0)

            return VAR_6;

        if ((VAR_6 = read_dcs(VAR_0->avctx, VAR_2, &VAR_0->bundle[BINK_SRC_INTER_DC], DC_START_BITS, 1)) < 0)

            return VAR_6;

        if ((VAR_6 = read_runs(VAR_0->avctx, VAR_2, &VAR_0->bundle[BINK_SRC_RUN])) < 0)

            return VAR_6;



        if (VAR_10 == VAR_19)

            break;

        dst  = VAR_1->data[VAR_3]  + 8*VAR_10*VAR_17;

        prev = (VAR_0->last->data[VAR_3] ? VAR_0->last->data[VAR_3]

                                         : VAR_1->data[VAR_3]) + 8*VAR_10*VAR_17;

        for (VAR_9 = 0; VAR_9 < VAR_18; VAR_9++, dst += 8, prev += 8) {

            VAR_5 = get_value(VAR_0, BINK_SRC_BLOCK_TYPES);

            

            if ((VAR_10 & 1) && VAR_5 == SCALED_BLOCK) {

                VAR_9++;

                dst  += 8;

                prev += 8;

                continue;

            }

            switch (VAR_5) {

            case SKIP_BLOCK:

                VAR_0->hdsp.put_pixels_tab[1][0](dst, prev, VAR_17, 8);

                break;

            case SCALED_BLOCK:

                VAR_5 = get_value(VAR_0, BINK_SRC_SUB_BLOCK_TYPES);

                switch (VAR_5) {

                case RUN_BLOCK:

                    VAR_13 = bink_patterns[get_bits(VAR_2, 4)];

                    VAR_7 = 0;

                    do {

                        int VAR_22 = get_value(VAR_0, BINK_SRC_RUN) + 1;



                        VAR_7 += VAR_22;

                        if (VAR_7 > 64) {

                            av_log(VAR_0->avctx, AV_LOG_ERROR, "Run went out of bounds\n");

                            return AVERROR_INVALIDDATA;

                        }

                        if (get_bits1(VAR_2)) {

                            VAR_11 = get_value(VAR_0, BINK_SRC_COLORS);

                            for (VAR_8 = 0; VAR_8 < VAR_22; VAR_8++)

                                ublock[*VAR_13++] = VAR_11;

                        } else {

                            for (VAR_8 = 0; VAR_8 < VAR_22; VAR_8++)

                                ublock[*VAR_13++] = get_value(VAR_0, BINK_SRC_COLORS);

                        }

                    } while (VAR_7 < 63);

                    if (VAR_7 == 63)

                        ublock[*VAR_13++] = get_value(VAR_0, BINK_SRC_COLORS);

                    break;

                case INTRA_BLOCK:

                    memset(dctblock, 0, sizeof(*dctblock) * 64);

                    dctblock[0] = get_value(VAR_0, BINK_SRC_INTRA_DC);

                    read_dct_coeffs(VAR_2, dctblock, bink_scan, bink_intra_quant, -1);

                    VAR_0->binkdsp.idct_put(ublock, 8, dctblock);

                    break;

                case FILL_BLOCK:

                    VAR_11 = get_value(VAR_0, BINK_SRC_COLORS);

                    VAR_0->bdsp.fill_block_tab[0](dst, VAR_11, VAR_17, 16);

                    break;

                case PATTERN_BLOCK:

                    for (VAR_7 = 0; VAR_7 < 2; VAR_7++)

                        VAR_12[VAR_7] = get_value(VAR_0, BINK_SRC_COLORS);

                    for (VAR_8 = 0; VAR_8 < 8; VAR_8++) {

                        VAR_11 = get_value(VAR_0, BINK_SRC_PATTERN);

                        for (VAR_7 = 0; VAR_7 < 8; VAR_7++, VAR_11 >>= 1)

                            ublock[VAR_7 + VAR_8*8] = VAR_12[VAR_11 & 1];

                    }

                    break;

                case RAW_BLOCK:

                    for (VAR_8 = 0; VAR_8 < 8; VAR_8++)

                        for (VAR_7 = 0; VAR_7 < 8; VAR_7++)

                            ublock[VAR_7 + VAR_8*8] = get_value(VAR_0, BINK_SRC_COLORS);

                    break;

                default:

                    av_log(VAR_0->avctx, AV_LOG_ERROR, "Incorrect 16x16 block type %d\n", VAR_5);

                    return AVERROR_INVALIDDATA;

                }

                if (VAR_5 != FILL_BLOCK)

                VAR_0->binkdsp.scale_block(ublock, dst, VAR_17);

                VAR_9++;

                dst  += 8;

                prev += 8;

                break;

            case MOTION_BLOCK:

                VAR_14 = get_value(VAR_0, BINK_SRC_X_OFF);

                VAR_15 = get_value(VAR_0, BINK_SRC_Y_OFF);

                ref = prev + VAR_14 + VAR_15 * VAR_17;

                if (ref < ref_start || ref > ref_end) {

                    av_log(VAR_0->avctx, AV_LOG_ERROR, "Copy out of bounds @%d, %d\n",

                           VAR_9*8 + VAR_14, VAR_10*8 + VAR_15);

                    return AVERROR_INVALIDDATA;

                }

                VAR_0->hdsp.put_pixels_tab[1][0](dst, ref, VAR_17, 8);

                break;

            case RUN_BLOCK:

                VAR_13 = bink_patterns[get_bits(VAR_2, 4)];

                VAR_7 = 0;

                do {

                    int VAR_22 = get_value(VAR_0, BINK_SRC_RUN) + 1;



                    VAR_7 += VAR_22;

                    if (VAR_7 > 64) {

                        av_log(VAR_0->avctx, AV_LOG_ERROR, "Run went out of bounds\n");

                        return AVERROR_INVALIDDATA;

                    }

                    if (get_bits1(VAR_2)) {

                        VAR_11 = get_value(VAR_0, BINK_SRC_COLORS);

                        for (VAR_8 = 0; VAR_8 < VAR_22; VAR_8++)

                            dst[VAR_16[*VAR_13++]] = VAR_11;

                    } else {

                        for (VAR_8 = 0; VAR_8 < VAR_22; VAR_8++)

                            dst[VAR_16[*VAR_13++]] = get_value(VAR_0, BINK_SRC_COLORS);

                    }

                } while (VAR_7 < 63);

                if (VAR_7 == 63)

                    dst[VAR_16[*VAR_13++]] = get_value(VAR_0, BINK_SRC_COLORS);

                break;

            case RESIDUE_BLOCK:

                VAR_14 = get_value(VAR_0, BINK_SRC_X_OFF);

                VAR_15 = get_value(VAR_0, BINK_SRC_Y_OFF);

                ref = prev + VAR_14 + VAR_15 * VAR_17;

                if (ref < ref_start || ref > ref_end) {

                    av_log(VAR_0->avctx, AV_LOG_ERROR, "Copy out of bounds @%d, %d\n",

                           VAR_9*8 + VAR_14, VAR_10*8 + VAR_15);

                    return AVERROR_INVALIDDATA;

                }

                VAR_0->hdsp.put_pixels_tab[1][0](dst, ref, VAR_17, 8);

                VAR_0->bdsp.clear_block(block);

                VAR_11 = get_bits(VAR_2, 7);

                read_residue(VAR_2, block, VAR_11);

                VAR_0->binkdsp.add_pixels8(dst, block, VAR_17);

                break;

            case INTRA_BLOCK:

                memset(dctblock, 0, sizeof(*dctblock) * 64);

                dctblock[0] = get_value(VAR_0, BINK_SRC_INTRA_DC);

                read_dct_coeffs(VAR_2, dctblock, bink_scan, bink_intra_quant, -1);

                VAR_0->binkdsp.idct_put(dst, VAR_17, dctblock);

                break;

            case FILL_BLOCK:

                VAR_11 = get_value(VAR_0, BINK_SRC_COLORS);

                VAR_0->bdsp.fill_block_tab[1](dst, VAR_11, VAR_17, 8);

                break;

            case INTER_BLOCK:

                VAR_14 = get_value(VAR_0, BINK_SRC_X_OFF);

                VAR_15 = get_value(VAR_0, BINK_SRC_Y_OFF);

                ref = prev + VAR_14 + VAR_15 * VAR_17;

                VAR_0->hdsp.put_pixels_tab[1][0](dst, ref, VAR_17, 8);

                memset(dctblock, 0, sizeof(*dctblock) * 64);

                dctblock[0] = get_value(VAR_0, BINK_SRC_INTER_DC);

                read_dct_coeffs(VAR_2, dctblock, bink_scan, bink_inter_quant, -1);

                VAR_0->binkdsp.idct_add(dst, VAR_17, dctblock);

                break;

            case PATTERN_BLOCK:

                for (VAR_7 = 0; VAR_7 < 2; VAR_7++)

                    VAR_12[VAR_7] = get_value(VAR_0, BINK_SRC_COLORS);

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

                    VAR_11 = get_value(VAR_0, BINK_SRC_PATTERN);

                    for (VAR_8 = 0; VAR_8 < 8; VAR_8++, VAR_11 >>= 1)

                        dst[VAR_7*VAR_17 + VAR_8] = VAR_12[VAR_11 & 1];

                }

                break;

            case RAW_BLOCK:

                for (VAR_7 = 0; VAR_7 < 8; VAR_7++)

                    memcpy(dst + VAR_7*VAR_17, VAR_0->bundle[BINK_SRC_COLORS].cur_ptr + VAR_7*8, 8);

                VAR_0->bundle[BINK_SRC_COLORS].cur_ptr += 64;

                break;

            default:

                av_log(VAR_0->avctx, AV_LOG_ERROR, "Unknown block type %d\n", VAR_5);

                return AVERROR_INVALIDDATA;

            }

        }

    }

    if (get_bits_count(VAR_2) & 0x1F) 

        skip_bits_long(VAR_2, 32 - (get_bits_count(VAR_2) & 0x1F));



    return 0;

}

static int FUNC_0(BinkContext *VAR_0, AVFrame *VAR_1, GetBitContext *VAR_2,
int VAR_3, int VAR_4)
{ int VAR_5, VAR_6; int VAR_7, VAR_8, VAR_9, VAR_10; uint8_t *dst, *prev, *ref, *ref_start, *ref_end; int VAR_11, VAR_12[2]; const uint8_t *VAR_13; int VAR_14, VAR_15; LOCAL_ALIGNED_16(int16_t, block, [64]); LOCAL_ALIGNED_16(uint8_t, ublock, [64]); LOCAL_ALIGNED_16(int32_t, dctblock, [64]); int VAR_16[64]; const int VAR_17 = VAR_1->linesize[VAR_3]; int VAR_18 = VAR_4 ? (VAR_0->avctx->VAR_20  + 15) >> 4 : (VAR_0->avctx->VAR_20  + 7) >> 3; int VAR_19 = VAR_4 ? (VAR_0->avctx->height + 15) >> 4 : (VAR_0->avctx->height + 7) >> 3; int VAR_20 = VAR_0->avctx->VAR_20 >> VAR_4; init_lengths(VAR_0, FFMAX(VAR_20, 8), VAR_18); for (VAR_7 = 0; VAR_7 < BINK_NB_SRC; VAR_7++) read_bundle(VAR_2, VAR_0, VAR_7); ref_start = VAR_0->last->data[VAR_3] ? VAR_0->last->data[VAR_3]
: VAR_1->data[VAR_3]; ref_end   = ref_start
+ (VAR_18 - 1 + VAR_0->last->linesize[VAR_3] * (VAR_19 - 1)) * 8; for (VAR_7 = 0; VAR_7 < 64; VAR_7++) VAR_16[VAR_7] = (VAR_7 & 7) + (VAR_7 >> 3) * VAR_17; for (VAR_10 = 0; VAR_10 < VAR_19; VAR_10++) { if ((VAR_6 = read_block_types(VAR_0->avctx, VAR_2, &VAR_0->bundle[BINK_SRC_BLOCK_TYPES])) < 0)
return VAR_6; if ((VAR_6 = read_block_types(VAR_0->avctx, VAR_2, &VAR_0->bundle[BINK_SRC_SUB_BLOCK_TYPES])) < 0)
return VAR_6; if ((VAR_6 = read_colors(VAR_2, &VAR_0->bundle[BINK_SRC_COLORS], VAR_0)) < 0)
return VAR_6; if ((VAR_6 = read_patterns(VAR_0->avctx, VAR_2, &VAR_0->bundle[BINK_SRC_PATTERN])) < 0)
return VAR_6; if ((VAR_6 = read_motion_values(VAR_0->avctx, VAR_2, &VAR_0->bundle[BINK_SRC_X_OFF])) < 0)
return VAR_6; if ((VAR_6 = read_motion_values(VAR_0->avctx, VAR_2, &VAR_0->bundle[BINK_SRC_Y_OFF])) < 0)
return VAR_6; if ((VAR_6 = read_dcs(VAR_0->avctx, VAR_2, &VAR_0->bundle[BINK_SRC_INTRA_DC], DC_START_BITS, 0)) < 0)
return VAR_6; if ((VAR_6 = read_dcs(VAR_0->avctx, VAR_2, &VAR_0->bundle[BINK_SRC_INTER_DC], DC_START_BITS, 1)) < 0)
return VAR_6; if ((VAR_6 = read_runs(VAR_0->avctx, VAR_2, &VAR_0->bundle[BINK_SRC_RUN])) < 0)
return VAR_6; if (VAR_10 == VAR_19)
break; dst  = VAR_1->data[VAR_3]  + 8*VAR_10*VAR_17; prev = (VAR_0->last->data[VAR_3] ? VAR_0->last->data[VAR_3]
: VAR_1->data[VAR_3]) + 8*VAR_10*VAR_17; for (VAR_9 = 0; VAR_9 < VAR_18; VAR_9++, dst += 8, prev += 8) { VAR_5 = get_value(VAR_0, BINK_SRC_BLOCK_TYPES); if ((VAR_10 & 1) && VAR_5 == SCALED_BLOCK) { VAR_9++; dst  += 8; prev += 8; continue; } switch (VAR_5) { case SKIP_BLOCK:
VAR_0->hdsp.put_pixels_tab[1][0](dst, prev, VAR_17, 8); break; case SCALED_BLOCK:
VAR_5 = get_value(VAR_0, BINK_SRC_SUB_BLOCK_TYPES); switch (VAR_5) { case RUN_BLOCK:
VAR_13 = bink_patterns[get_bits(VAR_2, 4)]; VAR_7 = 0; do { int VAR_22 = get_value(VAR_0, BINK_SRC_RUN) + 1; VAR_7 += VAR_22; if (VAR_7 > 64) { av_log(VAR_0->avctx, AV_LOG_ERROR, "Run went out of bounds\n"); return AVERROR_INVALIDDATA; } if (get_bits1(VAR_2)) { VAR_11 = get_value(VAR_0, BINK_SRC_COLORS); for (VAR_8 = 0; VAR_8 < VAR_22; VAR_8++) ublock[*VAR_13++] = VAR_11; } else { for (VAR_8 = 0; VAR_8 < VAR_22; VAR_8++) ublock[*VAR_13++] = get_value(VAR_0, BINK_SRC_COLORS); } } while (VAR_7 < 63); if (VAR_7 == 63)
ublock[*VAR_13++] = get_value(VAR_0, BINK_SRC_COLORS); break; case INTRA_BLOCK:
memset(dctblock, 0, sizeof(*dctblock) * 64); dctblock[0] = get_value(VAR_0, BINK_SRC_INTRA_DC); read_dct_coeffs(VAR_2, dctblock, bink_scan, bink_intra_quant, -1); VAR_0->binkdsp.idct_put(ublock, 8, dctblock); break; case FILL_BLOCK:
VAR_11 = get_value(VAR_0, BINK_SRC_COLORS); VAR_0->bdsp.fill_block_tab[0](dst, VAR_11, VAR_17, 16); break; case PATTERN_BLOCK:
for (VAR_7 = 0; VAR_7 < 2; VAR_7++) VAR_12[VAR_7] = get_value(VAR_0, BINK_SRC_COLORS); for (VAR_8 = 0; VAR_8 < 8; VAR_8++) { VAR_11 = get_value(VAR_0, BINK_SRC_PATTERN); for (VAR_7 = 0; VAR_7 < 8; VAR_7++, VAR_11 >>= 1) ublock[VAR_7 + VAR_8*8] = VAR_12[VAR_11 & 1]; } break; case RAW_BLOCK:
for (VAR_8 = 0; VAR_8 < 8; VAR_8++) for (VAR_7 = 0; VAR_7 < 8; VAR_7++) ublock[VAR_7 + VAR_8*8] = get_value(VAR_0, BINK_SRC_COLORS); break; default:
av_log(VAR_0->avctx, AV_LOG_ERROR, "Incorrect 16x16 block type %d\n", VAR_5); return AVERROR_INVALIDDATA; } if (VAR_5 != FILL_BLOCK)
VAR_0->binkdsp.scale_block(ublock, dst, VAR_17); VAR_9++; dst  += 8; prev += 8; break; case MOTION_BLOCK:
VAR_14 = get_value(VAR_0, BINK_SRC_X_OFF); VAR_15 = get_value(VAR_0, BINK_SRC_Y_OFF); ref = prev + VAR_14 + VAR_15 * VAR_17; if (ref < ref_start || ref > ref_end) { av_log(VAR_0->avctx, AV_LOG_ERROR, "Copy out of bounds @%d, %d\n",
VAR_9*8 + VAR_14, VAR_10*8 + VAR_15); return AVERROR_INVALIDDATA; } VAR_0->hdsp.put_pixels_tab[1][0](dst, ref, VAR_17, 8); break; case RUN_BLOCK:
VAR_13 = bink_patterns[get_bits(VAR_2, 4)]; VAR_7 = 0; do { int VAR_22 = get_value(VAR_0, BINK_SRC_RUN) + 1; VAR_7 += VAR_22; if (VAR_7 > 64) { av_log(VAR_0->avctx, AV_LOG_ERROR, "Run went out of bounds\n"); return AVERROR_INVALIDDATA; } if (get_bits1(VAR_2)) { VAR_11 = get_value(VAR_0, BINK_SRC_COLORS); for (VAR_8 = 0; VAR_8 < VAR_22; VAR_8++) dst[VAR_16[*VAR_13++]] = VAR_11; } else { for (VAR_8 = 0; VAR_8 < VAR_22; VAR_8++) dst[VAR_16[*VAR_13++]] = get_value(VAR_0, BINK_SRC_COLORS); } } while (VAR_7 < 63); if (VAR_7 == 63)
dst[VAR_16[*VAR_13++]] = get_value(VAR_0, BINK_SRC_COLORS); break; case RESIDUE_BLOCK:
VAR_14 = get_value(VAR_0, BINK_SRC_X_OFF); VAR_15 = get_value(VAR_0, BINK_SRC_Y_OFF); ref = prev + VAR_14 + VAR_15 * VAR_17; if (ref < ref_start || ref > ref_end) { av_log(VAR_0->avctx, AV_LOG_ERROR, "Copy out of bounds @%d, %d\n",
VAR_9*8 + VAR_14, VAR_10*8 + VAR_15); return AVERROR_INVALIDDATA; } VAR_0->hdsp.put_pixels_tab[1][0](dst, ref, VAR_17, 8); VAR_0->bdsp.clear_block(block); VAR_11 = get_bits(VAR_2, 7); read_residue(VAR_2, block, VAR_11); VAR_0->binkdsp.add_pixels8(dst, block, VAR_17); break; case INTRA_BLOCK:
memset(dctblock, 0, sizeof(*dctblock) * 64); dctblock[0] = get_value(VAR_0, BINK_SRC_INTRA_DC); read_dct_coeffs(VAR_2, dctblock, bink_scan, bink_intra_quant, -1); VAR_0->binkdsp.idct_put(dst, VAR_17, dctblock); break; case FILL_BLOCK:
VAR_11 = get_value(VAR_0, BINK_SRC_COLORS); VAR_0->bdsp.fill_block_tab[1](dst, VAR_11, VAR_17, 8); break; case INTER_BLOCK:
VAR_14 = get_value(VAR_0, BINK_SRC_X_OFF); VAR_15 = get_value(VAR_0, BINK_SRC_Y_OFF); ref = prev + VAR_14 + VAR_15 * VAR_17; VAR_0->hdsp.put_pixels_tab[1][0](dst, ref, VAR_17, 8); memset(dctblock, 0, sizeof(*dctblock) * 64); dctblock[0] = get_value(VAR_0, BINK_SRC_INTER_DC); read_dct_coeffs(VAR_2, dctblock, bink_scan, bink_inter_quant, -1); VAR_0->binkdsp.idct_add(dst, VAR_17, dctblock); break; case PATTERN_BLOCK:
for (VAR_7 = 0; VAR_7 < 2; VAR_7++) VAR_12[VAR_7] = get_value(VAR_0, BINK_SRC_COLORS); for (VAR_7 = 0; VAR_7 < 8; VAR_7++) { VAR_11 = get_value(VAR_0, BINK_SRC_PATTERN); for (VAR_8 = 0; VAR_8 < 8; VAR_8++, VAR_11 >>= 1) dst[VAR_7*VAR_17 + VAR_8] = VAR_12[VAR_11 & 1]; } break; case RAW_BLOCK:
for (VAR_7 = 0; VAR_7 < 8; VAR_7++) memcpy(dst + VAR_7*VAR_17, VAR_0->bundle[BINK_SRC_COLORS].cur_ptr + VAR_7*8, 8); VAR_0->bundle[BINK_SRC_COLORS].cur_ptr += 64; break; default:
av_log(VAR_0->avctx, AV_LOG_ERROR, "Unknown block type %d\n", VAR_5); return AVERROR_INVALIDDATA; } } } if (get_bits_count(VAR_2) & 0x1F)
skip_bits_long(VAR_2, 32 - (get_bits_count(VAR_2) & 0x1F)); return 0; }