static int bitplane_decoding(uint8_t* plane, int width, int height, VC9Context *v)

{

    int imode, x, y, i, code, use_vertical_tile, tile_w, tile_h;

    uint8_t invert, *planep = plane;

    int stride= width;



    invert = get_bits(&v->gb, 1);

    imode = get_vlc2(&v->gb, vc9_imode_vlc.table, VC9_IMODE_VLC_BITS, 2);

    av_log(v->avctx, AV_LOG_DEBUG, "Bitplane: imode=%i, invert=%i\n",

           imode, invert);



    switch (imode)

    {

    case IMODE_RAW:

        for (y=0; y<height; y++)

        {

            for (x=0; x<width; x++)

                planep[x] = (-get_bits(&v->gb, 1)); //-1=0xFF

            planep += stride;

        }

        invert=0; //spec says ignore invert if raw

        break;

    case IMODE_DIFF2:

    case IMODE_NORM2:

        if ((height*width) & 1) *(++planep) = get_bits(&v->gb, 1);

        for(i=0; i<(height*width)>>1; i++){

            code = get_vlc2(&v->gb, vc9_norm2_vlc.table, VC9_NORM2_VLC_BITS, 2);

            *(++planep) = code&1; //lsb => left

            *(++planep) = code&2; //msb => right - this is a bitplane, so only !0 matters

            //FIXME width->stride

        }

        break;

    case IMODE_DIFF6:

    case IMODE_NORM6:

        use_vertical_tile= height%3==0 && width%3!=0;

        tile_w= use_vertical_tile ? 2 : 3;

        tile_h= use_vertical_tile ? 3 : 2;



        for(y= height%tile_h; y<height; y+=tile_h){

            for(x= width%tile_w; x<width; x+=tile_w){

                code = get_vlc2(&v->gb, vc9_norm6_vlc.table, VC9_NORM6_VLC_BITS, 2);

                //FIXME following is a pure guess and probably wrong

                planep[x     + 0*stride]= (code>>0)&1;

                planep[x + 1 + 0*stride]= (code>>1)&1;

                if(use_vertical_tile){

                    planep[x + 0 + 1*stride]= (code>>2)&1;

                    planep[x + 1 + 1*stride]= (code>>3)&1;

                    planep[x + 0 + 2*stride]= (code>>4)&1;

                    planep[x + 1 + 2*stride]= (code>>5)&1;

                }else{

                    planep[x + 2 + 0*stride]= (code>>2)&1;

                    planep[x + 0 + 1*stride]= (code>>3)&1;

                    planep[x + 1 + 1*stride]= (code>>4)&1;

                    planep[x + 2 + 1*stride]= (code>>5)&1;

                }

            }

        }



        x= width % tile_w;

        decode_colskip(plane  ,         x, height         , stride, v);

        decode_rowskip(plane+x, width - x, height % tile_h, stride, v);



        break;

    case IMODE_ROWSKIP:

        decode_rowskip(plane, width, height, stride, v);

        break;

    case IMODE_COLSKIP: //Teh ugly

        decode_colskip(plane, width, height, stride, v);

        break;

    default: break;

    }



    /* Applying diff operator */

    if (imode == IMODE_DIFF2 || imode == IMODE_DIFF6)

    {

        planep = plane;

        planep[0] ^= invert;

        for (x=1; x<width; x++)

            planep[x] ^= planep[x-1];

        for (y=1; y<height; y++)

        {

            planep += stride;

            planep[0] ^= planep[-stride];

            for (x=1; x<width; x++)

            {

                if (planep[x-1] != planep[x-stride]) planep[x] ^= invert;

                else                                 planep[x] ^= planep[x-1];

            }

        }

    }

    else if (invert)

    {

        planep = plane;

        for (x=0; x<width*height; x++) planep[x] = !planep[x]; //FIXME stride

    }

    return 0;

}

static int bitplane_decoding(uint8_t* plane, int width, int height, VC9Context *v)

{

    int imode, x, y, i, code, use_vertical_tile, tile_w, tile_h;

    uint8_t invert, *planep = plane;

    int stride= width;



    invert = get_bits(&v->gb, 1);

    imode = get_vlc2(&v->gb, vc9_imode_vlc.table, VC9_IMODE_VLC_BITS, 2);

    av_log(v->avctx, AV_LOG_DEBUG, "Bitplane: imode=%i, invert=%i\n",

           imode, invert);



    switch (imode)

    {

    case IMODE_RAW:

        for (y=0; y<height; y++)

        {

            for (x=0; x<width; x++)

                planep[x] = (-get_bits(&v->gb, 1)); 

            planep += stride;

        }

        invert=0; 

        break;

    case IMODE_DIFF2:

    case IMODE_NORM2:

        if ((height*width) & 1) *(++planep) = get_bits(&v->gb, 1);

        for(i=0; i<(height*width)>>1; i++){

            code = get_vlc2(&v->gb, vc9_norm2_vlc.table, VC9_NORM2_VLC_BITS, 2);

            *(++planep) = code&1; 

            *(++planep) = code&2; 

            

        }

        break;

    case IMODE_DIFF6:

    case IMODE_NORM6:

        use_vertical_tile= height%3==0 && width%3!=0;

        tile_w= use_vertical_tile ? 2 : 3;

        tile_h= use_vertical_tile ? 3 : 2;



        for(y= height%tile_h; y<height; y+=tile_h){

            for(x= width%tile_w; x<width; x+=tile_w){

                code = get_vlc2(&v->gb, vc9_norm6_vlc.table, VC9_NORM6_VLC_BITS, 2);

                

                planep[x     + 0*stride]= (code>>0)&1;

                planep[x + 1 + 0*stride]= (code>>1)&1;

                if(use_vertical_tile){

                    planep[x + 0 + 1*stride]= (code>>2)&1;

                    planep[x + 1 + 1*stride]= (code>>3)&1;

                    planep[x + 0 + 2*stride]= (code>>4)&1;

                    planep[x + 1 + 2*stride]= (code>>5)&1;

                }else{

                    planep[x + 2 + 0*stride]= (code>>2)&1;

                    planep[x + 0 + 1*stride]= (code>>3)&1;

                    planep[x + 1 + 1*stride]= (code>>4)&1;

                    planep[x + 2 + 1*stride]= (code>>5)&1;

                }

            }

        }



        x= width % tile_w;

        decode_colskip(plane  ,         x, height         , stride, v);

        decode_rowskip(plane+x, width - x, height % tile_h, stride, v);



        break;

    case IMODE_ROWSKIP:

        decode_rowskip(plane, width, height, stride, v);

        break;

    case IMODE_COLSKIP: 

        decode_colskip(plane, width, height, stride, v);

        break;

    default: break;

    }



    

    if (imode == IMODE_DIFF2 || imode == IMODE_DIFF6)

    {

        planep = plane;

        planep[0] ^= invert;

        for (x=1; x<width; x++)

            planep[x] ^= planep[x-1];

        for (y=1; y<height; y++)

        {

            planep += stride;

            planep[0] ^= planep[-stride];

            for (x=1; x<width; x++)

            {

                if (planep[x-1] != planep[x-stride]) planep[x] ^= invert;

                else                                 planep[x] ^= planep[x-1];

            }

        }

    }

    else if (invert)

    {

        planep = plane;

        for (x=0; x<width*height; x++) planep[x] = !planep[x]; 

    }

    return 0;

}

static int FUNC_0(uint8_t* VAR_0, int VAR_1, int VAR_2, VC9Context *VAR_3)

{

    int VAR_4, VAR_5, VAR_6, VAR_7, VAR_8, VAR_9, VAR_10, VAR_11;

    uint8_t invert, *planep = VAR_0;

    int VAR_12= VAR_1;



    invert = get_bits(&VAR_3->gb, 1);

    VAR_4 = get_vlc2(&VAR_3->gb, vc9_imode_vlc.table, VC9_IMODE_VLC_BITS, 2);

    av_log(VAR_3->avctx, AV_LOG_DEBUG, "Bitplane: VAR_4=%VAR_7, invert=%VAR_7\n",

           VAR_4, invert);



    switch (VAR_4)

    {

    case IMODE_RAW:

        for (VAR_6=0; VAR_6<VAR_2; VAR_6++)

        {

            for (VAR_5=0; VAR_5<VAR_1; VAR_5++)

                planep[VAR_5] = (-get_bits(&VAR_3->gb, 1)); 

            planep += VAR_12;

        }

        invert=0; 

        break;

    case IMODE_DIFF2:

    case IMODE_NORM2:

        if ((VAR_2*VAR_1) & 1) *(++planep) = get_bits(&VAR_3->gb, 1);

        for(VAR_7=0; VAR_7<(VAR_2*VAR_1)>>1; VAR_7++){

            VAR_8 = get_vlc2(&VAR_3->gb, vc9_norm2_vlc.table, VC9_NORM2_VLC_BITS, 2);

            *(++planep) = VAR_8&1; 

            *(++planep) = VAR_8&2; 

            

        }

        break;

    case IMODE_DIFF6:

    case IMODE_NORM6:

        VAR_9= VAR_2%3==0 && VAR_1%3!=0;

        VAR_10= VAR_9 ? 2 : 3;

        VAR_11= VAR_9 ? 3 : 2;



        for(VAR_6= VAR_2%VAR_11; VAR_6<VAR_2; VAR_6+=VAR_11){

            for(VAR_5= VAR_1%VAR_10; VAR_5<VAR_1; VAR_5+=VAR_10){

                VAR_8 = get_vlc2(&VAR_3->gb, vc9_norm6_vlc.table, VC9_NORM6_VLC_BITS, 2);

                

                planep[VAR_5     + 0*VAR_12]= (VAR_8>>0)&1;

                planep[VAR_5 + 1 + 0*VAR_12]= (VAR_8>>1)&1;

                if(VAR_9){

                    planep[VAR_5 + 0 + 1*VAR_12]= (VAR_8>>2)&1;

                    planep[VAR_5 + 1 + 1*VAR_12]= (VAR_8>>3)&1;

                    planep[VAR_5 + 0 + 2*VAR_12]= (VAR_8>>4)&1;

                    planep[VAR_5 + 1 + 2*VAR_12]= (VAR_8>>5)&1;

                }else{

                    planep[VAR_5 + 2 + 0*VAR_12]= (VAR_8>>2)&1;

                    planep[VAR_5 + 0 + 1*VAR_12]= (VAR_8>>3)&1;

                    planep[VAR_5 + 1 + 1*VAR_12]= (VAR_8>>4)&1;

                    planep[VAR_5 + 2 + 1*VAR_12]= (VAR_8>>5)&1;

                }

            }

        }



        VAR_5= VAR_1 % VAR_10;

        decode_colskip(VAR_0  ,         VAR_5, VAR_2         , VAR_12, VAR_3);

        decode_rowskip(VAR_0+VAR_5, VAR_1 - VAR_5, VAR_2 % VAR_11, VAR_12, VAR_3);



        break;

    case IMODE_ROWSKIP:

        decode_rowskip(VAR_0, VAR_1, VAR_2, VAR_12, VAR_3);

        break;

    case IMODE_COLSKIP: 

        decode_colskip(VAR_0, VAR_1, VAR_2, VAR_12, VAR_3);

        break;

    default: break;

    }



    

    if (VAR_4 == IMODE_DIFF2 || VAR_4 == IMODE_DIFF6)

    {

        planep = VAR_0;

        planep[0] ^= invert;

        for (VAR_5=1; VAR_5<VAR_1; VAR_5++)

            planep[VAR_5] ^= planep[VAR_5-1];

        for (VAR_6=1; VAR_6<VAR_2; VAR_6++)

        {

            planep += VAR_12;

            planep[0] ^= planep[-VAR_12];

            for (VAR_5=1; VAR_5<VAR_1; VAR_5++)

            {

                if (planep[VAR_5-1] != planep[VAR_5-VAR_12]) planep[VAR_5] ^= invert;

                else                                 planep[VAR_5] ^= planep[VAR_5-1];

            }

        }

    }

    else if (invert)

    {

        planep = VAR_0;

        for (VAR_5=0; VAR_5<VAR_1*VAR_2; VAR_5++) planep[VAR_5] = !planep[VAR_5]; 

    }

    return 0;

}

static int FUNC_0(uint8_t* VAR_0, int VAR_1, int VAR_2, VC9Context *VAR_3)
{ int VAR_4, VAR_5, VAR_6, VAR_7, VAR_8, VAR_9, VAR_10, VAR_11; uint8_t invert, *planep = VAR_0; int VAR_12= VAR_1; invert = get_bits(&VAR_3->gb, 1); VAR_4 = get_vlc2(&VAR_3->gb, vc9_imode_vlc.table, VC9_IMODE_VLC_BITS, 2); av_log(VAR_3->avctx, AV_LOG_DEBUG, "Bitplane: VAR_4=%VAR_7, invert=%VAR_7\n",
VAR_4, invert); switch (VAR_4)
{ case IMODE_RAW:
for (VAR_6=0; VAR_6<VAR_2; VAR_6++) { for (VAR_5=0; VAR_5<VAR_1; VAR_5++) planep[VAR_5] = (-get_bits(&VAR_3->gb, 1)); planep += VAR_12; } invert=0; break; case IMODE_DIFF2:
case IMODE_NORM2:
if ((VAR_2*VAR_1) & 1) *(++planep) = get_bits(&VAR_3->gb, 1); for(VAR_7=0; VAR_7<(VAR_2*VAR_1)>>1; VAR_7++){ VAR_8 = get_vlc2(&VAR_3->gb, vc9_norm2_vlc.table, VC9_NORM2_VLC_BITS, 2); *(++planep) = VAR_8&1; *(++planep) = VAR_8&2; } break; case IMODE_DIFF6:
case IMODE_NORM6:
VAR_9= VAR_2%3==0 && VAR_1%3!=0; VAR_10= VAR_9 ? 2 : 3; VAR_11= VAR_9 ? 3 : 2; for(VAR_6= VAR_2%VAR_11; VAR_6<VAR_2; VAR_6+=VAR_11){ for(VAR_5= VAR_1%VAR_10; VAR_5<VAR_1; VAR_5+=VAR_10){ VAR_8 = get_vlc2(&VAR_3->gb, vc9_norm6_vlc.table, VC9_NORM6_VLC_BITS, 2); planep[VAR_5     + 0*VAR_12]= (VAR_8>>0)&1; planep[VAR_5 + 1 + 0*VAR_12]= (VAR_8>>1)&1; if(VAR_9){ planep[VAR_5 + 0 + 1*VAR_12]= (VAR_8>>2)&1; planep[VAR_5 + 1 + 1*VAR_12]= (VAR_8>>3)&1; planep[VAR_5 + 0 + 2*VAR_12]= (VAR_8>>4)&1; planep[VAR_5 + 1 + 2*VAR_12]= (VAR_8>>5)&1; }else{ planep[VAR_5 + 2 + 0*VAR_12]= (VAR_8>>2)&1; planep[VAR_5 + 0 + 1*VAR_12]= (VAR_8>>3)&1; planep[VAR_5 + 1 + 1*VAR_12]= (VAR_8>>4)&1; planep[VAR_5 + 2 + 1*VAR_12]= (VAR_8>>5)&1; } } } VAR_5= VAR_1 % VAR_10; decode_colskip(VAR_0  ,         VAR_5, VAR_2         , VAR_12, VAR_3); decode_rowskip(VAR_0+VAR_5, VAR_1 - VAR_5, VAR_2 % VAR_11, VAR_12, VAR_3); break; case IMODE_ROWSKIP:
decode_rowskip(VAR_0, VAR_1, VAR_2, VAR_12, VAR_3); break; case IMODE_COLSKIP:
decode_colskip(VAR_0, VAR_1, VAR_2, VAR_12, VAR_3); break; default: break; } if (VAR_4 == IMODE_DIFF2 || VAR_4 == IMODE_DIFF6)
{ planep = VAR_0; planep[0] ^= invert; for (VAR_5=1; VAR_5<VAR_1; VAR_5++) planep[VAR_5] ^= planep[VAR_5-1]; for (VAR_6=1; VAR_6<VAR_2; VAR_6++) { planep += VAR_12; planep[0] ^= planep[-VAR_12]; for (VAR_5=1; VAR_5<VAR_1; VAR_5++) { if (planep[VAR_5-1] != planep[VAR_5-VAR_12]) planep[VAR_5] ^= invert; else                                 planep[VAR_5] ^= planep[VAR_5-1]; } } } else if (invert)
{ planep = VAR_0; for (VAR_5=0; VAR_5<VAR_1*VAR_2; VAR_5++) planep[VAR_5] = !planep[VAR_5]; } return 0; }