static int x8_decode_intra_mb(IntraX8Context *const w, const int chroma)

{

    MpegEncContext *const s = w->s;



    uint8_t *scantable;

    int final, run, level;

    int ac_mode, dc_mode, est_run, dc_level;

    int pos, n;

    int zeros_only;

    int use_quant_matrix;

    int sign;



    assert(w->orient < 12);

    s->bdsp.clear_block(s->block[0]);



    if (chroma)

        dc_mode = 2;

    else

        dc_mode = !!w->est_run; // 0, 1



    if (x8_get_dc_rlf(w, dc_mode, &dc_level, &final))

        return -1;

    n          = 0;

    zeros_only = 0;

    if (!final) { // decode ac

        use_quant_matrix = w->use_quant_matrix;

        if (chroma) {

            ac_mode = 1;

            est_run = 64; // not used

        } else {

            if (w->raw_orient < 3)

                use_quant_matrix = 0;



            if (w->raw_orient > 4) {

                ac_mode = 0;

                est_run = 64;

            } else {

                if (w->est_run > 1) {

                    ac_mode = 2;

                    est_run = w->est_run;

                } else {

                    ac_mode = 3;

                    est_run = 64;

                }

            }

        }

        x8_select_ac_table(w, ac_mode);

        /* scantable_selector[12] = { 0, 2, 0, 1, 1, 1, 0, 2, 2, 0, 1, 2 }; <-

         * -> 10'01' 00'10' 10'00' 01'01' 01'00' 10'00 => 0x928548 */

        scantable = w->scantable[(0x928548 >> (2 * w->orient)) & 3].permutated;

        pos       = 0;

        do {

            n++;

            if (n >= est_run) {

                ac_mode = 3;

                x8_select_ac_table(w, 3);

            }



            x8_get_ac_rlf(w, ac_mode, &run, &level, &final);



            pos += run + 1;

            if (pos > 63) {

                // this also handles vlc error in x8_get_ac_rlf

                return -1;

            }

            level  = (level + 1) * w->dquant;

            level += w->qsum;



            sign  = -get_bits1(&s->gb);

            level = (level ^ sign) - sign;



            if (use_quant_matrix)

                level = (level * quant_table[pos]) >> 8;



            s->block[0][scantable[pos]] = level;

        } while (!final);



        s->block_last_index[0] = pos;

    } else { // DC only

        s->block_last_index[0] = 0;

        if (w->flat_dc && ((unsigned) (dc_level + 1)) < 3) { // [-1; 1]

            int32_t divide_quant = !chroma ? w->divide_quant_dc_luma

                                           : w->divide_quant_dc_chroma;

            int32_t dc_quant     = !chroma ? w->quant

                                           : w->quant_dc_chroma;



            // original intent dc_level += predicted_dc/quant;

            // but it got lost somewhere in the rounding

            dc_level += (w->predicted_dc * divide_quant + (1 << 12)) >> 13;



            dsp_x8_put_solidcolor(av_clip_uint8((dc_level * dc_quant + 4) >> 3),

                                  w->dest[chroma],

                                  s->current_picture.f->linesize[!!chroma]);



            goto block_placed;

        }

        zeros_only = (dc_level == 0);

    }

    if (!chroma)

        s->block[0][0] = dc_level * w->quant;

    else

        s->block[0][0] = dc_level * w->quant_dc_chroma;



    // there is !zero_only check in the original, but dc_level check is enough

    if ((unsigned int) (dc_level + 1) >= 3 && (w->edges & 3) != 3) {

        int direction;

        /* ac_comp_direction[orient] = { 0, 3, 3, 1, 1, 0, 0, 0, 2, 2, 2, 1 }; <-

         * -> 01'10' 10'10' 00'00' 00'01' 01'11' 11'00 => 0x6A017C */

        direction = (0x6A017C >> (w->orient * 2)) & 3;

        if (direction != 3) {

            // modify block_last[]

            x8_ac_compensation(w, direction, s->block[0][0]);

        }

    }



    if (w->flat_dc) {

        dsp_x8_put_solidcolor(w->predicted_dc, w->dest[chroma],

                              s->current_picture.f->linesize[!!chroma]);

    } else {

        w->dsp.spatial_compensation[w->orient](s->sc.edge_emu_buffer,

                                               w->dest[chroma],

                                               s->current_picture.f->linesize[!!chroma]);

    }

    if (!zeros_only)

        w->idsp.idct_add(w->dest[chroma],

                         s->current_picture.f->linesize[!!chroma],

                         s->block[0]);



block_placed:

    if (!chroma)

        x8_update_predictions(w, w->orient, n);



    if (s->loop_filter) {

        uint8_t *ptr = w->dest[chroma];

        int linesize = s->current_picture.f->linesize[!!chroma];



        if (!((w->edges & 2) || (zeros_only && (w->orient | 4) == 4)))

            w->dsp.h_loop_filter(ptr, linesize, w->quant);



        if (!((w->edges & 1) || (zeros_only && (w->orient | 8) == 8)))

            w->dsp.v_loop_filter(ptr, linesize, w->quant);

    }

    return 0;

}

static int x8_decode_intra_mb(IntraX8Context *const w, const int chroma)

{

    MpegEncContext *const s = w->s;



    uint8_t *scantable;

    int final, run, level;

    int ac_mode, dc_mode, est_run, dc_level;

    int pos, n;

    int zeros_only;

    int use_quant_matrix;

    int sign;



    assert(w->orient < 12);

    s->bdsp.clear_block(s->block[0]);



    if (chroma)

        dc_mode = 2;

    else

        dc_mode = !!w->est_run; 



    if (x8_get_dc_rlf(w, dc_mode, &dc_level, &final))

        return -1;

    n          = 0;

    zeros_only = 0;

    if (!final) { 

        use_quant_matrix = w->use_quant_matrix;

        if (chroma) {

            ac_mode = 1;

            est_run = 64; 

        } else {

            if (w->raw_orient < 3)

                use_quant_matrix = 0;



            if (w->raw_orient > 4) {

                ac_mode = 0;

                est_run = 64;

            } else {

                if (w->est_run > 1) {

                    ac_mode = 2;

                    est_run = w->est_run;

                } else {

                    ac_mode = 3;

                    est_run = 64;

                }

            }

        }

        x8_select_ac_table(w, ac_mode);

        



        scantable = w->scantable[(0x928548 >> (2 * w->orient)) & 3].permutated;

        pos       = 0;

        do {

            n++;

            if (n >= est_run) {

                ac_mode = 3;

                x8_select_ac_table(w, 3);

            }



            x8_get_ac_rlf(w, ac_mode, &run, &level, &final);



            pos += run + 1;

            if (pos > 63) {

                

                return -1;

            }

            level  = (level + 1) * w->dquant;

            level += w->qsum;



            sign  = -get_bits1(&s->gb);

            level = (level ^ sign) - sign;



            if (use_quant_matrix)

                level = (level * quant_table[pos]) >> 8;



            s->block[0][scantable[pos]] = level;

        } while (!final);



        s->block_last_index[0] = pos;

    } else { 

        s->block_last_index[0] = 0;

        if (w->flat_dc && ((unsigned) (dc_level + 1)) < 3) { 

            int32_t divide_quant = !chroma ? w->divide_quant_dc_luma

                                           : w->divide_quant_dc_chroma;

            int32_t dc_quant     = !chroma ? w->quant

                                           : w->quant_dc_chroma;



            

            

            dc_level += (w->predicted_dc * divide_quant + (1 << 12)) >> 13;



            dsp_x8_put_solidcolor(av_clip_uint8((dc_level * dc_quant + 4) >> 3),

                                  w->dest[chroma],

                                  s->current_picture.f->linesize[!!chroma]);



            goto block_placed;

        }

        zeros_only = (dc_level == 0);

    }

    if (!chroma)

        s->block[0][0] = dc_level * w->quant;

    else

        s->block[0][0] = dc_level * w->quant_dc_chroma;



    

    if ((unsigned int) (dc_level + 1) >= 3 && (w->edges & 3) != 3) {

        int direction;

        



        direction = (0x6A017C >> (w->orient * 2)) & 3;

        if (direction != 3) {

            

            x8_ac_compensation(w, direction, s->block[0][0]);

        }

    }



    if (w->flat_dc) {

        dsp_x8_put_solidcolor(w->predicted_dc, w->dest[chroma],

                              s->current_picture.f->linesize[!!chroma]);

    } else {

        w->dsp.spatial_compensation[w->orient](s->sc.edge_emu_buffer,

                                               w->dest[chroma],

                                               s->current_picture.f->linesize[!!chroma]);

    }

    if (!zeros_only)

        w->idsp.idct_add(w->dest[chroma],

                         s->current_picture.f->linesize[!!chroma],

                         s->block[0]);



block_placed:

    if (!chroma)

        x8_update_predictions(w, w->orient, n);



    if (s->loop_filter) {

        uint8_t *ptr = w->dest[chroma];

        int linesize = s->current_picture.f->linesize[!!chroma];



        if (!((w->edges & 2) || (zeros_only && (w->orient | 4) == 4)))

            w->dsp.h_loop_filter(ptr, linesize, w->quant);



        if (!((w->edges & 1) || (zeros_only && (w->orient | 8) == 8)))

            w->dsp.v_loop_filter(ptr, linesize, w->quant);

    }

    return 0;

}

static int FUNC_0(IntraX8Context *const VAR_0, const int VAR_1)

{

    MpegEncContext *const s = VAR_0->s;



    uint8_t *scantable;

    int VAR_2, VAR_3, VAR_4;

    int VAR_5, VAR_6, VAR_7, VAR_8;

    int VAR_9, VAR_10;

    int VAR_11;

    int VAR_12;

    int VAR_13;



    assert(VAR_0->orient < 12);

    s->bdsp.clear_block(s->block[0]);



    if (VAR_1)

        VAR_6 = 2;

    else

        VAR_6 = !!VAR_0->VAR_7; 



    if (x8_get_dc_rlf(VAR_0, VAR_6, &VAR_8, &VAR_2))

        return -1;

    VAR_10          = 0;

    VAR_11 = 0;

    if (!VAR_2) { 

        VAR_12 = VAR_0->VAR_12;

        if (VAR_1) {

            VAR_5 = 1;

            VAR_7 = 64; 

        } else {

            if (VAR_0->raw_orient < 3)

                VAR_12 = 0;



            if (VAR_0->raw_orient > 4) {

                VAR_5 = 0;

                VAR_7 = 64;

            } else {

                if (VAR_0->VAR_7 > 1) {

                    VAR_5 = 2;

                    VAR_7 = VAR_0->VAR_7;

                } else {

                    VAR_5 = 3;

                    VAR_7 = 64;

                }

            }

        }

        x8_select_ac_table(VAR_0, VAR_5);

        



        scantable = VAR_0->scantable[(0x928548 >> (2 * VAR_0->orient)) & 3].permutated;

        VAR_9       = 0;

        do {

            VAR_10++;

            if (VAR_10 >= VAR_7) {

                VAR_5 = 3;

                x8_select_ac_table(VAR_0, 3);

            }



            x8_get_ac_rlf(VAR_0, VAR_5, &VAR_3, &VAR_4, &VAR_2);



            VAR_9 += VAR_3 + 1;

            if (VAR_9 > 63) {

                

                return -1;

            }

            VAR_4  = (VAR_4 + 1) * VAR_0->dquant;

            VAR_4 += VAR_0->qsum;



            VAR_13  = -get_bits1(&s->gb);

            VAR_4 = (VAR_4 ^ VAR_13) - VAR_13;



            if (VAR_12)

                VAR_4 = (VAR_4 * quant_table[VAR_9]) >> 8;



            s->block[0][scantable[VAR_9]] = VAR_4;

        } while (!VAR_2);



        s->block_last_index[0] = VAR_9;

    } else { 

        s->block_last_index[0] = 0;

        if (VAR_0->flat_dc && ((unsigned) (VAR_8 + 1)) < 3) { 

            int32_t divide_quant = !VAR_1 ? VAR_0->divide_quant_dc_luma

                                           : VAR_0->divide_quant_dc_chroma;

            int32_t dc_quant     = !VAR_1 ? VAR_0->quant

                                           : VAR_0->quant_dc_chroma;



            

            

            VAR_8 += (VAR_0->predicted_dc * divide_quant + (1 << 12)) >> 13;



            dsp_x8_put_solidcolor(av_clip_uint8((VAR_8 * dc_quant + 4) >> 3),

                                  VAR_0->dest[VAR_1],

                                  s->current_picture.f->VAR_15[!!VAR_1]);



            goto block_placed;

        }

        VAR_11 = (VAR_8 == 0);

    }

    if (!VAR_1)

        s->block[0][0] = VAR_8 * VAR_0->quant;

    else

        s->block[0][0] = VAR_8 * VAR_0->quant_dc_chroma;



    

    if ((unsigned int) (VAR_8 + 1) >= 3 && (VAR_0->edges & 3) != 3) {

        int VAR_14;

        



        VAR_14 = (0x6A017C >> (VAR_0->orient * 2)) & 3;

        if (VAR_14 != 3) {

            

            x8_ac_compensation(VAR_0, VAR_14, s->block[0][0]);

        }

    }



    if (VAR_0->flat_dc) {

        dsp_x8_put_solidcolor(VAR_0->predicted_dc, VAR_0->dest[VAR_1],

                              s->current_picture.f->VAR_15[!!VAR_1]);

    } else {

        VAR_0->dsp.spatial_compensation[VAR_0->orient](s->sc.edge_emu_buffer,

                                               VAR_0->dest[VAR_1],

                                               s->current_picture.f->VAR_15[!!VAR_1]);

    }

    if (!VAR_11)

        VAR_0->idsp.idct_add(VAR_0->dest[VAR_1],

                         s->current_picture.f->VAR_15[!!VAR_1],

                         s->block[0]);



block_placed:

    if (!VAR_1)

        x8_update_predictions(VAR_0, VAR_0->orient, VAR_10);



    if (s->loop_filter) {

        uint8_t *ptr = VAR_0->dest[VAR_1];

        int VAR_15 = s->current_picture.f->VAR_15[!!VAR_1];



        if (!((VAR_0->edges & 2) || (VAR_11 && (VAR_0->orient | 4) == 4)))

            VAR_0->dsp.h_loop_filter(ptr, VAR_15, VAR_0->quant);



        if (!((VAR_0->edges & 1) || (VAR_11 && (VAR_0->orient | 8) == 8)))

            VAR_0->dsp.v_loop_filter(ptr, VAR_15, VAR_0->quant);

    }

    return 0;

}

static int FUNC_0(IntraX8Context *const VAR_0, const int VAR_1)
{ MpegEncContext *const s = VAR_0->s; uint8_t *scantable; int VAR_2, VAR_3, VAR_4; int VAR_5, VAR_6, VAR_7, VAR_8; int VAR_9, VAR_10; int VAR_11; int VAR_12; int VAR_13; assert(VAR_0->orient < 12); s->bdsp.clear_block(s->block[0]); if (VAR_1)
VAR_6 = 2; else
VAR_6 = !!VAR_0->VAR_7; if (x8_get_dc_rlf(VAR_0, VAR_6, &VAR_8, &VAR_2))
return -1; VAR_10          = 0; VAR_11 = 0; if (!VAR_2) { VAR_12 = VAR_0->VAR_12; if (VAR_1) { VAR_5 = 1; VAR_7 = 64; } else { if (VAR_0->raw_orient < 3)
VAR_12 = 0; if (VAR_0->raw_orient > 4) { VAR_5 = 0; VAR_7 = 64; } else { if (VAR_0->VAR_7 > 1) { VAR_5 = 2; VAR_7 = VAR_0->VAR_7; } else { VAR_5 = 3; VAR_7 = 64; } } } x8_select_ac_table(VAR_0, VAR_5); scantable = VAR_0->scantable[(0x928548 >> (2 * VAR_0->orient)) & 3].permutated; VAR_9       = 0; do { VAR_10++; if (VAR_10 >= VAR_7) { VAR_5 = 3; x8_select_ac_table(VAR_0, 3); } x8_get_ac_rlf(VAR_0, VAR_5, &VAR_3, &VAR_4, &VAR_2); VAR_9 += VAR_3 + 1; if (VAR_9 > 63) { return -1; } VAR_4  = (VAR_4 + 1) * VAR_0->dquant; VAR_4 += VAR_0->qsum; VAR_13  = -get_bits1(&s->gb); VAR_4 = (VAR_4 ^ VAR_13) - VAR_13; if (VAR_12)
VAR_4 = (VAR_4 * quant_table[VAR_9]) >> 8; s->block[0][scantable[VAR_9]] = VAR_4; } while (!VAR_2); s->block_last_index[0] = VAR_9; } else { s->block_last_index[0] = 0; if (VAR_0->flat_dc && ((unsigned) (VAR_8 + 1)) < 3) { int32_t divide_quant = !VAR_1 ? VAR_0->divide_quant_dc_luma
: VAR_0->divide_quant_dc_chroma; int32_t dc_quant     = !VAR_1 ? VAR_0->quant
: VAR_0->quant_dc_chroma; VAR_8 += (VAR_0->predicted_dc * divide_quant + (1 << 12)) >> 13; dsp_x8_put_solidcolor(av_clip_uint8((VAR_8 * dc_quant + 4) >> 3),
VAR_0->dest[VAR_1],
s->current_picture.f->VAR_15[!!VAR_1]); goto block_placed; } VAR_11 = (VAR_8 == 0); } if (!VAR_1)
s->block[0][0] = VAR_8 * VAR_0->quant; else
s->block[0][0] = VAR_8 * VAR_0->quant_dc_chroma; if ((unsigned int) (VAR_8 + 1) >= 3 && (VAR_0->edges & 3) != 3) { int VAR_14; VAR_14 = (0x6A017C >> (VAR_0->orient * 2)) & 3; if (VAR_14 != 3) { x8_ac_compensation(VAR_0, VAR_14, s->block[0][0]); } } if (VAR_0->flat_dc) { dsp_x8_put_solidcolor(VAR_0->predicted_dc, VAR_0->dest[VAR_1],
s->current_picture.f->VAR_15[!!VAR_1]); } else { VAR_0->dsp.spatial_compensation[VAR_0->orient](s->sc.edge_emu_buffer,
VAR_0->dest[VAR_1],
s->current_picture.f->VAR_15[!!VAR_1]); } if (!VAR_11)
VAR_0->idsp.idct_add(VAR_0->dest[VAR_1],
s->current_picture.f->VAR_15[!!VAR_1],
s->block[0]); block_placed:
if (!VAR_1)
x8_update_predictions(VAR_0, VAR_0->orient, VAR_10); if (s->loop_filter) { uint8_t *ptr = VAR_0->dest[VAR_1]; int VAR_15 = s->current_picture.f->VAR_15[!!VAR_1]; if (!((VAR_0->edges & 2) || (VAR_11 && (VAR_0->orient | 4) == 4)))
VAR_0->dsp.h_loop_filter(ptr, VAR_15, VAR_0->quant); if (!((VAR_0->edges & 1) || (VAR_11 && (VAR_0->orient | 8) == 8)))
VAR_0->dsp.v_loop_filter(ptr, VAR_15, VAR_0->quant); } return 0; }