int ff_init_vlc_sparse(VLC *vlc, int nb_bits, int nb_codes,

                       const void *bits, int bits_wrap, int bits_size,

                       const void *codes, int codes_wrap, int codes_size,

                       const void *symbols, int symbols_wrap, int symbols_size,

                       int flags)

{

    VLCcode *buf;

    int i, j, ret;



    vlc->bits = nb_bits;

    if (flags & INIT_VLC_USE_NEW_STATIC) {

        VLC dyn_vlc = *vlc;



        if (vlc->table_size)

            return 0;



        ret = ff_init_vlc_sparse(&dyn_vlc, nb_bits, nb_codes,

                                 bits, bits_wrap, bits_size,

                                 codes, codes_wrap, codes_size,

                                 symbols, symbols_wrap, symbols_size,

                                 flags & ~INIT_VLC_USE_NEW_STATIC);

        av_assert0(ret >= 0);

        av_assert0(dyn_vlc.table_size <= vlc->table_allocated);

        if (dyn_vlc.table_size < vlc->table_allocated)

            av_log(NULL, AV_LOG_ERROR, "needed %d had %d\n", dyn_vlc.table_size, vlc->table_allocated);

        memcpy(vlc->table, dyn_vlc.table, dyn_vlc.table_size * sizeof(*vlc->table));

        vlc->table_size = dyn_vlc.table_size;

        ff_free_vlc(&dyn_vlc);

        return 0;

    } else {

        vlc->table           = NULL;

        vlc->table_allocated = 0;

        vlc->table_size      = 0;

    }



    av_dlog(NULL, "build table nb_codes=%d\n", nb_codes);



    buf = av_malloc((nb_codes + 1) * sizeof(VLCcode));





    av_assert0(symbols_size <= 2 || !symbols);

    j = 0;

#define COPY(condition)\

    for (i = 0; i < nb_codes; i++) {                                        \

        GET_DATA(buf[j].bits, bits, i, bits_wrap, bits_size);               \

        if (!(condition))                                                   \

            continue;                                                       \

        if (buf[j].bits > 3*nb_bits || buf[j].bits>32) {                    \

            av_log(NULL, AV_LOG_ERROR, "Too long VLC (%d) in init_vlc\n", buf[j].bits);\

            av_free(buf);                                                   \

            return -1;                                                      \

        }                                                                   \

        GET_DATA(buf[j].code, codes, i, codes_wrap, codes_size);            \

        if (buf[j].code >= (1LL<<buf[j].bits)) {                            \

            av_log(NULL, AV_LOG_ERROR, "Invalid code in init_vlc\n");       \

            av_free(buf);                                                   \

            return -1;                                                      \

        }                                                                   \

        if (flags & INIT_VLC_LE)                                            \

            buf[j].code = bitswap_32(buf[j].code);                          \

        else                                                                \

            buf[j].code <<= 32 - buf[j].bits;                               \

        if (symbols)                                                        \

            GET_DATA(buf[j].symbol, symbols, i, symbols_wrap, symbols_size) \

        else                                                                \

            buf[j].symbol = i;                                              \

        j++;                                                                \

    }

    COPY(buf[j].bits > nb_bits);

    // qsort is the slowest part of init_vlc, and could probably be improved or avoided

    qsort(buf, j, sizeof(VLCcode), compare_vlcspec);

    COPY(buf[j].bits && buf[j].bits <= nb_bits);

    nb_codes = j;



    ret = build_table(vlc, nb_bits, nb_codes, buf, flags);



    av_free(buf);

    if (ret < 0) {

        av_freep(&vlc->table);

        return ret;

    }

    return 0;

}
int ff_init_vlc_sparse(VLC *vlc, int nb_bits, int nb_codes,

                       const void *bits, int bits_wrap, int bits_size,

                       const void *codes, int codes_wrap, int codes_size,

                       const void *symbols, int symbols_wrap, int symbols_size,

                       int flags)

{

    VLCcode *buf;

    int i, j, ret;



    vlc->bits = nb_bits;

    if (flags & INIT_VLC_USE_NEW_STATIC) {

        VLC dyn_vlc = *vlc;



        if (vlc->table_size)

            return 0;



        ret = ff_init_vlc_sparse(&dyn_vlc, nb_bits, nb_codes,

                                 bits, bits_wrap, bits_size,

                                 codes, codes_wrap, codes_size,

                                 symbols, symbols_wrap, symbols_size,

                                 flags & ~INIT_VLC_USE_NEW_STATIC);

        av_assert0(ret >= 0);

        av_assert0(dyn_vlc.table_size <= vlc->table_allocated);

        if (dyn_vlc.table_size < vlc->table_allocated)

            av_log(NULL, AV_LOG_ERROR, "needed %d had %d\n", dyn_vlc.table_size, vlc->table_allocated);

        memcpy(vlc->table, dyn_vlc.table, dyn_vlc.table_size * sizeof(*vlc->table));

        vlc->table_size = dyn_vlc.table_size;

        ff_free_vlc(&dyn_vlc);

        return 0;

    } else {

        vlc->table           = NULL;

        vlc->table_allocated = 0;

        vlc->table_size      = 0;

    }



    av_dlog(NULL, "build table nb_codes=%d\n", nb_codes);



    buf = av_malloc((nb_codes + 1) * sizeof(VLCcode));





    av_assert0(symbols_size <= 2 || !symbols);

    j = 0;

#define COPY(condition)\

    for (i = 0; i < nb_codes; i++) {                                        \

        GET_DATA(buf[j].bits, bits, i, bits_wrap, bits_size);               \

        if (!(condition))                                                   \

            continue;                                                       \

        if (buf[j].bits > 3*nb_bits || buf[j].bits>32) {                    \

            av_log(NULL, AV_LOG_ERROR, "Too long VLC (%d) in init_vlc\n", buf[j].bits);\

            av_free(buf);                                                   \

            return -1;                                                      \

        }                                                                   \

        GET_DATA(buf[j].code, codes, i, codes_wrap, codes_size);            \

        if (buf[j].code >= (1LL<<buf[j].bits)) {                            \

            av_log(NULL, AV_LOG_ERROR, "Invalid code in init_vlc\n");       \

            av_free(buf);                                                   \

            return -1;                                                      \

        }                                                                   \

        if (flags & INIT_VLC_LE)                                            \

            buf[j].code = bitswap_32(buf[j].code);                          \

        else                                                                \

            buf[j].code <<= 32 - buf[j].bits;                               \

        if (symbols)                                                        \

            GET_DATA(buf[j].symbol, symbols, i, symbols_wrap, symbols_size) \

        else                                                                \

            buf[j].symbol = i;                                              \

        j++;                                                                \

    }

    COPY(buf[j].bits > nb_bits);

    

    qsort(buf, j, sizeof(VLCcode), compare_vlcspec);

    COPY(buf[j].bits && buf[j].bits <= nb_bits);

    nb_codes = j;



    ret = build_table(vlc, nb_bits, nb_codes, buf, flags);



    av_free(buf);

    if (ret < 0) {

        av_freep(&vlc->table);

        return ret;

    }

    return 0;

}
int FUNC_0(VLC *VAR_0, int VAR_1, int VAR_2,

                       const void *VAR_3, int VAR_4, int VAR_5,

                       const void *VAR_6, int VAR_7, int VAR_8,

                       const void *VAR_9, int VAR_10, int VAR_11,

                       int VAR_12)

{

    VLCcode *buf;

    int VAR_13, VAR_14, VAR_15;



    VAR_0->VAR_3 = VAR_1;

    if (VAR_12 & INIT_VLC_USE_NEW_STATIC) {

        VLC dyn_vlc = *VAR_0;



        if (VAR_0->table_size)

            return 0;



        VAR_15 = FUNC_0(&dyn_vlc, VAR_1, VAR_2,

                                 VAR_3, VAR_4, VAR_5,

                                 VAR_6, VAR_7, VAR_8,

                                 VAR_9, VAR_10, VAR_11,

                                 VAR_12 & ~INIT_VLC_USE_NEW_STATIC);

        av_assert0(VAR_15 >= 0);

        av_assert0(dyn_vlc.table_size <= VAR_0->table_allocated);

        if (dyn_vlc.table_size < VAR_0->table_allocated)

            av_log(NULL, AV_LOG_ERROR, "needed %d had %d\n", dyn_vlc.table_size, VAR_0->table_allocated);

        memcpy(VAR_0->table, dyn_vlc.table, dyn_vlc.table_size * sizeof(*VAR_0->table));

        VAR_0->table_size = dyn_vlc.table_size;

        ff_free_vlc(&dyn_vlc);

        return 0;

    } else {

        VAR_0->table           = NULL;

        VAR_0->table_allocated = 0;

        VAR_0->table_size      = 0;

    }



    av_dlog(NULL, "build table VAR_2=%d\n", VAR_2);



    buf = av_malloc((VAR_2 + 1) * sizeof(VLCcode));





    av_assert0(VAR_11 <= 2 || !VAR_9);

    VAR_14 = 0;

#define COPY(condition)\

    for (VAR_13 = 0; VAR_13 < VAR_2; VAR_13++) {                                        \

        GET_DATA(buf[VAR_14].VAR_3, VAR_3, VAR_13, VAR_4, VAR_5);               \

        if (!(condition))                                                   \

            continue;                                                       \

        if (buf[VAR_14].VAR_3 > 3*VAR_1 || buf[VAR_14].VAR_3>32) {                    \

            av_log(NULL, AV_LOG_ERROR, "Too long VLC (%d) in init_vlc\n", buf[VAR_14].VAR_3);\

            av_free(buf);                                                   \

            return -1;                                                      \

        }                                                                   \

        GET_DATA(buf[VAR_14].code, VAR_6, VAR_13, VAR_7, VAR_8);            \

        if (buf[VAR_14].code >= (1LL<<buf[VAR_14].VAR_3)) {                            \

            av_log(NULL, AV_LOG_ERROR, "Invalid code in init_vlc\n");       \

            av_free(buf);                                                   \

            return -1;                                                      \

        }                                                                   \

        if (VAR_12 & INIT_VLC_LE)                                            \

            buf[VAR_14].code = bitswap_32(buf[VAR_14].code);                          \

        else                                                                \

            buf[VAR_14].code <<= 32 - buf[VAR_14].VAR_3;                               \

        if (VAR_9)                                                        \

            GET_DATA(buf[VAR_14].symbol, VAR_9, VAR_13, VAR_10, VAR_11) \

        else                                                                \

            buf[VAR_14].symbol = VAR_13;                                              \

        VAR_14++;                                                                \

    }

    COPY(buf[VAR_14].VAR_3 > VAR_1);

    

    qsort(buf, VAR_14, sizeof(VLCcode), compare_vlcspec);

    COPY(buf[VAR_14].VAR_3 && buf[VAR_14].VAR_3 <= VAR_1);

    VAR_2 = VAR_14;



    VAR_15 = build_table(VAR_0, VAR_1, VAR_2, buf, VAR_12);



    av_free(buf);

    if (VAR_15 < 0) {

        av_freep(&VAR_0->table);

        return VAR_15;

    }

    return 0;

}
int FUNC_0(VLC *VAR_0, int VAR_1, int VAR_2,
const void *VAR_3, int VAR_4, int VAR_5,
const void *VAR_6, int VAR_7, int VAR_8,
const void *VAR_9, int VAR_10, int VAR_11,
int VAR_12)
{ VLCcode *buf; int VAR_13, VAR_14, VAR_15; VAR_0->VAR_3 = VAR_1; if (VAR_12 & INIT_VLC_USE_NEW_STATIC) { VLC dyn_vlc = *VAR_0; if (VAR_0->table_size)
return 0; VAR_15 = FUNC_0(&dyn_vlc, VAR_1, VAR_2,
VAR_3, VAR_4, VAR_5,
VAR_6, VAR_7, VAR_8,
VAR_9, VAR_10, VAR_11,
VAR_12 & ~INIT_VLC_USE_NEW_STATIC); av_assert0(VAR_15 >= 0); av_assert0(dyn_vlc.table_size <= VAR_0->table_allocated); if (dyn_vlc.table_size < VAR_0->table_allocated)
av_log(NULL, AV_LOG_ERROR, "needed %d had %d\n", dyn_vlc.table_size, VAR_0->table_allocated); memcpy(VAR_0->table, dyn_vlc.table, dyn_vlc.table_size * sizeof(*VAR_0->table)); VAR_0->table_size = dyn_vlc.table_size; ff_free_vlc(&dyn_vlc); return 0; } else { VAR_0->table           = NULL; VAR_0->table_allocated = 0; VAR_0->table_size      = 0; } av_dlog(NULL, "build table VAR_2=%d\n", VAR_2); buf = av_malloc((VAR_2 + 1) * sizeof(VLCcode)); av_assert0(VAR_11 <= 2 || !VAR_9); VAR_14 = 0; #define COPY(condition)\
for (VAR_13 = 0; VAR_13 < VAR_2; VAR_13++) {                                        \ GET_DATA(buf[VAR_14].VAR_3, VAR_3, VAR_13, VAR_4, VAR_5);               \ if (!(condition))                                                   \
continue;                                                       \ if (buf[VAR_14].VAR_3 > 3*VAR_1 || buf[VAR_14].VAR_3>32) {                    \ av_log(NULL, AV_LOG_ERROR, "Too long VLC (%d) in init_vlc\n", buf[VAR_14].VAR_3);\ av_free(buf);                                                   \ return -1;                                                      \ }                                                                   \ GET_DATA(buf[VAR_14].code, VAR_6, VAR_13, VAR_7, VAR_8);            \ if (buf[VAR_14].code >= (1LL<<buf[VAR_14].VAR_3)) {                            \ av_log(NULL, AV_LOG_ERROR, "Invalid code in init_vlc\n");       \ av_free(buf);                                                   \ return -1;                                                      \ }                                                                   \ if (VAR_12 & INIT_VLC_LE)                                            \
buf[VAR_14].code = bitswap_32(buf[VAR_14].code);                          \ else                                                                \
buf[VAR_14].code <<= 32 - buf[VAR_14].VAR_3;                               \ if (VAR_9)                                                        \
GET_DATA(buf[VAR_14].symbol, VAR_9, VAR_13, VAR_10, VAR_11) \
else                                                                \
buf[VAR_14].symbol = VAR_13;                                              \ VAR_14++;                                                                \ } COPY(buf[VAR_14].VAR_3 > VAR_1); qsort(buf, VAR_14, sizeof(VLCcode), compare_vlcspec); COPY(buf[VAR_14].VAR_3 && buf[VAR_14].VAR_3 <= VAR_1); VAR_2 = VAR_14; VAR_15 = build_table(VAR_0, VAR_1, VAR_2, buf, VAR_12); av_free(buf); if (VAR_15 < 0) { av_freep(&VAR_0->table); return VAR_15; } return 0; }