static void unpack_superblocks(Vp3DecodeContext *s, GetBitContext *gb)

{

    int bit = 0;

    int current_superblock = 0;

    int current_run = 0;

    int decode_fully_flags = 0;

    int decode_partial_blocks = 0;



    int i, j;

    int current_fragment;



    debug_vp3("  vp3: unpacking superblock coding\n");



    if (s->keyframe) {



        debug_vp3("    keyframe-- all superblocks are fully coded\n");

        memset(s->superblock_coding, SB_FULLY_CODED, s->superblock_count);



    } else {



        /* unpack the list of partially-coded superblocks */

        bit = get_bits(gb, 1);

        /* toggle the bit because as soon as the first run length is 

         * fetched the bit will be toggled again */

        bit ^= 1;

        while (current_superblock < s->superblock_count) {

            if (current_run == 0) {

                bit ^= 1;

                current_run = get_superblock_run_length(gb);

                debug_block_coding("      setting superblocks %d..%d to %s\n",

                    current_superblock,

                    current_superblock + current_run - 1,

                    (bit) ? "partially coded" : "not coded");



                /* if any of the superblocks are not partially coded, flag

                 * a boolean to decode the list of fully-coded superblocks */

                if (bit == 0)

                    decode_fully_flags = 1;

            } else {



                /* make a note of the fact that there are partially coded

                 * superblocks */

                decode_partial_blocks = 1;



            }

            s->superblock_coding[current_superblock++] = 

                (bit) ? SB_PARTIALLY_CODED : SB_NOT_CODED;

            current_run--;

        }



        /* unpack the list of fully coded superblocks if any of the blocks were

         * not marked as partially coded in the previous step */

        if (decode_fully_flags) {



            current_superblock = 0;

            current_run = 0;

            bit = get_bits(gb, 1);

            /* toggle the bit because as soon as the first run length is 

             * fetched the bit will be toggled again */

            bit ^= 1;

            while (current_superblock < s->superblock_count) {



                /* skip any superblocks already marked as partially coded */

                if (s->superblock_coding[current_superblock] == SB_NOT_CODED) {



                    if (current_run == 0) {

                        bit ^= 1;

                        current_run = get_superblock_run_length(gb);

                    }



                    debug_block_coding("      setting superblock %d to %s\n",

                        current_superblock,

                        (bit) ? "fully coded" : "not coded");

                    s->superblock_coding[current_superblock] = 

                        (bit) ? SB_FULLY_CODED : SB_NOT_CODED;

                    current_run--;

                }

                current_superblock++;

            }

        }



        /* if there were partial blocks, initialize bitstream for

         * unpacking fragment codings */

        if (decode_partial_blocks) {



            current_run = 0;

            bit = get_bits(gb, 1);

            /* toggle the bit because as soon as the first run length is 

             * fetched the bit will be toggled again */

            bit ^= 1;

        }

    }



    /* figure out which fragments are coded; iterate through each

     * superblock (all planes) */

    s->coded_fragment_list_index = 0;

    s->first_coded_y_fragment = s->first_coded_c_fragment = 0;

    s->last_coded_y_fragment = s->last_coded_c_fragment = -1;

    memset(s->macroblock_coded, 0, s->macroblock_count);

    for (i = 0; i < s->superblock_count; i++) {



        /* iterate through all 16 fragments in a superblock */

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



            /* if the fragment is in bounds, check its coding status */

            current_fragment = s->superblock_fragments[i * 16 + j];

            if (current_fragment != -1) {

                if (s->superblock_coding[i] == SB_NOT_CODED) {



                    /* copy all the fragments from the prior frame */

                    s->all_fragments[current_fragment].coding_method = 

                        MODE_COPY;



                } else if (s->superblock_coding[i] == SB_PARTIALLY_CODED) {



                    /* fragment may or may not be coded; this is the case

                     * that cares about the fragment coding runs */

                    if (current_run == 0) {

                        bit ^= 1;

                        current_run = get_fragment_run_length(gb);

                    }



                    if (bit) {

                        /* mode will be decoded in the next phase */

                        s->all_fragments[current_fragment].coding_method = 

                            MODE_INTER_NO_MV;

                        s->coded_fragment_list[s->coded_fragment_list_index] = 

                            current_fragment;

                        if ((current_fragment >= s->u_fragment_start) &&

                            (s->last_coded_y_fragment == -1)) {

                            s->first_coded_c_fragment = s->coded_fragment_list_index;

                            s->last_coded_y_fragment = s->first_coded_c_fragment - 1;

                        }

                        s->coded_fragment_list_index++;

                        s->macroblock_coded[s->all_fragments[current_fragment].macroblock] = 1;

                        debug_block_coding("      superblock %d is partially coded, fragment %d is coded\n",

                            i, current_fragment);

                    } else {

                        /* not coded; copy this fragment from the prior frame */

                        s->all_fragments[current_fragment].coding_method =

                            MODE_COPY;

                        debug_block_coding("      superblock %d is partially coded, fragment %d is not coded\n",

                            i, current_fragment);

                    }



                    current_run--;



                } else {



                    /* fragments are fully coded in this superblock; actual

                     * coding will be determined in next step */

                    s->all_fragments[current_fragment].coding_method = 

                        MODE_INTER_NO_MV;

                    s->coded_fragment_list[s->coded_fragment_list_index] = 

                        current_fragment;

                    if ((current_fragment >= s->u_fragment_start) &&

                        (s->last_coded_y_fragment == -1)) {

                        s->first_coded_c_fragment = s->coded_fragment_list_index;

                        s->last_coded_y_fragment = s->first_coded_c_fragment - 1;

                    }

                    s->coded_fragment_list_index++;

                    s->macroblock_coded[s->all_fragments[current_fragment].macroblock] = 1;

                    debug_block_coding("      superblock %d is fully coded, fragment %d is coded\n",

                        i, current_fragment);

                }

            }

        }

    }



    if (s->first_coded_c_fragment == 0)

        /* no C fragments coded */

        s->last_coded_y_fragment = s->coded_fragment_list_index - 1;

    else

        s->last_coded_c_fragment = s->coded_fragment_list_index - 1;

    debug_block_coding("    %d total coded fragments, y: %d -> %d, c: %d -> %d\n",

        s->coded_fragment_list_index,

        s->first_coded_y_fragment,

        s->last_coded_y_fragment,

        s->first_coded_c_fragment,

        s->last_coded_c_fragment);

}

static void unpack_superblocks(Vp3DecodeContext *s, GetBitContext *gb)

{

    int bit = 0;

    int current_superblock = 0;

    int current_run = 0;

    int decode_fully_flags = 0;

    int decode_partial_blocks = 0;



    int i, j;

    int current_fragment;



    debug_vp3("  vp3: unpacking superblock coding\n");



    if (s->keyframe) {



        debug_vp3("    keyframe-- all superblocks are fully coded\n");

        memset(s->superblock_coding, SB_FULLY_CODED, s->superblock_count);



    } else {



        

        bit = get_bits(gb, 1);

        



        bit ^= 1;

        while (current_superblock < s->superblock_count) {

            if (current_run == 0) {

                bit ^= 1;

                current_run = get_superblock_run_length(gb);

                debug_block_coding("      setting superblocks %d..%d to %s\n",

                    current_superblock,

                    current_superblock + current_run - 1,

                    (bit) ? "partially coded" : "not coded");



                



                if (bit == 0)

                    decode_fully_flags = 1;

            } else {



                



                decode_partial_blocks = 1;



            }

            s->superblock_coding[current_superblock++] = 

                (bit) ? SB_PARTIALLY_CODED : SB_NOT_CODED;

            current_run--;

        }



        



        if (decode_fully_flags) {



            current_superblock = 0;

            current_run = 0;

            bit = get_bits(gb, 1);

            



            bit ^= 1;

            while (current_superblock < s->superblock_count) {



                

                if (s->superblock_coding[current_superblock] == SB_NOT_CODED) {



                    if (current_run == 0) {

                        bit ^= 1;

                        current_run = get_superblock_run_length(gb);

                    }



                    debug_block_coding("      setting superblock %d to %s\n",

                        current_superblock,

                        (bit) ? "fully coded" : "not coded");

                    s->superblock_coding[current_superblock] = 

                        (bit) ? SB_FULLY_CODED : SB_NOT_CODED;

                    current_run--;

                }

                current_superblock++;

            }

        }



        



        if (decode_partial_blocks) {



            current_run = 0;

            bit = get_bits(gb, 1);

            



            bit ^= 1;

        }

    }



    



    s->coded_fragment_list_index = 0;

    s->first_coded_y_fragment = s->first_coded_c_fragment = 0;

    s->last_coded_y_fragment = s->last_coded_c_fragment = -1;

    memset(s->macroblock_coded, 0, s->macroblock_count);

    for (i = 0; i < s->superblock_count; i++) {



        

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



            

            current_fragment = s->superblock_fragments[i * 16 + j];

            if (current_fragment != -1) {

                if (s->superblock_coding[i] == SB_NOT_CODED) {



                    

                    s->all_fragments[current_fragment].coding_method = 

                        MODE_COPY;



                } else if (s->superblock_coding[i] == SB_PARTIALLY_CODED) {



                    



                    if (current_run == 0) {

                        bit ^= 1;

                        current_run = get_fragment_run_length(gb);

                    }



                    if (bit) {

                        

                        s->all_fragments[current_fragment].coding_method = 

                            MODE_INTER_NO_MV;

                        s->coded_fragment_list[s->coded_fragment_list_index] = 

                            current_fragment;

                        if ((current_fragment >= s->u_fragment_start) &&

                            (s->last_coded_y_fragment == -1)) {

                            s->first_coded_c_fragment = s->coded_fragment_list_index;

                            s->last_coded_y_fragment = s->first_coded_c_fragment - 1;

                        }

                        s->coded_fragment_list_index++;

                        s->macroblock_coded[s->all_fragments[current_fragment].macroblock] = 1;

                        debug_block_coding("      superblock %d is partially coded, fragment %d is coded\n",

                            i, current_fragment);

                    } else {

                        

                        s->all_fragments[current_fragment].coding_method =

                            MODE_COPY;

                        debug_block_coding("      superblock %d is partially coded, fragment %d is not coded\n",

                            i, current_fragment);

                    }



                    current_run--;



                } else {



                    



                    s->all_fragments[current_fragment].coding_method = 

                        MODE_INTER_NO_MV;

                    s->coded_fragment_list[s->coded_fragment_list_index] = 

                        current_fragment;

                    if ((current_fragment >= s->u_fragment_start) &&

                        (s->last_coded_y_fragment == -1)) {

                        s->first_coded_c_fragment = s->coded_fragment_list_index;

                        s->last_coded_y_fragment = s->first_coded_c_fragment - 1;

                    }

                    s->coded_fragment_list_index++;

                    s->macroblock_coded[s->all_fragments[current_fragment].macroblock] = 1;

                    debug_block_coding("      superblock %d is fully coded, fragment %d is coded\n",

                        i, current_fragment);

                }

            }

        }

    }



    if (s->first_coded_c_fragment == 0)

        

        s->last_coded_y_fragment = s->coded_fragment_list_index - 1;

    else

        s->last_coded_c_fragment = s->coded_fragment_list_index - 1;

    debug_block_coding("    %d total coded fragments, y: %d -> %d, c: %d -> %d\n",

        s->coded_fragment_list_index,

        s->first_coded_y_fragment,

        s->last_coded_y_fragment,

        s->first_coded_c_fragment,

        s->last_coded_c_fragment);

}

static void FUNC_0(Vp3DecodeContext *VAR_0, GetBitContext *VAR_1)

{

    int VAR_2 = 0;

    int VAR_3 = 0;

    int VAR_4 = 0;

    int VAR_5 = 0;

    int VAR_6 = 0;



    int VAR_7, VAR_8;

    int VAR_9;



    debug_vp3("  vp3: unpacking superblock coding\n");



    if (VAR_0->keyframe) {



        debug_vp3("    keyframe-- all superblocks are fully coded\n");

        memset(VAR_0->superblock_coding, SB_FULLY_CODED, VAR_0->superblock_count);



    } else {



        

        VAR_2 = get_bits(VAR_1, 1);

        



        VAR_2 ^= 1;

        while (VAR_3 < VAR_0->superblock_count) {

            if (VAR_4 == 0) {

                VAR_2 ^= 1;

                VAR_4 = get_superblock_run_length(VAR_1);

                debug_block_coding("      setting superblocks %d..%d to %VAR_0\n",

                    VAR_3,

                    VAR_3 + VAR_4 - 1,

                    (VAR_2) ? "partially coded" : "not coded");



                



                if (VAR_2 == 0)

                    VAR_5 = 1;

            } else {



                



                VAR_6 = 1;



            }

            VAR_0->superblock_coding[VAR_3++] = 

                (VAR_2) ? SB_PARTIALLY_CODED : SB_NOT_CODED;

            VAR_4--;

        }



        



        if (VAR_5) {



            VAR_3 = 0;

            VAR_4 = 0;

            VAR_2 = get_bits(VAR_1, 1);

            



            VAR_2 ^= 1;

            while (VAR_3 < VAR_0->superblock_count) {



                

                if (VAR_0->superblock_coding[VAR_3] == SB_NOT_CODED) {



                    if (VAR_4 == 0) {

                        VAR_2 ^= 1;

                        VAR_4 = get_superblock_run_length(VAR_1);

                    }



                    debug_block_coding("      setting superblock %d to %VAR_0\n",

                        VAR_3,

                        (VAR_2) ? "fully coded" : "not coded");

                    VAR_0->superblock_coding[VAR_3] = 

                        (VAR_2) ? SB_FULLY_CODED : SB_NOT_CODED;

                    VAR_4--;

                }

                VAR_3++;

            }

        }



        



        if (VAR_6) {



            VAR_4 = 0;

            VAR_2 = get_bits(VAR_1, 1);

            



            VAR_2 ^= 1;

        }

    }



    



    VAR_0->coded_fragment_list_index = 0;

    VAR_0->first_coded_y_fragment = VAR_0->first_coded_c_fragment = 0;

    VAR_0->last_coded_y_fragment = VAR_0->last_coded_c_fragment = -1;

    memset(VAR_0->macroblock_coded, 0, VAR_0->macroblock_count);

    for (VAR_7 = 0; VAR_7 < VAR_0->superblock_count; VAR_7++) {



        

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



            

            VAR_9 = VAR_0->superblock_fragments[VAR_7 * 16 + VAR_8];

            if (VAR_9 != -1) {

                if (VAR_0->superblock_coding[VAR_7] == SB_NOT_CODED) {



                    

                    VAR_0->all_fragments[VAR_9].coding_method = 

                        MODE_COPY;



                } else if (VAR_0->superblock_coding[VAR_7] == SB_PARTIALLY_CODED) {



                    



                    if (VAR_4 == 0) {

                        VAR_2 ^= 1;

                        VAR_4 = get_fragment_run_length(VAR_1);

                    }



                    if (VAR_2) {

                        

                        VAR_0->all_fragments[VAR_9].coding_method = 

                            MODE_INTER_NO_MV;

                        VAR_0->coded_fragment_list[VAR_0->coded_fragment_list_index] = 

                            VAR_9;

                        if ((VAR_9 >= VAR_0->u_fragment_start) &&

                            (VAR_0->last_coded_y_fragment == -1)) {

                            VAR_0->first_coded_c_fragment = VAR_0->coded_fragment_list_index;

                            VAR_0->last_coded_y_fragment = VAR_0->first_coded_c_fragment - 1;

                        }

                        VAR_0->coded_fragment_list_index++;

                        VAR_0->macroblock_coded[VAR_0->all_fragments[VAR_9].macroblock] = 1;

                        debug_block_coding("      superblock %d is partially coded, fragment %d is coded\n",

                            VAR_7, VAR_9);

                    } else {

                        

                        VAR_0->all_fragments[VAR_9].coding_method =

                            MODE_COPY;

                        debug_block_coding("      superblock %d is partially coded, fragment %d is not coded\n",

                            VAR_7, VAR_9);

                    }



                    VAR_4--;



                } else {



                    



                    VAR_0->all_fragments[VAR_9].coding_method = 

                        MODE_INTER_NO_MV;

                    VAR_0->coded_fragment_list[VAR_0->coded_fragment_list_index] = 

                        VAR_9;

                    if ((VAR_9 >= VAR_0->u_fragment_start) &&

                        (VAR_0->last_coded_y_fragment == -1)) {

                        VAR_0->first_coded_c_fragment = VAR_0->coded_fragment_list_index;

                        VAR_0->last_coded_y_fragment = VAR_0->first_coded_c_fragment - 1;

                    }

                    VAR_0->coded_fragment_list_index++;

                    VAR_0->macroblock_coded[VAR_0->all_fragments[VAR_9].macroblock] = 1;

                    debug_block_coding("      superblock %d is fully coded, fragment %d is coded\n",

                        VAR_7, VAR_9);

                }

            }

        }

    }



    if (VAR_0->first_coded_c_fragment == 0)

        

        VAR_0->last_coded_y_fragment = VAR_0->coded_fragment_list_index - 1;

    else

        VAR_0->last_coded_c_fragment = VAR_0->coded_fragment_list_index - 1;

    debug_block_coding("    %d total coded fragments, y: %d -> %d, c: %d -> %d\n",

        VAR_0->coded_fragment_list_index,

        VAR_0->first_coded_y_fragment,

        VAR_0->last_coded_y_fragment,

        VAR_0->first_coded_c_fragment,

        VAR_0->last_coded_c_fragment);

}

static void FUNC_0(Vp3DecodeContext *VAR_0, GetBitContext *VAR_1)
{ int VAR_2 = 0; int VAR_3 = 0; int VAR_4 = 0; int VAR_5 = 0; int VAR_6 = 0; int VAR_7, VAR_8; int VAR_9; debug_vp3("  vp3: unpacking superblock coding\n"); if (VAR_0->keyframe) { debug_vp3("    keyframe-- all superblocks are fully coded\n"); memset(VAR_0->superblock_coding, SB_FULLY_CODED, VAR_0->superblock_count); } else { VAR_2 = get_bits(VAR_1, 1); VAR_2 ^= 1; while (VAR_3 < VAR_0->superblock_count) { if (VAR_4 == 0) { VAR_2 ^= 1; VAR_4 = get_superblock_run_length(VAR_1); debug_block_coding("      setting superblocks %d..%d to %VAR_0\n",
VAR_3,
VAR_3 + VAR_4 - 1,
(VAR_2) ? "partially coded" : "not coded"); if (VAR_2 == 0)
VAR_5 = 1; } else { VAR_6 = 1; } VAR_0->superblock_coding[VAR_3++] =
(VAR_2) ? SB_PARTIALLY_CODED : SB_NOT_CODED; VAR_4--; } if (VAR_5) { VAR_3 = 0; VAR_4 = 0; VAR_2 = get_bits(VAR_1, 1); VAR_2 ^= 1; while (VAR_3 < VAR_0->superblock_count) { if (VAR_0->superblock_coding[VAR_3] == SB_NOT_CODED) { if (VAR_4 == 0) { VAR_2 ^= 1; VAR_4 = get_superblock_run_length(VAR_1); } debug_block_coding("      setting superblock %d to %VAR_0\n",
VAR_3,
(VAR_2) ? "fully coded" : "not coded"); VAR_0->superblock_coding[VAR_3] =
(VAR_2) ? SB_FULLY_CODED : SB_NOT_CODED; VAR_4--; } VAR_3++; } } if (VAR_6) { VAR_4 = 0; VAR_2 = get_bits(VAR_1, 1); VAR_2 ^= 1; } } VAR_0->coded_fragment_list_index = 0; VAR_0->first_coded_y_fragment = VAR_0->first_coded_c_fragment = 0; VAR_0->last_coded_y_fragment = VAR_0->last_coded_c_fragment = -1; memset(VAR_0->macroblock_coded, 0, VAR_0->macroblock_count); for (VAR_7 = 0; VAR_7 < VAR_0->superblock_count; VAR_7++) { for (VAR_8 = 0; VAR_8 < 16; VAR_8++) { VAR_9 = VAR_0->superblock_fragments[VAR_7 * 16 + VAR_8]; if (VAR_9 != -1) { if (VAR_0->superblock_coding[VAR_7] == SB_NOT_CODED) { VAR_0->all_fragments[VAR_9].coding_method =
MODE_COPY; } else if (VAR_0->superblock_coding[VAR_7] == SB_PARTIALLY_CODED) { if (VAR_4 == 0) { VAR_2 ^= 1; VAR_4 = get_fragment_run_length(VAR_1); } if (VAR_2) { VAR_0->all_fragments[VAR_9].coding_method =
MODE_INTER_NO_MV; VAR_0->coded_fragment_list[VAR_0->coded_fragment_list_index] =
VAR_9; if ((VAR_9 >= VAR_0->u_fragment_start) &&
(VAR_0->last_coded_y_fragment == -1)) { VAR_0->first_coded_c_fragment = VAR_0->coded_fragment_list_index; VAR_0->last_coded_y_fragment = VAR_0->first_coded_c_fragment - 1; } VAR_0->coded_fragment_list_index++; VAR_0->macroblock_coded[VAR_0->all_fragments[VAR_9].macroblock] = 1; debug_block_coding("      superblock %d is partially coded, fragment %d is coded\n",
VAR_7, VAR_9); } else { VAR_0->all_fragments[VAR_9].coding_method =
MODE_COPY; debug_block_coding("      superblock %d is partially coded, fragment %d is not coded\n",
VAR_7, VAR_9); } VAR_4--; } else { VAR_0->all_fragments[VAR_9].coding_method =
MODE_INTER_NO_MV; VAR_0->coded_fragment_list[VAR_0->coded_fragment_list_index] =
VAR_9; if ((VAR_9 >= VAR_0->u_fragment_start) &&
(VAR_0->last_coded_y_fragment == -1)) { VAR_0->first_coded_c_fragment = VAR_0->coded_fragment_list_index; VAR_0->last_coded_y_fragment = VAR_0->first_coded_c_fragment - 1; } VAR_0->coded_fragment_list_index++; VAR_0->macroblock_coded[VAR_0->all_fragments[VAR_9].macroblock] = 1; debug_block_coding("      superblock %d is fully coded, fragment %d is coded\n",
VAR_7, VAR_9); } } } } if (VAR_0->first_coded_c_fragment == 0)
VAR_0->last_coded_y_fragment = VAR_0->coded_fragment_list_index - 1; else
VAR_0->last_coded_c_fragment = VAR_0->coded_fragment_list_index - 1; debug_block_coding("    %d total coded fragments, y: %d -> %d, c: %d -> %d\n",
VAR_0->coded_fragment_list_index,
VAR_0->first_coded_y_fragment,
VAR_0->last_coded_y_fragment,
VAR_0->first_coded_c_fragment,
VAR_0->last_coded_c_fragment); }