/*******************************************************************
                      block layer interface
 *******************************************************************/

#include "scan.h"
#include "b14.h"
#include "b15.h"

#define BLOCK_C
#include "block.h"

typedef struct {
	int value;
	int length;
} BASIC_VLC_ELEMENT;

typedef struct {
	int alternate_scan;
	int quantizer_scale;
	unsigned char *quantizer_weight;
} INVERS_QUANTIZATION_PARAMETER;

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 short invers_quantization_non_intra_block(int level, int n, INVERS_QUANTIZATION_PARAMETER *prm);
static short invers_quantization_intra_block(int level, int n, INVERS_QUANTIZATION_PARAMETER *prm);

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 n,sum;
	int dct_dc_size;
	int dct_dc_differential;

	int run;
	int level;

	static const short missmatch_control[2][2] = {
		{1, -1}, {0, 0},
	};

	INVERS_QUANTIZATION_PARAMETER iq_prm;

	rdc read_dct_coefficient;
	short (* invers_quantization)(int, int, INVERS_QUANTIZATION_PARAMETER *);

	iq_prm.alternate_scan = opt->alternate_scan;
	iq_prm.quantizer_scale = quantizer_scale[opt->q_scale_type][opt->quantizer_scale_code];

	sum = 0;

	/* initialize output block */
	memset(out, 0, sizeof(short)*64);

	/* read first coefficient & select functions */
	if(opt->macroblock_intra){
		
		if(color_component[block_number]){
			dct_dc_size = get_dct_dc_size_chrominance(in);
			iq_prm.quantizer_weight = opt->quantizer_weight[2];
		}else{
			dct_dc_size = get_dct_dc_size_luminance(in);
			iq_prm.quantizer_weight = opt->quantizer_weight[0];
		}
		
		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;
		}
		
		opt->dc_dct_predictor[color_component[block_number]] += dct_dc_differential;

		out[0] = opt->dc_dct_predictor[color_component[block_number]] * (1 << (3 - opt->intra_dc_precision));
		
		if(out[0] >= 0){
			if(out[0] < 2048){
				/* nothing to do */
			}else{
				out[0] = 2047;
			}
		}else{
			out[0] = 0;
		}
		sum = out[0];

		n = 1;
		
		if(opt->intra_vlc_format){
			read_dct_coefficient = read_dct_coefficient_b15;
		}else{
			read_dct_coefficient = read_dct_coefficient_b14;
		}
		invers_quantization = invers_quantization_intra_block;

	}else{
		
		read_dct_coefficient = read_dct_coefficient_b14;
		invers_quantization = invers_quantization_non_intra_block;

		if(color_component[block_number]){
			iq_prm.quantizer_weight = opt->quantizer_weight[3];
		}else{	
			iq_prm.quantizer_weight = opt->quantizer_weight[1];
		}

		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(in, &run, &level);
		}
        
		n = run;
		out[scan_table[opt->alternate_scan][n]] = invers_quantization(level, n, &iq_prm);
		sum = out[scan_table[opt->alternate_scan][n]];
		n += 1;
		
	}

	/* read rest coefficients */
	while(read_dct_coefficient(in, &run, &level)){

		n += run;
		
        if(n >= 64){
            return 0;
        }

		out[scan_table[opt->alternate_scan][n]] = invers_quantization(level, n,  &iq_prm);
		sum += out[scan_table[opt->alternate_scan][n]];
		n += 1;
	}

	out[63] += missmatch_control[sum&1][out[63]&1];
	
	return 1;
}

int reset_dc_dct_predictor(READ_BLOCK_OPTION *p)
{
	int w;

	w = 1 << (7 + p->intra_dc_precision);
	p->dc_dct_predictor[0] = w;
	p->dc_dct_predictor[1] = w;
	p->dc_dct_predictor[2] = w;

	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 short invers_quantization_non_intra_block(int level, int n, INVERS_QUANTIZATION_PARAMETER *prm)
{
	int w;

	w = ( ((level * 2) + ( (level > 0) ? 1 : -1)) * prm->quantizer_weight[scan_table[prm->alternate_scan][n]] * prm->quantizer_scale ) / 32;

	if(w >= -2048){
		if(w < 2048){
			return w;
		}else{
			return 2047;
		}
	}else{
		return -2048;
	}
}

static short invers_quantization_intra_block(int level, int n, INVERS_QUANTIZATION_PARAMETER *prm)
{
	int w;

	w = (level * prm->quantizer_weight[scan_table[prm->alternate_scan][n]] * prm->quantizer_scale) / 16;

	if(w >= -2048){
		if(w < 2048){
			return w;
		}else{
			return 2047;
		}
	}else{
		return -2048;
	}
}
