static int read_dct_coeffs(GetBitContext *gb, int32_t block[64], const uint8_t *scan,

                           const int32_t quant_matrices[16][64], int q)

{

    int coef_list[128];

    int mode_list[128];

    int i, t, mask, bits, ccoef, mode, sign;

    int list_start = 64, list_end = 64, list_pos;

    int coef_count = 0;

    int coef_idx[64];

    int quant_idx;

    const int32_t *quant;



    coef_list[list_end] = 4;  mode_list[list_end++] = 0;

    coef_list[list_end] = 24; mode_list[list_end++] = 0;

    coef_list[list_end] = 44; mode_list[list_end++] = 0;

    coef_list[list_end] = 1;  mode_list[list_end++] = 3;

    coef_list[list_end] = 2;  mode_list[list_end++] = 3;

    coef_list[list_end] = 3;  mode_list[list_end++] = 3;



    bits = get_bits(gb, 4) - 1;

    for (mask = 1 << bits; bits >= 0; mask >>= 1, bits--) {

        list_pos = list_start;

        while (list_pos < list_end) {

            if (!(mode_list[list_pos] | coef_list[list_pos]) || !get_bits1(gb)) {

                list_pos++;

                continue;

            }

            ccoef = coef_list[list_pos];

            mode  = mode_list[list_pos];

            switch (mode) {

            case 0:

                coef_list[list_pos] = ccoef + 4;

                mode_list[list_pos] = 1;

            case 2:

                if (mode == 2) {

                    coef_list[list_pos]   = 0;

                    mode_list[list_pos++] = 0;

                }

                for (i = 0; i < 4; i++, ccoef++) {

                    if (get_bits1(gb)) {

                        coef_list[--list_start] = ccoef;

                        mode_list[  list_start] = 3;

                    } else {

                        if (!bits) {

                            t = 1 - (get_bits1(gb) << 1);

                        } else {

                            t = get_bits(gb, bits) | mask;

                            sign = -get_bits1(gb);

                            t = (t ^ sign) - sign;

                        }

                        block[scan[ccoef]] = t;

                        coef_idx[coef_count++] = ccoef;

                    }

                }

                break;

            case 1:

                mode_list[list_pos] = 2;

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

                    ccoef += 4;

                    coef_list[list_end]   = ccoef;

                    mode_list[list_end++] = 2;

                }

                break;

            case 3:

                if (!bits) {

                    t = 1 - (get_bits1(gb) << 1);

                } else {

                    t = get_bits(gb, bits) | mask;

                    sign = -get_bits1(gb);

                    t = (t ^ sign) - sign;

                }

                block[scan[ccoef]] = t;

                coef_idx[coef_count++] = ccoef;

                coef_list[list_pos]   = 0;

                mode_list[list_pos++] = 0;

                break;

            }

        }

    }



    if (q == -1) {

        quant_idx = get_bits(gb, 4);

    } else {

        quant_idx = q;

    }



    quant = quant_matrices[quant_idx];



    block[0] = (block[0] * quant[0]) >> 11;

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

        int idx = coef_idx[i];

        block[scan[idx]] = (block[scan[idx]] * quant[idx]) >> 11;

    }



    return 0;

}
