static int vorbis_parse_setup_hdr_residues(vorbis_context *vc)

{

    GetBitContext *gb = &vc->gb;

    uint_fast8_t i, j, k;



    vc->residue_count = get_bits(gb, 6)+1;

    vc->residues      = av_mallocz(vc->residue_count * sizeof(vorbis_residue));



    AV_DEBUG(" There are %d residues. \n", vc->residue_count);



    for (i = 0; i < vc->residue_count; ++i) {

        vorbis_residue *res_setup = &vc->residues[i];

        uint_fast8_t cascade[64];

        uint_fast8_t high_bits;

        uint_fast8_t low_bits;



        res_setup->type = get_bits(gb, 16);



        AV_DEBUG(" %d. residue type %d \n", i, res_setup->type);



        res_setup->begin          = get_bits(gb, 24);

        res_setup->end            = get_bits(gb, 24);

        res_setup->partition_size = get_bits(gb, 24) + 1;

        /* Validations to prevent a buffer overflow later. */

        if (res_setup->begin>res_setup->end ||

            res_setup->end > vc->avccontext->channels * vc->blocksize[1] / (res_setup->type == 2 ? 1 : 2) ||

            (res_setup->end-res_setup->begin) / res_setup->partition_size > V_MAX_PARTITIONS) {

            av_log(vc->avccontext, AV_LOG_ERROR, "partition out of bounds: type, begin, end, size, blocksize: %"PRIdFAST16", %"PRIdFAST32", %"PRIdFAST32", %u, %"PRIdFAST32"\n", res_setup->type, res_setup->begin, res_setup->end, res_setup->partition_size, vc->blocksize[1] / 2);

            return -1;

        }



        res_setup->classifications = get_bits(gb, 6) + 1;

        GET_VALIDATED_INDEX(res_setup->classbook, 8, vc->codebook_count)



        res_setup->ptns_to_read =

            (res_setup->end - res_setup->begin) / res_setup->partition_size;

        res_setup->classifs = av_malloc(res_setup->ptns_to_read *

                                        vc->audio_channels *

                                        sizeof(*res_setup->classifs));

        if (!res_setup->classifs)

            return AVERROR(ENOMEM);



        AV_DEBUG("    begin %d end %d part.size %d classif.s %d classbook %d \n", res_setup->begin, res_setup->end, res_setup->partition_size,

          res_setup->classifications, res_setup->classbook);



        for (j = 0; j < res_setup->classifications; ++j) {

            high_bits = 0;

            low_bits  = get_bits(gb, 3);

            if (get_bits1(gb))

                high_bits = get_bits(gb, 5);

            cascade[j] = (high_bits << 3) + low_bits;



            AV_DEBUG("     %d class casscade depth: %d \n", j, ilog(cascade[j]));

        }



        res_setup->maxpass = 0;

        for (j = 0; j < res_setup->classifications; ++j) {

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

                if (cascade[j]&(1 << k)) {

                    GET_VALIDATED_INDEX(res_setup->books[j][k], 8, vc->codebook_count)



                    AV_DEBUG("     %d class casscade depth %d book: %d \n", j, k, res_setup->books[j][k]);



                    if (k>res_setup->maxpass)

                        res_setup->maxpass = k;

                } else {

                    res_setup->books[j][k] = -1;

                }

            }

        }

    }

    return 0;

}
