/*
 * This file is part of FFmpeg.
 *
 * FFmpeg is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * FFmpeg is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with FFmpeg; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

/**
 * @file
 * @brief IntraX8 (J-Frame) subdecoder, used by WMV2 and VC-1
 */

#include "libavutil/avassert.h"
#include "avcodec.h"
#include "error_resilience.h"
#include "get_bits.h"
#include "idctdsp.h"
#include "mpegvideo.h"
#include "msmpeg4data.h"
#include "intrax8huf.h"
#include "intrax8.h"
#include "intrax8dsp.h"

#define MAX_TABLE_DEPTH(table_bits, max_bits) ((max_bits+table_bits-1)/table_bits)

#define DC_VLC_BITS 9
#define AC_VLC_BITS 9
#define OR_VLC_BITS 7

#define DC_VLC_MTD MAX_TABLE_DEPTH(DC_VLC_BITS, MAX_DC_VLC_BITS)
#define AC_VLC_MTD MAX_TABLE_DEPTH(AC_VLC_BITS, MAX_AC_VLC_BITS)
#define OR_VLC_MTD MAX_TABLE_DEPTH(OR_VLC_BITS, MAX_OR_VLC_BITS)

static VLC j_ac_vlc[2][2][8];  //[quant<13],[intra/inter],[select]
static VLC j_dc_vlc[2][8];     //[quant], [select]
static VLC j_orient_vlc[2][4]; //[quant], [select]

static av_cold void x8_vlc_init(void){
    int i;
    int offset = 0;
    int sizeidx = 0;
    static const uint16_t sizes[8*4 + 8*2 + 2 + 4] = {
        576, 548, 582, 618, 546, 616, 560, 642,
        584, 582, 704, 664, 512, 544, 656, 640,
        512, 648, 582, 566, 532, 614, 596, 648,
        586, 552, 584, 590, 544, 578, 584, 624,

        528, 528, 526, 528, 536, 528, 526, 544,
        544, 512, 512, 528, 528, 544, 512, 544,

        128, 128, 128, 128, 128, 128};

    static VLC_TYPE table[28150][2];

#define  init_ac_vlc(dst,src) \
    dst.table = &table[offset]; \
    dst.table_allocated = sizes[sizeidx]; \
    offset += sizes[sizeidx++]; \
       init_vlc(&dst, \
              AC_VLC_BITS,77, \
              &src[1],4,2, \
              &src[0],4,2, \
              INIT_VLC_USE_NEW_STATIC)
//set ac tables
    for(i=0;i<8;i++){
        init_ac_vlc( j_ac_vlc[0][0][i], x8_ac0_highquant_table[i][0] );
        init_ac_vlc( j_ac_vlc[0][1][i], x8_ac1_highquant_table[i][0] );
        init_ac_vlc( j_ac_vlc[1][0][i], x8_ac0_lowquant_table [i][0] );
        init_ac_vlc( j_ac_vlc[1][1][i], x8_ac1_lowquant_table [i][0] );
    }
#undef init_ac_vlc

//set dc tables
#define init_dc_vlc(dst,src) \
    dst.table = &table[offset]; \
    dst.table_allocated = sizes[sizeidx]; \
    offset += sizes[sizeidx++]; \
        init_vlc(&dst, \
        DC_VLC_BITS,34, \
        &src[1],4,2, \
        &src[0],4,2, \
        INIT_VLC_USE_NEW_STATIC);
    for(i=0;i<8;i++){
        init_dc_vlc( j_dc_vlc[0][i], x8_dc_highquant_table[i][0]);
        init_dc_vlc( j_dc_vlc[1][i], x8_dc_lowquant_table [i][0]);
    }
#undef init_dc_vlc

//set orient tables
#define init_or_vlc(dst,src) \
    dst.table = &table[offset]; \
    dst.table_allocated = sizes[sizeidx]; \
    offset += sizes[sizeidx++]; \
    init_vlc(&dst, \
    OR_VLC_BITS,12, \
    &src[1],4,2, \
    &src[0],4,2, \
    INIT_VLC_USE_NEW_STATIC);
    for(i=0;i<2;i++){
        init_or_vlc( j_orient_vlc[0][i], x8_orient_highquant_table[i][0]);
    }
    for(i=0;i<4;i++){
        init_or_vlc( j_orient_vlc[1][i], x8_orient_lowquant_table [i][0])
    }
    if (offset != sizeof(table)/sizeof(VLC_TYPE)/2)
        av_log(NULL, AV_LOG_ERROR, "table size %i does not match needed %i\n", (int)(sizeof(table)/sizeof(VLC_TYPE)/2), offset);
}
#undef init_or_vlc

static void x8_reset_vlc_tables(IntraX8Context * w){
    memset(w->j_dc_vlc,0,sizeof(w->j_dc_vlc));
    memset(w->j_ac_vlc,0,sizeof(w->j_ac_vlc));
    w->j_orient_vlc=NULL;
}

static inline void x8_select_ac_table(IntraX8Context * const w , int mode){
    MpegEncContext * const s= w->s;
    int table_index;

    av_assert2(mode<4);

    if( w->j_ac_vlc[mode] ) return;

    table_index = get_bits(&s->gb, 3);
    w->j_ac_vlc[mode] = &j_ac_vlc[w->quant<13][mode>>1][table_index];//2 modes use same tables
    av_assert2(w->j_ac_vlc[mode]);
}

static inline int x8_get_orient_vlc(IntraX8Context * w){
    MpegEncContext * const s= w->s;
    int table_index;

    if(!w->j_orient_vlc ){
        table_index = get_bits(&s->gb, 1+(w->quant<13) );
        w->j_orient_vlc = &j_orient_vlc[w->quant<13][table_index];
    }

    return get_vlc2(&s->gb, w->j_orient_vlc->table, OR_VLC_BITS, OR_VLC_MTD);
}

#define extra_bits(eb) (eb)
#define extra_run   (0xFF<<8)
#define extra_level (0x00<<8)
#define   run_offset(r)    ((r)<<16)
#define level_offset(l)    ((l)<<24)
static const uint32_t ac_decode_table[]={
    /*46*/ extra_bits(3) |  extra_run  | run_offset(16) | level_offset( 0),
    /*47*/ extra_bits(3) |  extra_run  | run_offset(24) | level_offset( 0),
    /*48*/ extra_bits(2) |  extra_run  | run_offset( 4) | level_offset( 1),
    /*49*/ extra_bits(3) |  extra_run  | run_offset( 8) | level_offset( 1),

    /*50*/ extra_bits(5) |  extra_run  | run_offset(32) | level_offset( 0),
    /*51*/ extra_bits(4) |  extra_run  | run_offset(16) | level_offset( 1),

    /*52*/ extra_bits(2) | extra_level | run_offset( 0) | level_offset( 4),
    /*53*/ extra_bits(2) | extra_level | run_offset( 0) | level_offset( 8),
    /*54*/ extra_bits(2) | extra_level | run_offset( 0) | level_offset(12),
    /*55*/ extra_bits(3) | extra_level | run_offset( 0) | level_offset(16),
    /*56*/ extra_bits(3) | extra_level | run_offset( 0) | level_offset(24),

    /*57*/ extra_bits(2) | extra_level | run_offset( 1) | level_offset( 3),
    /*58*/ extra_bits(3) | extra_level | run_offset( 1) | level_offset( 7),

    /*59*/ extra_bits(2) |  extra_run  | run_offset(16) | level_offset( 0),
    /*60*/ extra_bits(2) |  extra_run  | run_offset(20) | level_offset( 0),
    /*61*/ extra_bits(2) |  extra_run  | run_offset(24) | level_offset( 0),
    /*62*/ extra_bits(2) |  extra_run  | run_offset(28) | level_offset( 0),
    /*63*/ extra_bits(4) |  extra_run  | run_offset(32) | level_offset( 0),
    /*64*/ extra_bits(4) |  extra_run  | run_offset(48) | level_offset( 0),

    /*65*/ extra_bits(2) |  extra_run  | run_offset( 4) | level_offset( 1),
    /*66*/ extra_bits(3) |  extra_run  | run_offset( 8) | level_offset( 1),
    /*67*/ extra_bits(4) |  extra_run  | run_offset(16) | level_offset( 1),

    /*68*/ extra_bits(2) | extra_level | run_offset( 0) | level_offset( 4),
    /*69*/ extra_bits(3) | extra_level | run_offset( 0) | level_offset( 8),
    /*70*/ extra_bits(4) | extra_level | run_offset( 0) | level_offset(16),

    /*71*/ extra_bits(2) | extra_level | run_offset( 1) | level_offset( 3),
    /*72*/ extra_bits(3) | extra_level | run_offset( 1) | level_offset( 7),
};
//extra_bits = 3bits; extra_run/level = 1 bit; run_offset = 6bits; level_offset = 5 bits;
#undef extra_bits
#undef extra_run
#undef extra_level
#undef run_offset
#undef level_offset

static void x8_get_ac_rlf(IntraX8Context * const w, const int mode,
                     int * const run, int * const level, int * const final){
    MpegEncContext *  const s= w->s;
    int i,e;

//    x8_select_ac_table(w,mode);
    i = get_vlc2(&s->gb, w->j_ac_vlc[mode]->table, AC_VLC_BITS, AC_VLC_MTD);

    if(i<46){ //[0-45]
        int t,l;
        if(i<0){
            (*level)=(*final)=//prevent 'may be used unilitialized'
            (*run)=64;//this would cause error exit in the ac loop
            return;
        }

        (*final) = t = (i>22);
        i-=23*t;
/*
  i== 0-15 r=0-15 l=0 ;r=i& %01111
  i==16-19 r=0-3  l=1 ;r=i& %00011
  i==20-21 r=0-1  l=2 ;r=i& %00001
  i==22    r=0    l=3 ;r=i& %00000
l=lut_l[i/2]={0,0,0,0,0,0,0,0,1,1,2,3}[i>>1];// 11 10'01 01'00 00'00 00'00 00'00 00 => 0xE50000
t=lut_mask[l]={0x0f,0x03,0x01,0x00}[l]; as i<256 the higher bits do not matter */
        l=(0xE50000>>(i&(0x1E)))&3;/*0x1E or (~1) or ((i>>1)<<1)*/
        t=(0x01030F>>(l<<3));

        (*run)   = i&t;
        (*level) = l;
    }else if(i<73){//[46-72]
        uint32_t sm;
        uint32_t mask;

        i-=46;
        sm=ac_decode_table[i];

        e=get_bits(&s->gb,sm&0xF);sm>>=8;//3bits
        mask=sm&0xff;sm>>=8;             //1bit

        (*run)  =(sm&0xff) + (e&( mask));//6bits
        (*level)=(sm>>8)   + (e&(~mask));//5bits
        (*final)=i>(58-46);
    }else if(i<75){//[73-74]
        static const uint8_t crazy_mix_runlevel[32]={
        0x22,0x32,0x33,0x53,0x23,0x42,0x43,0x63,
        0x24,0x52,0x34,0x73,0x25,0x62,0x44,0x83,
        0x26,0x72,0x35,0x54,0x27,0x82,0x45,0x64,
        0x28,0x92,0x36,0x74,0x29,0xa2,0x46,0x84};

        (*final)=!(i&1);
        e=get_bits(&s->gb,5);//get the extra bits
        (*run)  =crazy_mix_runlevel[e]>>4;
        (*level)=crazy_mix_runlevel[e]&0x0F;
    }else{
        (*level)=get_bits( &s->gb, 7-3*(i&1));
        (*run)  =get_bits( &s->gb, 6);
        (*final)=get_bits1(&s->gb);
    }
    return;
}

//static const uint8_t dc_extra_sbits[]   ={0, 1,1, 1,1, 2,2, 3,3,   4,4,   5,5,   6,6,    7,7    };
static const uint8_t dc_index_offset[]  ={ 0, 1,2, 3,4, 5,7, 9,13, 17,25, 33,49, 65,97, 129,193};

static int x8_get_dc_rlf(IntraX8Context * const w,int const mode, int * const level, int * const final){
    MpegEncContext * const s= w->s;
    int i,e,c;

    av_assert2(mode<3);
    if( !w->j_dc_vlc[mode] ) {
        int table_index;
        table_index = get_bits(&s->gb, 3);
        //4 modes, same table
        w->j_dc_vlc[mode]= &j_dc_vlc[w->quant<13][table_index];
    }

    i=get_vlc2(&s->gb, w->j_dc_vlc[mode]->table, DC_VLC_BITS, DC_VLC_MTD);

    /*(i>=17) {i-=17;final=1;}*/
    c= i>16;
    (*final)=c;
    i-=17*c;

    if(i<=0){
        (*level)=0;
        return -i;
    }
    c=(i+1)>>1;//hackish way to calculate dc_extra_sbits[]
    c-=c>1;

    e=get_bits(&s->gb,c);//get the extra bits
    i=dc_index_offset[i]+(e>>1);

    e= -(e & 1);//0,0xffffff
    (*level)= (i ^ e) - e;// (i^0)-0 , (i^0xff)-(-1)
    return 0;
}
//end of huffman

static int x8_setup_spatial_predictor(IntraX8Context * const w, const int chroma){
    MpegEncContext * const s= w->s;
    int range;
    int sum;
    int quant;

    w->dsp.setup_spatial_compensation(s->dest[chroma], s->sc.edge_emu_buffer,
                                      s->current_picture.f->linesize[chroma>0],
                                      &range, &sum, w->edges);
    if(chroma){
        w->orient=w->chroma_orient;
        quant=w->quant_dc_chroma;
    }else{
        quant=w->quant;
    }

    w->flat_dc=0;
    if(range < quant || range < 3){
        w->orient=0;
        if(range < 3){//yep you read right, a +-1 idct error may break decoding!
            w->flat_dc=1;
            sum+=9;
            w->predicted_dc = (sum*6899)>>17;//((1<<17)+9)/(8+8+1+2)=6899
        }
    }
    if(chroma)
        return 0;

    av_assert2(w->orient < 3);
    if(range < 2*w->quant){
        if( (w->edges&3) == 0){
            if(w->orient==1) w->orient=11;
            if(w->orient==2) w->orient=10;
        }else{
            w->orient=0;
        }
        w->raw_orient=0;
    }else{
        static const uint8_t prediction_table[3][12]={
            {0,8,4, 10,11, 2,6,9,1,3,5,7},
            {4,0,8, 11,10, 3,5,2,6,9,1,7},
            {8,0,4, 10,11, 1,7,2,6,9,3,5}
        };
        w->raw_orient=x8_get_orient_vlc(w);
        if(w->raw_orient<0) return -1;
        av_assert2(w->raw_orient < 12 );
        av_assert2(w->orient<3);
        w->orient=prediction_table[w->orient][w->raw_orient];
    }
    return 0;
}

static void x8_update_predictions(IntraX8Context * const w, const int orient, const int est_run ){
    MpegEncContext * const s= w->s;

    w->prediction_table[s->mb_x*2+(s->mb_y&1)] = (est_run<<2) + 1*(orient==4) + 2*(orient==8);
/*
  y=2n+0 ->//0 2 4
  y=2n+1 ->//1 3 5
*/
}
static void x8_get_prediction_chroma(IntraX8Context * const w){
    MpegEncContext * const s= w->s;

    w->edges = 1*( !(s->mb_x>>1) );
    w->edges|= 2*( !(s->mb_y>>1) );
    w->edges|= 4*( s->mb_x >= (2*s->mb_width-1) );//mb_x for chroma would always be odd

    w->raw_orient=0;
    if(w->edges&3){//lut_co[8]={inv,4,8,8, inv,4,8,8}<- =>{1,1,0,0;1,1,0,0} => 0xCC
        w->chroma_orient=4<<((0xCC>>w->edges)&1);
        return;
    }
    w->chroma_orient = (w->prediction_table[2*s->mb_x-2] & 0x03)<<2;//block[x-1][y|1-1)]
}

static void x8_get_prediction(IntraX8Context * const w){
    MpegEncContext * const s= w->s;
    int a,b,c,i;

    w->edges = 1*( !s->mb_x );
    w->edges|= 2*( !s->mb_y );
    w->edges|= 4*( s->mb_x >= (2*s->mb_width-1) );

    switch(w->edges&3){
        case 0:
            break;
        case 1:
            //take the one from the above block[0][y-1]
            w->est_run = w->prediction_table[!(s->mb_y&1)]>>2;
            w->orient  = 1;
            return;
        case 2:
            //take the one from the previous block[x-1][0]
            w->est_run = w->prediction_table[2*s->mb_x-2]>>2;
            w->orient  = 2;
            return;
        case 3:
            w->est_run = 16;
            w->orient  = 0;
            return;
    }
    //no edge cases
    b= w->prediction_table[2*s->mb_x   + !(s->mb_y&1) ];//block[x  ][y-1]
    a= w->prediction_table[2*s->mb_x-2 +  (s->mb_y&1) ];//block[x-1][y  ]
    c= w->prediction_table[2*s->mb_x-2 + !(s->mb_y&1) ];//block[x-1][y-1]

    w->est_run = FFMIN(b,a);
    /* This condition has nothing to do with w->edges, even if it looks
       similar it would trigger if e.g. x=3;y=2;
       I guess somebody wrote something wrong and it became standard. */
    if( (s->mb_x & s->mb_y) != 0 ) w->est_run=FFMIN(c,w->est_run);
    w->est_run>>=2;

    a&=3;
    b&=3;
    c&=3;

    i=( 0xFFEAF4C4>>(2*b+8*a) )&3;
    if(i!=3) w->orient=i;
    else     w->orient=( 0xFFEAD8>>(2*c+8*(w->quant>12)) )&3;
/*
lut1[b][a]={
->{0, 1, 0, pad},
  {0, 1, X, pad},
  {2, 2, 2, pad}}
   pad 2   2  2; pad X  1  0; pad 0  1  0 <-
-> 11 10 '10 10 '11 11'01 00 '11 00'01 00=>0xEAF4C4

lut2[q>12][c]={
  ->{0,2,1,pad},
    {2,2,2,pad}}
   pad 2  2  2; pad 1  2  0 <-
-> 11 10'10 10 '11 01'10 00=>0xEAD8
*/
}


static void x8_ac_compensation(IntraX8Context * const w, int const direction, int const dc_level){
    MpegEncContext * const s= w->s;
    int t;
#define B(x,y)  s->block[0][w->idct_permutation[(x)+(y)*8]]
#define T(x)  ((x) * dc_level + 0x8000) >> 16;
    switch(direction){
    case 0:
        t = T(3811);//h
        B(1,0) -= t;
        B(0,1) -= t;

        t = T(487);//e
        B(2,0) -= t;
        B(0,2) -= t;

        t = T(506);//f
        B(3,0) -= t;
        B(0,3) -= t;

        t = T(135);//c
        B(4,0) -= t;
        B(0,4) -= t;
        B(2,1) += t;
        B(1,2) += t;
        B(3,1) += t;
        B(1,3) += t;

        t = T(173);//d
        B(5,0) -= t;
        B(0,5) -= t;

        t = T(61);//b
        B(6,0) -= t;
        B(0,6) -= t;
        B(5,1) += t;
        B(1,5) += t;

        t = T(42); //a
        B(7,0) -= t;
        B(0,7) -= t;
        B(4,1) += t;
        B(1,4) += t;
        B(4,4) += t;

        t = T(1084);//g
        B(1,1) += t;

        s->block_last_index[0] = FFMAX(s->block_last_index[0], 7*8);
        break;
    case 1:
        B(0,1) -= T(6269);
        B(0,3) -= T( 708);
        B(0,5) -= T( 172);
        B(0,7) -= T(  73);

        s->block_last_index[0] = FFMAX(s->block_last_index[0], 7*8);
        break;
    case 2:
        B(1,0) -= T(6269);
        B(3,0) -= T( 708);
        B(5,0) -= T( 172);
        B(7,0) -= T(  73);

        s->block_last_index[0] = FFMAX(s->block_last_index[0], 7);
        break;
    }
#undef B
#undef T
}

static void dsp_x8_put_solidcolor(uint8_t const pix, uint8_t * dst, int const linesize){
    int k;
    for(k=0;k<8;k++){
        memset(dst,pix,8);
        dst+=linesize;
    }
}

static const int16_t quant_table[64] = {
    256, 256, 256, 256,  256, 256, 259, 262,
    265, 269, 272, 275,  278, 282, 285, 288,
    292, 295, 299, 303,  306, 310, 314, 317,
    321, 325, 329, 333,  337, 341, 345, 349,
    353, 358, 362, 366,  371, 375, 379, 384,
    389, 393, 398, 403,  408, 413, 417, 422,
    428, 433, 438, 443,  448, 454, 459, 465,
    470, 476, 482, 488,  493, 499, 505, 511
};

static int x8_decode_intra_mb(IntraX8Context* const w, const int chroma){
    MpegEncContext * const s= w->s;

    uint8_t * scantable;
    int final,run,level;
    int ac_mode,dc_mode,est_run,dc_level;
    int pos,n;
    int zeros_only;
    int use_quant_matrix;
    int sign;

    av_assert2(w->orient<12);
    s->bdsp.clear_block(s->block[0]);

    if(chroma){
        dc_mode=2;
    }else{
        dc_mode=!!w->est_run;//0,1
    }

    if(x8_get_dc_rlf(w, dc_mode, &dc_level, &final)) return -1;
    n=0;
    zeros_only=0;
    if(!final){//decode ac
        use_quant_matrix=w->use_quant_matrix;
        if(chroma){
            ac_mode = 1;
            est_run = 64;//not used
        }else{
            if (w->raw_orient < 3){
                use_quant_matrix = 0;
            }
            if(w->raw_orient > 4){
                ac_mode = 0;
                est_run = 64;
            }else{
                if(w->est_run > 1){
                    ac_mode = 2;
                    est_run=w->est_run;
                }else{
                    ac_mode = 3;
                    est_run = 64;
                }
            }
        }
        x8_select_ac_table(w,ac_mode);
        /*scantable_selector[12]={0,2,0,1,1,1,0,2,2,0,1,2};<-
        -> 10'01' 00'10' 10'00' 01'01' 01'00' 10'00 =>0x928548 */
        scantable = w->scantable[ (0x928548>>(2*w->orient))&3 ].permutated;
        pos=0;
        do {
            n++;
            if( n >= est_run ){
                ac_mode=3;
                x8_select_ac_table(w,3);
            }

            x8_get_ac_rlf(w,ac_mode,&run,&level,&final);

            pos+=run+1;
            if(pos>63){
                //this also handles vlc error in x8_get_ac_rlf
                return -1;
            }
            level= (level+1) * w->dquant;
            level+= w->qsum;

            sign = - get_bits1(&s->gb);
            level = (level ^ sign) - sign;

            if(use_quant_matrix){
                level = (level*quant_table[pos])>>8;
            }
            s->block[0][ scantable[pos] ]=level;
        }while(!final);

        s->block_last_index[0]=pos;
    }else{//DC only
        s->block_last_index[0]=0;
        if(w->flat_dc && ((unsigned)(dc_level+1)) < 3){//[-1;1]
            int32_t divide_quant= !chroma ? w->divide_quant_dc_luma:
                                            w->divide_quant_dc_chroma;
            int32_t dc_quant    = !chroma ? w->quant:
                                            w->quant_dc_chroma;

            //original intent dc_level+=predicted_dc/quant; but it got lost somewhere in the rounding
            dc_level+= (w->predicted_dc*divide_quant + (1<<12) )>>13;

            dsp_x8_put_solidcolor( av_clip_uint8((dc_level*dc_quant+4)>>3),
                                   s->dest[chroma], s->current_picture.f->linesize[!!chroma]);

            goto block_placed;
        }
        zeros_only = (dc_level == 0);
    }
    if(!chroma){
        s->block[0][0] = dc_level*w->quant;
    }else{
        s->block[0][0] = dc_level*w->quant_dc_chroma;
    }

    //there is !zero_only check in the original, but dc_level check is enough
    if( (unsigned int)(dc_level+1) >= 3 && (w->edges&3) != 3 ){
        int direction;
        /*ac_comp_direction[orient] = { 0, 3, 3, 1, 1, 0, 0, 0, 2, 2, 2, 1 };<-
        -> 01'10' 10'10' 00'00' 00'01' 01'11' 11'00 =>0x6A017C */
        direction= (0x6A017C>>(w->orient*2))&3;
        if (direction != 3){
            x8_ac_compensation(w, direction, s->block[0][0]);//modify block_last[]
        }
    }

    if(w->flat_dc){
        dsp_x8_put_solidcolor(w->predicted_dc, s->dest[chroma], s->current_picture.f->linesize[!!chroma]);
    }else{
        w->dsp.spatial_compensation[w->orient]( s->sc.edge_emu_buffer,
                                            s->dest[chroma],
                                            s->current_picture.f->linesize[!!chroma] );
    }
    if(!zeros_only)
        w->wdsp.idct_add(s->dest[chroma],
                         s->current_picture.f->linesize[!!chroma],
                         s->block[0]);

block_placed:

    if(!chroma){
        x8_update_predictions(w,w->orient,n);
    }

    if(s->loop_filter){
        uint8_t* ptr = s->dest[chroma];
        int linesize = s->current_picture.f->linesize[!!chroma];

        if(!( (w->edges&2) || ( zeros_only && (w->orient|4)==4 ) )){
            w->dsp.h_loop_filter(ptr, linesize, w->quant);
        }
        if(!( (w->edges&1) || ( zeros_only && (w->orient|8)==8 ) )){
            w->dsp.v_loop_filter(ptr, linesize, w->quant);
        }
    }
    return 0;
}

static void x8_init_block_index(MpegEncContext *s){ //FIXME maybe merge with ff_*
//not s->linesize as this would be wrong for field pics
//not that IntraX8 has interlacing support ;)
    const int linesize   = s->current_picture.f->linesize[0];
    const int uvlinesize = s->current_picture.f->linesize[1];

    s->dest[0] = s->current_picture.f->data[0];
    s->dest[1] = s->current_picture.f->data[1];
    s->dest[2] = s->current_picture.f->data[2];

    s->dest[0] +=   s->mb_y        *   linesize << 3;
    s->dest[1] += ( s->mb_y&(~1) ) * uvlinesize << 2;//chroma blocks are on add rows
    s->dest[2] += ( s->mb_y&(~1) ) * uvlinesize << 2;
}

/**
 * Initialize IntraX8 frame decoder.
 * Requires valid MpegEncContext with valid s->mb_width before calling.
 * @param w pointer to IntraX8Context
 * @param s pointer to MpegEncContext of the parent codec
 */
av_cold void ff_intrax8_common_init(IntraX8Context * w, MpegEncContext * const s){

    w->s=s;
    x8_vlc_init();
    av_assert0(s->mb_width>0);
    w->prediction_table=av_mallocz(s->mb_width*2*2);//two rows, 2 blocks per cannon mb

    ff_wmv2dsp_init(&w->wdsp);
    ff_init_scantable_permutation(w->idct_permutation,
                                  w->wdsp.idct_perm);

    ff_init_scantable(w->idct_permutation, &w->scantable[0], ff_wmv1_scantable[0]);
    ff_init_scantable(w->idct_permutation, &w->scantable[1], ff_wmv1_scantable[2]);
    ff_init_scantable(w->idct_permutation, &w->scantable[2], ff_wmv1_scantable[3]);

    ff_intrax8dsp_init(&w->dsp);
}

/**
 * Destroy IntraX8 frame structure.
 * @param w pointer to IntraX8Context
 */
av_cold void ff_intrax8_common_end(IntraX8Context * w)
{
    av_freep(&w->prediction_table);
}

/**
 * Decode single IntraX8 frame.
 * The parent codec must fill s->loopfilter and s->gb (bitstream).
 * The parent codec must call ff_mpv_frame_start(), ff_er_frame_start() before calling this function.
 * The parent codec must call ff_er_frame_end(), ff_mpv_frame_end() after calling this function.
 * This function does not use ff_mpv_decode_mb().
 * lowres decoding is theoretically impossible.
 * @param w pointer to IntraX8Context
 * @param dquant doubled quantizer, it would be odd in case of VC-1 halfpq==1.
 * @param quant_offset offset away from zero
 */
int ff_intrax8_decode_picture(IntraX8Context * const w, int dquant, int quant_offset){
    MpegEncContext * const s= w->s;
    int mb_xy;
    w->use_quant_matrix = get_bits1(&s->gb);

    w->dquant = dquant;
    w->quant  = dquant >> 1;
    w->qsum   = quant_offset;

    w->divide_quant_dc_luma = ((1<<16) + (w->quant>>1)) / w->quant;
    if(w->quant < 5){
        w->quant_dc_chroma =  w->quant;
        w->divide_quant_dc_chroma = w->divide_quant_dc_luma;
    }else{
        w->quant_dc_chroma =  w->quant+((w->quant+3)>>3);
        w->divide_quant_dc_chroma = ((1<<16) + (w->quant_dc_chroma>>1)) / w->quant_dc_chroma;
    }
    x8_reset_vlc_tables(w);

    s->resync_mb_x=0;
    s->resync_mb_y=0;

    for(s->mb_y=0; s->mb_y < s->mb_height*2; s->mb_y++){
        x8_init_block_index(s);
        mb_xy=(s->mb_y>>1)*s->mb_stride;

        for(s->mb_x=0; s->mb_x < s->mb_width*2; s->mb_x++){
            x8_get_prediction(w);
            if(x8_setup_spatial_predictor(w,0)) goto error;
            if(x8_decode_intra_mb(w,0)) goto error;

            if( s->mb_x & s->mb_y & 1 ){
                x8_get_prediction_chroma(w);

                /*when setting up chroma, no vlc is read,
                so no error condition can be reached*/
                x8_setup_spatial_predictor(w,1);
                if(x8_decode_intra_mb(w,1)) goto error;

                x8_setup_spatial_predictor(w,2);
                if(x8_decode_intra_mb(w,2)) goto error;

                s->dest[1]+= 8;
                s->dest[2]+= 8;

                /*emulate MB info in the relevant tables*/
                s->mbskip_table [mb_xy]=0;
                s->mbintra_table[mb_xy]=1;
                s->current_picture.qscale_table[mb_xy] = w->quant;
                mb_xy++;
            }
            s->dest[0]+= 8;
        }
        if(s->mb_y&1){
            ff_mpeg_draw_horiz_band(s, (s->mb_y-1)*8, 16);
        }
    }

error:
    ff_er_add_slice(&s->er, s->resync_mb_x, s->resync_mb_y,
                        (s->mb_x>>1)-1, (s->mb_y>>1)-1,
                        ER_MB_END );
    return 0;
}
