/*******************************************************************
                      block layer interface
 *******************************************************************/

#include "scan.h"

#define BLOCK_C
#include "block.h"

typedef struct {
	int value;
	int length;
} BASIC_VLC_ELEMENT;

typedef struct {
	int run;
	int level;
	int length;
} DCT_COEFFICIENT_VLC_ELEMENT;

int read_block(VIDEO_STREAM *in, short *out, int block_number, READ_BLOCK_OPTION *opt);
int reset_dc_dct_predictor(READ_BLOCK_OPTION *p);

static int get_dct_dc_size_luminance(VIDEO_STREAM *in);
static int get_dct_dc_size_chrominance(VIDEO_STREAM *in);
static int read_dct_coefficient_b14(VIDEO_STREAM *in, int *run, int *level);
static int read_dct_coefficient_b15(VIDEO_STREAM *in, int *run, int *level);
static void read_fixed_length_dct_coefficient(VIDEO_STREAM *in, int *run, int *level);

typedef int (* read_dct_coefficient)(VIDEO_STREAM *, int *, int *);

static const int quantizer_scale[2][32] = {
	{
		 0,  2,  4,  6,  8, 10, 12, 14,
		16, 18, 20, 22, 24, 26, 28, 30,
		32, 34, 36, 38, 40, 42, 44, 46,
		48, 50, 52, 54, 56, 58, 60, 62,
	}, {
		 0,  1,  2,  3,  4,  5,  6,  7,
		 8, 10, 12, 14, 16, 18, 20, 22,
		24, 28, 32, 36, 40, 44, 48, 52,
		56, 64, 72, 80, 88, 96,104,112,
	},
};
	
static const int color_component[12] = {
	0, 0, 0, 0, 1, 2, 1, 2, 1, 2, 1, 2,
};

int read_block(VIDEO_STREAM *in, short *out, int block_number, READ_BLOCK_OPTION *opt)
{
	int i,n,sum;
	int dct_dc_size;
	int dct_dc_differential;

	int q_dct[64];

	int run;
	int level;
	read_dct_coefficient rdc;

	/* read first coefficient */
	if(opt->macroblock_intra){
		
		if(color_component[block_number]){
			dct_dc_size = get_dct_dc_size_chrominance(in);
		}else{
			dct_dc_size = get_dct_dc_size_luminance(in);
		}
		
		if(dct_dc_size){
			dct_dc_differential = get_bits(in, dct_dc_size);
			if(dct_dc_differential < (1 << (dct_dc_size - 1))){
				dct_dc_differential = dct_dc_differential + 1 - (1 << dct_dc_size);
			}
		}else{
			dct_dc_differential = 0;
		}
		
		q_dct[0] = opt->dc_dct_predictor[color_component[block_number]] + dct_dc_differential;
		opt->dc_dct_predictor[color_component[block_number]] = q_dct[0];

		if(q_dct[0] < 0){
			q_dct[0] = 0;
		}else if( q_dct[0] >= (1 << (8 + opt->intra_dc_precision)) ){
			q_dct[0] = (1 << (8 + opt->intra_dc_precision)) - 1;
		}

		n = 1;
		
	}else{
		
		n = 0;

		if(read_bits(in, 1)){
            erase_bits(in, 1);
            run = 0;
            if(get_bits(in, 1)){
                level = -1;
            }else{
                level = 1;
            }
        }else{
            read_dct_coefficient_b14(in, &run, &level);
		}
        
		for(i=0;i<run;i++){
			q_dct[scan_table[opt->alternate_scan][n]] = 0;
			n += 1;
		}
		q_dct[scan_table[opt->alternate_scan][n]] = level;
		n += 1;
		
	}

	/* select read_dct_coefficient function */
	if(opt->macroblock_intra && opt->intra_vlc_format){
		rdc = read_dct_coefficient_b15;
	}else{
		rdc = read_dct_coefficient_b14;
	}

	/* read rest coefficients */
	while(rdc(in, &run, &level)){
		if(run < 0){
			return 0;
		}

        if(run + n >= 64){
            return 0;
        }

		for(i=0;i<run;i++){
			q_dct[scan_table[opt->alternate_scan][n]] = 0;
			n += 1;
		}
		q_dct[scan_table[opt->alternate_scan][n]] = level;
		n += 1;
	}

	for(;n<64;n++){
		q_dct[scan_table[opt->alternate_scan][n]] = 0;
	}

	/* invers quantisation */
	if(color_component[block_number]){
		n = 2;
	}else{
		n = 0;
	}

	if(opt->macroblock_intra){
		out[0] = q_dct[0*8+0] * (1 << (3 - opt->intra_dc_precision));
		for(i=1;i<64;i++){
			out[i] = (q_dct[i] * opt->quantizer_weight[n][i] * quantizer_scale[opt->q_scale_type][opt->quantizer_scale_code]) / 16;
		}
	}else{
		n += 1;
		for(i=0;i<64;i++){
            if(q_dct[i]){
			    out[i] = (((q_dct[i] * 2) + (q_dct[i] < 0 ? -1 : 1)) * opt->quantizer_weight[n][i] * quantizer_scale[opt->q_scale_type][opt->quantizer_scale_code]) / 32;
            }else{
                out[i] = 0;
            }
		}
	}

	/* clip */
	sum = 0;
	for(i=0;i<64;i++){
		if(out[i] < 2047){
			if(out[i] > -2048){
				/* nothing to do */
			}else{
				out[i] = -2048;
			}
		}else{
			out[i] = 2047;
		}
		sum += out[i];
	}

	if((sum & 1) == 0){
		if(out[63] & 1){
			out[63] -= 1;
		}else{
			out[63] += 1;
		}
	}

	return 1;
}

int reset_dc_dct_predictor(READ_BLOCK_OPTION *p)
{
	int i;

	for(i=0;i<3;i++){
		p->dc_dct_predictor[i] = 1 << (7 + p->intra_dc_precision);
	}

	return 1;
}

static int get_dct_dc_size_luminance(VIDEO_STREAM *in)
{
	int code;

	static const BASIC_VLC_ELEMENT table[] = {
		{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},{1,2}, 
		{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},{1,2}, 
		{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},{1,2}, 
		{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},{1,2}, 

		{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},{1,2}, 
		{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},{1,2}, 
		{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},{1,2}, 
		{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},{1,2}, 

		{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},{1,2}, 
		{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},{1,2}, 
		{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},{1,2}, 
		{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},{1,2}, 

		{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},{1,2}, 
		{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},{1,2}, 
		{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},{1,2}, 
		{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},{1,2}, 

		{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},
		{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},
		{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},
		{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},

		{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},
		{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},
		{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},
		{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},

		{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},
		{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},
		{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},
		{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},

		{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},
		{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},
		{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},
		{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},

		{0,3},{0,3},{0,3},{0,3},{0,3},{0,3},{0,3},{0,3},
		{0,3},{0,3},{0,3},{0,3},{0,3},{0,3},{0,3},{0,3},
		{0,3},{0,3},{0,3},{0,3},{0,3},{0,3},{0,3},{0,3},
		{0,3},{0,3},{0,3},{0,3},{0,3},{0,3},{0,3},{0,3},

		{0,3},{0,3},{0,3},{0,3},{0,3},{0,3},{0,3},{0,3},
		{0,3},{0,3},{0,3},{0,3},{0,3},{0,3},{0,3},{0,3},
		{0,3},{0,3},{0,3},{0,3},{0,3},{0,3},{0,3},{0,3},
		{0,3},{0,3},{0,3},{0,3},{0,3},{0,3},{0,3},{0,3},

		{3,3},{3,3},{3,3},{3,3},{3,3},{3,3},{3,3},{3,3},
		{3,3},{3,3},{3,3},{3,3},{3,3},{3,3},{3,3},{3,3},
		{3,3},{3,3},{3,3},{3,3},{3,3},{3,3},{3,3},{3,3},
		{3,3},{3,3},{3,3},{3,3},{3,3},{3,3},{3,3},{3,3},

		{3,3},{3,3},{3,3},{3,3},{3,3},{3,3},{3,3},{3,3},
		{3,3},{3,3},{3,3},{3,3},{3,3},{3,3},{3,3},{3,3},
		{3,3},{3,3},{3,3},{3,3},{3,3},{3,3},{3,3},{3,3},
		{3,3},{3,3},{3,3},{3,3},{3,3},{3,3},{3,3},{3,3},

		{4,3},{4,3},{4,3},{4,3},{4,3},{4,3},{4,3},{4,3},
		{4,3},{4,3},{4,3},{4,3},{4,3},{4,3},{4,3},{4,3},
		{4,3},{4,3},{4,3},{4,3},{4,3},{4,3},{4,3},{4,3},
		{4,3},{4,3},{4,3},{4,3},{4,3},{4,3},{4,3},{4,3},

		{4,3},{4,3},{4,3},{4,3},{4,3},{4,3},{4,3},{4,3},
		{4,3},{4,3},{4,3},{4,3},{4,3},{4,3},{4,3},{4,3},
		{4,3},{4,3},{4,3},{4,3},{4,3},{4,3},{4,3},{4,3},
		{4,3},{4,3},{4,3},{4,3},{4,3},{4,3},{4,3},{4,3},

		{5,4},{5,4},{5,4},{5,4},{5,4},{5,4},{5,4},{5,4},
		{5,4},{5,4},{5,4},{5,4},{5,4},{5,4},{5,4},{5,4},
		{5,4},{5,4},{5,4},{5,4},{5,4},{5,4},{5,4},{5,4},
		{5,4},{5,4},{5,4},{5,4},{5,4},{5,4},{5,4},{5,4},

		{6,5},{6,5},{6,5},{6,5},{6,5},{6,5},{6,5},{6,5},
		{6,5},{6,5},{6,5},{6,5},{6,5},{6,5},{6,5},{6,5},
		{7,6},{7,6},{7,6},{7,6},{7,6},{7,6},{7,6},{7,6},
		{8,7},{8,7},{8,7},{8,7},{9,8},{9,8},{10,9},{11,9},
	};

	code = read_bits(in, 9);

	erase_bits(in, table[code].length);
	
	return table[code].value;
}

static int get_dct_dc_size_chrominance(VIDEO_STREAM *in)
{
	int code;

	static const BASIC_VLC_ELEMENT table[] = {
		{0,2},{0,2},{0,2},{0,2},{0,2},{0,2},{0,2},{0,2},
		{0,2},{0,2},{0,2},{0,2},{0,2},{0,2},{0,2},{0,2},
		{0,2},{0,2},{0,2},{0,2},{0,2},{0,2},{0,2},{0,2},
		{0,2},{0,2},{0,2},{0,2},{0,2},{0,2},{0,2},{0,2},

		{0,2},{0,2},{0,2},{0,2},{0,2},{0,2},{0,2},{0,2},
		{0,2},{0,2},{0,2},{0,2},{0,2},{0,2},{0,2},{0,2},
		{0,2},{0,2},{0,2},{0,2},{0,2},{0,2},{0,2},{0,2},
		{0,2},{0,2},{0,2},{0,2},{0,2},{0,2},{0,2},{0,2},

		{0,2},{0,2},{0,2},{0,2},{0,2},{0,2},{0,2},{0,2},
		{0,2},{0,2},{0,2},{0,2},{0,2},{0,2},{0,2},{0,2},
		{0,2},{0,2},{0,2},{0,2},{0,2},{0,2},{0,2},{0,2},
		{0,2},{0,2},{0,2},{0,2},{0,2},{0,2},{0,2},{0,2},

		{0,2},{0,2},{0,2},{0,2},{0,2},{0,2},{0,2},{0,2},
		{0,2},{0,2},{0,2},{0,2},{0,2},{0,2},{0,2},{0,2},
		{0,2},{0,2},{0,2},{0,2},{0,2},{0,2},{0,2},{0,2},
		{0,2},{0,2},{0,2},{0,2},{0,2},{0,2},{0,2},{0,2},

		{0,2},{0,2},{0,2},{0,2},{0,2},{0,2},{0,2},{0,2},
		{0,2},{0,2},{0,2},{0,2},{0,2},{0,2},{0,2},{0,2},
		{0,2},{0,2},{0,2},{0,2},{0,2},{0,2},{0,2},{0,2},
		{0,2},{0,2},{0,2},{0,2},{0,2},{0,2},{0,2},{0,2},

		{0,2},{0,2},{0,2},{0,2},{0,2},{0,2},{0,2},{0,2},
		{0,2},{0,2},{0,2},{0,2},{0,2},{0,2},{0,2},{0,2},
		{0,2},{0,2},{0,2},{0,2},{0,2},{0,2},{0,2},{0,2},
		{0,2},{0,2},{0,2},{0,2},{0,2},{0,2},{0,2},{0,2},

		{0,2},{0,2},{0,2},{0,2},{0,2},{0,2},{0,2},{0,2},
		{0,2},{0,2},{0,2},{0,2},{0,2},{0,2},{0,2},{0,2},
		{0,2},{0,2},{0,2},{0,2},{0,2},{0,2},{0,2},{0,2},
		{0,2},{0,2},{0,2},{0,2},{0,2},{0,2},{0,2},{0,2},

		{0,2},{0,2},{0,2},{0,2},{0,2},{0,2},{0,2},{0,2},
		{0,2},{0,2},{0,2},{0,2},{0,2},{0,2},{0,2},{0,2},
		{0,2},{0,2},{0,2},{0,2},{0,2},{0,2},{0,2},{0,2},
		{0,2},{0,2},{0,2},{0,2},{0,2},{0,2},{0,2},{0,2},

		{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},
		{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},
		{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},
		{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},
		
		{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},
		{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},
		{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},
		{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},
		
		{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},
		{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},
		{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},
		{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},
		
		{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},
		{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},
		{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},
		{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},
		
		{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},
		{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},
		{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},
		{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},
		
		{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},
		{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},
		{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},
		{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},
		
		{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},
		{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},
		{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},
		{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},
		
		{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},
		{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},
		{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},
		{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},
		
		{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},
		{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},
		{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},
		{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},

		{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},
		{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},
		{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},
		{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},

		{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},
		{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},
		{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},
		{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},

		{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},
		{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},
		{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},
		{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},

		{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},
		{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},
		{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},
		{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},

		{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},
		{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},
		{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},
		{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},

		{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},
		{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},
		{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},
		{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},

		{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},
		{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},
		{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},
		{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},

		{3,3},{3,3},{3,3},{3,3},{3,3},{3,3},{3,3},{3,3},
		{3,3},{3,3},{3,3},{3,3},{3,3},{3,3},{3,3},{3,3},
		{3,3},{3,3},{3,3},{3,3},{3,3},{3,3},{3,3},{3,3},
		{3,3},{3,3},{3,3},{3,3},{3,3},{3,3},{3,3},{3,3},

		{3,3},{3,3},{3,3},{3,3},{3,3},{3,3},{3,3},{3,3},
		{3,3},{3,3},{3,3},{3,3},{3,3},{3,3},{3,3},{3,3},
		{3,3},{3,3},{3,3},{3,3},{3,3},{3,3},{3,3},{3,3},
		{3,3},{3,3},{3,3},{3,3},{3,3},{3,3},{3,3},{3,3},

		{3,3},{3,3},{3,3},{3,3},{3,3},{3,3},{3,3},{3,3},
		{3,3},{3,3},{3,3},{3,3},{3,3},{3,3},{3,3},{3,3},
		{3,3},{3,3},{3,3},{3,3},{3,3},{3,3},{3,3},{3,3},
		{3,3},{3,3},{3,3},{3,3},{3,3},{3,3},{3,3},{3,3},

		{3,3},{3,3},{3,3},{3,3},{3,3},{3,3},{3,3},{3,3},
		{3,3},{3,3},{3,3},{3,3},{3,3},{3,3},{3,3},{3,3},
		{3,3},{3,3},{3,3},{3,3},{3,3},{3,3},{3,3},{3,3},
		{3,3},{3,3},{3,3},{3,3},{3,3},{3,3},{3,3},{3,3},

		{4,4},{4,4},{4,4},{4,4},{4,4},{4,4},{4,4},{4,4},
		{4,4},{4,4},{4,4},{4,4},{4,4},{4,4},{4,4},{4,4},
		{4,4},{4,4},{4,4},{4,4},{4,4},{4,4},{4,4},{4,4},
		{4,4},{4,4},{4,4},{4,4},{4,4},{4,4},{4,4},{4,4},

		{4,4},{4,4},{4,4},{4,4},{4,4},{4,4},{4,4},{4,4},
		{4,4},{4,4},{4,4},{4,4},{4,4},{4,4},{4,4},{4,4},
		{4,4},{4,4},{4,4},{4,4},{4,4},{4,4},{4,4},{4,4},
		{4,4},{4,4},{4,4},{4,4},{4,4},{4,4},{4,4},{4,4},

		{5,5},{5,5},{5,5},{5,5},{5,5},{5,5},{5,5},{5,5},
		{5,5},{5,5},{5,5},{5,5},{5,5},{5,5},{5,5},{5,5},
		{5,5},{5,5},{5,5},{5,5},{5,5},{5,5},{5,5},{5,5},
		{5,5},{5,5},{5,5},{5,5},{5,5},{5,5},{5,5},{5,5},

		{6,6},{6,6},{6,6},{6,6},{6,6},{6,6},{6,6},{6,6},
		{6,6},{6,6},{6,6},{6,6},{6,6},{6,6},{6,6},{6,6},
		{7,7},{7,7},{7,7},{7,7},{7,7},{7,7},{7,7},{7,7},
		{8,8},{8,8},{8,8},{8,8},{9,9},{9,9},{10,10},{11,10},
	};

	code = read_bits(in, 10);

	erase_bits(in, table[code].length);

	return table[code].value;
}

static int read_dct_coefficient_b14(VIDEO_STREAM *in, int *run, int *level)
{
	int code;

	static const DCT_COEFFICIENT_VLC_ELEMENT table_a[] = {
    	{2,2,7},{2,2,7},{9,1,7},{9,1,7},{0,4,7},{0,4,7},{8,1,7},{8,1,7},
	    {7,1,6},{7,1,6},{7,1,6},{7,1,6},{6,1,6},{6,1,6},{6,1,6},{6,1,6},
    	{1,2,6},{1,2,6},{1,2,6},{1,2,6},{5,1,6},{5,1,6},{5,1,6},{5,1,6},
	    {13,1,8},{0,6,8},{12,1,8},{11,1,8},{3,2,8},{1,3,8},{0,5,8},{10,1,8},
       	{0,3,5},{0,3,5},{0,3,5},{0,3,5},{0,3,5},{0,3,5},{0,3,5},{0,3,5},
    	{4,1,5},{4,1,5},{4,1,5},{4,1,5},{4,1,5},{4,1,5},{4,1,5},{4,1,5},
	    {3,1,5},{3,1,5},{3,1,5},{3,1,5},{3,1,5},{3,1,5},{3,1,5},{3,1,5},
    	{0,2,4},{0,2,4},{0,2,4},{0,2,4},{0,2,4},{0,2,4},{0,2,4},{0,2,4},
	    {0,2,4},{0,2,4},{0,2,4},{0,2,4},{0,2,4},{0,2,4},{0,2,4},{0,2,4},
    	{2,1,4},{2,1,4},{2,1,4},{2,1,4},{2,1,4},{2,1,4},{2,1,4},{2,1,4},
	    {2,1,4},{2,1,4},{2,1,4},{2,1,4},{2,1,4},{2,1,4},{2,1,4},{2,1,4},
    	{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},
	    {1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},
    	{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},
	    {1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},
	};

	static const DCT_COEFFICIENT_VLC_ELEMENT table_b[] = {
    	{10,2,13},{9,2,13},{5,3,13},{3,4,13},{2,5,13},{1,7,13},{1,6,13},{0,15,13},
	    {0,14,13},{0,13,13},{0,12,13},{26,1,13},{25,1,13},{24,1,13},{23,1,13},{22,1,13},
    	{0,11,12},{0,11,12},{8,2,12},{8,2,12},{4,3,12},{4,3,12},{0,10,12},{0,10,12},
	    {2,4,12},{2,4,12},{7,2,12},{7,2,12},{21,1,12},{21,1,12},{20,1,12},{20,1,12},
    	{0,9,12},{0,9,12},{19,1,12},{19,1,12},{18,1,12},{18,1,12},{1,5,12},{1,5,12},
	    {3,3,12},{3,3,12},{0,8,12},{0,8,12},{6,2,12},{6,2,12},{17,1,12},{17,1,12},
    	{16,1,10},{16,1,10},{16,1,10},{16,1,10},{16,1,10},{16,1,10},{16,1,10},{16,1,10},
	    {5,2,10},{5,2,10},{5,2,10},{5,2,10},{5,2,10},{5,2,10},{5,2,10},{5,2,10},
    	{0,7,10},{0,7,10},{0,7,10},{0,7,10},{0,7,10},{0,7,10},{0,7,10},{0,7,10},
	    {2,3,10},{2,3,10},{2,3,10},{2,3,10},{2,3,10},{2,3,10},{2,3,10},{2,3,10},
       	{1,4,10},{1,4,10},{1,4,10},{1,4,10},{1,4,10},{1,4,10},{1,4,10},{1,4,10},
	    {15,1,10},{15,1,10},{15,1,10},{15,1,10},{15,1,10},{15,1,10},{15,1,10},{15,1,10},
    	{14,1,10},{14,1,10},{14,1,10},{14,1,10},{14,1,10},{14,1,10},{14,1,10},{14,1,10},
	    {4,2,10},{4,2,10},{4,2,10},{4,2,10},{4,2,10},{4,2,10},{4,2,10},{4,2,10},
	};

	static const DCT_COEFFICIENT_VLC_ELEMENT table_c[] = {
		{1,18,16},{1,17,16},{1,16,16},{1,15,16},{6,3,16},{16,2,16},{15,2,16},{14,2,16},
		{13,2,16},{12,2,16},{11,2,16},{31,1,16},{30,1,16},{29,1,16},{28,1,16},{27,1,16},
		{0,40,15},{0,40,15},{0,39,15},{0,39,15},{0,38,15},{0,38,15},{0,37,15},{0,37,15},
		{0,36,15},{0,36,15},{0,35,15},{0,35,15},{0,34,15},{0,34,15},{0,33,15},{0,33,15},
		{0,32,15},{0,32,15},{1,14,15},{1,14,15},{1,13,15},{1,13,15},{1,12,15},{1,12,15},
		{1,11,15},{1,11,15},{1,10,15},{1,10,15},{1,9,15},{1,9,15},{1,8,15},{1,8,15},
		{0,31,14},{0,31,14},{0,31,14},{0,31,14},{0,30,14},{0,30,14},{0,30,14},{0,30,14},
		{0,29,14},{0,29,14},{0,29,14},{0,29,14},{0,28,14},{0,28,14},{0,28,14},{0,28,14},
		{0,27,14},{0,27,14},{0,27,14},{0,27,14},{0,26,14},{0,26,14},{0,26,14},{0,26,14},
		{0,25,14},{0,25,14},{0,25,14},{0,25,14},{0,24,14},{0,24,14},{0,24,14},{0,24,14},
		{0,23,14},{0,23,14},{0,23,14},{0,23,14},{0,22,14},{0,22,14},{0,22,14},{0,22,14},
		{0,21,14},{0,21,14},{0,21,14},{0,21,14},{0,20,14},{0,20,14},{0,20,14},{0,20,14},
		{0,19,14},{0,19,14},{0,19,14},{0,19,14},{0,18,14},{0,18,14},{0,18,14},{0,18,14},
		{0,17,14},{0,17,14},{0,17,14},{0,17,14},{0,16,14},{0,16,14},{0,16,14},{0,16,14},
	};

	code = read_bits(in, 2);
	if(code == 2){ /* EOB */
		erase_bits(in, 2);
		*run = -1;
		*level = 0;
		return 0;
	}else if(code == 3){
		erase_bits(in, 2);
		*run = 0;
        if(get_bits(in, 1)){
            *level = -1;
        }else{
            *level = 1;
        }
		return 1;
	}

	code = read_bits(in, 6);
	if(code == 1){
		erase_bits(in, 6);
		read_fixed_length_dct_coefficient(in, run, level);
		return 1;
	}

	code = read_bits(in, 16);

	if(code > 0x7ff){
		code = (code >> 8) - 8;
		*run = table_a[code].run;
		*level = table_a[code].level;
		erase_bits(in, table_a[code].length);
	}else if(code > 0x7f){
		code = (code >> 3) - 16;
		*run = table_b[code].run;
		*level = table_b[code].level;
		erase_bits(in, table_b[code].length);
	}else{
		code = code - 16;
		*run = table_c[code].run;
		*level = table_c[code].level;
		erase_bits(in, table_c[code].length);
	}

	if(get_bits(in, 1)){
		*level *= -1;
	}

	return 1;
}
static int read_dct_coefficient_b15(VIDEO_STREAM *in, int *run, int *level)
{
	int code;

	static const DCT_COEFFICIENT_VLC_ELEMENT table_a[] = {
		{7,1,7},{7,1,7},{8,1,7},{8,1,7},{6,1,7},{6,1,7},{2,2,7},{2,2,7},
		{0,7,6},{0,7,6},{0,7,6},{0,7,6},{0,6,6},{0,6,6},{0,6,6},{0,6,6},
		{4,1,6},{4,1,6},{4,1,6},{4,1,6},{5,1,6},{5,1,6},{5,1,6},{5,1,6},
		{1,5,8},{11,1,8},{0,11,8},{0,10,8},{13,1,8},{12,1,8},{3,2,8},{1,4,8},
		{2,1,5},{2,1,5},{2,1,5},{2,1,5},{2,1,5},{2,1,5},{2,1,5},{2,1,5},
		{1,2,5},{1,2,5},{1,2,5},{1,2,5},{1,2,5},{1,2,5},{1,2,5},{1,2,5},
		{3,1,5},{3,1,5},{3,1,5},{3,1,5},{3,1,5},{3,1,5},{3,1,5},{3,1,5},
		{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},
		{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},
		{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},
		{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},{1,1,3},
		{-1,0,4},{-1,0,4},{-1,0,4},{-1,0,4},{-1,0,4},{-1,0,4},{-1,0,4},{-1,0,4},
		{-1,0,4},{-1,0,4},{-1,0,4},{-1,0,4},{-1,0,4},{-1,0,4},{-1,0,4},{-1,0,4},
		{0,3,4},{0,3,4},{0,3,4},{0,3,4},{0,3,4},{0,3,4},{0,3,4},{0,3,4},
		{0,3,4},{0,3,4},{0,3,4},{0,3,4},{0,3,4},{0,3,4},{0,3,4},{0,3,4},
		{0,1,2},{0,1,2},{0,1,2},{0,1,2},{0,1,2},{0,1,2},{0,1,2},{0,1,2},
		{0,1,2},{0,1,2},{0,1,2},{0,1,2},{0,1,2},{0,1,2},{0,1,2},{0,1,2},
		{0,1,2},{0,1,2},{0,1,2},{0,1,2},{0,1,2},{0,1,2},{0,1,2},{0,1,2},
		{0,1,2},{0,1,2},{0,1,2},{0,1,2},{0,1,2},{0,1,2},{0,1,2},{0,1,2},
		{0,1,2},{0,1,2},{0,1,2},{0,1,2},{0,1,2},{0,1,2},{0,1,2},{0,1,2},
		{0,1,2},{0,1,2},{0,1,2},{0,1,2},{0,1,2},{0,1,2},{0,1,2},{0,1,2},
		{0,1,2},{0,1,2},{0,1,2},{0,1,2},{0,1,2},{0,1,2},{0,1,2},{0,1,2},
		{0,1,2},{0,1,2},{0,1,2},{0,1,2},{0,1,2},{0,1,2},{0,1,2},{0,1,2},
		{0,2,3},{0,2,3},{0,2,3},{0,2,3},{0,2,3},{0,2,3},{0,2,3},{0,2,3},
		{0,2,3},{0,2,3},{0,2,3},{0,2,3},{0,2,3},{0,2,3},{0,2,3},{0,2,3},
		{0,2,3},{0,2,3},{0,2,3},{0,2,3},{0,2,3},{0,2,3},{0,2,3},{0,2,3},
		{0,2,3},{0,2,3},{0,2,3},{0,2,3},{0,2,3},{0,2,3},{0,2,3},{0,2,3},
		{0,4,5},{0,4,5},{0,4,5},{0,4,5},{0,4,5},{0,4,5},{0,4,5},{0,4,5},
		{0,5,5},{0,5,5},{0,5,5},{0,5,5},{0,5,5},{0,5,5},{0,5,5},{0,5,5},
		{9,1,7},{9,1,7},{1,3,7},{1,3,7},{10,1,7},{10,1,7},{0,8,7},{0,8,7},
		{0,9,7},{0,9,7},{0,12,8},{0,13,8},{2,3,8},{4,2,8},{0,14,8},{0,15,8},
	};

	static const DCT_COEFFICIENT_VLC_ELEMENT table_b[] = {
		{10,2,13},{9,2,13},{5,3,13},{3,4,13},{2,5,13},{1,7,13},{1,6,13},{0,15,13},
		{0,14,13},{0,13,13},{0,12,13},{26,1,13},{25,1,13},{24,1,13},{23,1,13},{22,1,13},
		{0,11,12},{0,11,12},{8,2,12},{8,2,12},{4,3,12},{4,3,12},{0,10,12},{0,10,12},
		{2,4,12},{2,4,12},{7,2,12},{7,2,12},{21,1,12},{21,1,12},{20,1,12},{20,1,12},
		{0,9,12},{0,9,12},{19,1,12},{19,1,12},{18,1,12},{18,1,12},{1,5,12},{1,5,12},
		{3,3,12},{3,3,12},{0,8,12},{0,8,12},{6,2,12},{6,2,12},{17,1,12},{17,1,12},
		{5,2,9},{5,2,9},{5,2,9},{5,2,9},{5,2,9},{5,2,9},{5,2,9},{5,2,9},
		{5,2,9},{5,2,9},{5,2,9},{5,2,9},{5,2,9},{5,2,9},{5,2,9},{5,2,9},
		{14,1,9},{14,1,9},{14,1,9},{14,1,9},{14,1,9},{14,1,9},{14,1,9},{14,1,9},
		{14,1,9},{14,1,9},{14,1,9},{14,1,9},{14,1,9},{14,1,9},{14,1,9},{14,1,9},
		{2,4,10},{2,4,10},{2,4,10},{2,4,10},{2,4,10},{2,4,10},{2,4,10},{2,4,10},
		{16,1,10},{16,1,10},{16,1,10},{16,1,10},{16,1,10},{16,1,10},{16,1,10},{16,1,10},
		{15,1,9},{15,1,9},{15,1,9},{15,1,9},{15,1,9},{15,1,9},{15,1,9},{15,1,9},
		{15,1,9},{15,1,9},{15,1,9},{15,1,9},{15,1,9},{15,1,9},{15,1,9},{15,1,9},
	};

	static const DCT_COEFFICIENT_VLC_ELEMENT table_c[] = {
		{1,18,16},{1,17,16},{1,16,16},{1,15,16},{6,3,16},{16,2,16},{15,2,16},{14,2,16},
		{13,2,16},{12,2,16},{11,2,16},{31,1,16},{30,1,16},{29,1,16},{28,1,16},{27,1,16},
		{0,40,15},{0,40,15},{0,39,15},{0,39,15},{0,38,15},{0,38,15},{0,37,15},{0,37,15},
		{0,36,15},{0,36,15},{0,35,15},{0,35,15},{0,34,15},{0,34,15},{0,33,15},{0,33,15},
		{0,32,15},{0,32,15},{1,14,15},{1,14,15},{1,13,15},{1,13,15},{1,12,15},{1,12,15},
		{1,11,15},{1,11,15},{1,10,15},{1,10,15},{1,9,15},{1,9,15},{1,8,15},{1,8,15},
		{0,31,14},{0,31,14},{0,31,14},{0,31,14},{0,30,14},{0,30,14},{0,30,14},{0,30,14},
		{0,29,14},{0,29,14},{0,29,14},{0,29,14},{0,28,14},{0,28,14},{0,28,14},{0,28,14},
		{0,27,14},{0,27,14},{0,27,14},{0,27,14},{0,26,14},{0,26,14},{0,26,14},{0,26,14},
		{0,25,14},{0,25,14},{0,25,14},{0,25,14},{0,24,14},{0,24,14},{0,24,14},{0,24,14},
		{0,23,14},{0,23,14},{0,23,14},{0,23,14},{0,22,14},{0,22,14},{0,22,14},{0,22,14},
		{0,21,14},{0,21,14},{0,21,14},{0,21,14},{0,20,14},{0,20,14},{0,20,14},{0,20,14},
		{0,19,14},{0,19,14},{0,19,14},{0,19,14},{0,18,14},{0,18,14},{0,18,14},{0,18,14},
		{0,17,14},{0,17,14},{0,17,14},{0,17,14},{0,16,14},{0,16,14},{0,16,14},{0,16,14},
	};

	code = read_bits(in, 4);
	if(code == 6){ /* EOB */
		*run = -1;
		*level = 0;
		erase_bits(in, 4);
		return 0;
	}

	code = read_bits(in, 6);
	if(code == 1){ /* Escape */
		erase_bits(in, 6);
		read_fixed_length_dct_coefficient(in, run, level);
		return 1;
	}

	code = read_bits(in, 16);
	if(code > 0x7FF){
		code = (code >> 8) - 8;
		*run = table_a[code].run;
		*level = table_a[code].level;
		erase_bits(in, table_a[code].length);
	}else if(code > 0x7F){
		code = (code >> 3) - 16;
		*run = table_b[code].run;
		*level = table_b[code].level;
		erase_bits(in, table_b[code].length);
	}else{
		code = code - 16;
		*run = table_c[code].run;
		*level = table_c[code].level;
		erase_bits(in, table_c[code].length);
	}

	if(get_bits(in, 1)){
		*level *= -1;
	}

	return 1;
}

static void read_fixed_length_dct_coefficient(VIDEO_STREAM *in, int *run, int *level)
{
	int code;

	code = get_bits(in, 6);

	*run = code;

	code = get_bits(in, 12);
	if(code & 0x800){
		code |= 0xFFFFF000;
	}
	
	*level = code;
}







