/*******************************************************************
                      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;

int read_intra_block(VIDEO_STREAM *in, short *out, int block_number, READ_BLOCK_OPTION *opt);
int read_non_intra_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 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_intra_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;
	
	rdc read_dct_coefficient;

	/* read first coefficient */

	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;
		
	/* select read_dct_coefficient function */
	if(opt->intra_vlc_format){
		read_dct_coefficient = read_dct_coefficient_b15;
	}else{
		read_dct_coefficient = read_dct_coefficient_b14;
	}

	/* read rest coefficients */
	while(read_dct_coefficient(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;
	}

	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;
	}

#if 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;
		}
	}
#endif
	
	return 1;
}

int read_non_intra_block(VIDEO_STREAM *in, short *out, int block_number, READ_BLOCK_OPTION *opt)
{
	int i,n,sum;

	int q_dct[64];

	int run;
	int level;

	unsigned char *quantizer_weight; 

	if(color_component[block_number]){
		quantizer_weight = opt->quantizer_weight[3];
	}else{
		quantizer_weight = opt->quantizer_weight[1];
	}

	/* read first coefficient */
	
	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;

	/* read rest coefficients */
	while(read_dct_coefficient_b14(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 */
	n += 1;
	for(i=0;i<64;i++){
		if(q_dct[i]){
			out[i] = (((q_dct[i] * 2) + (q_dct[i] < 0 ? -1 : 1)) * quantizer_weight[i] * quantizer_scale[opt->q_scale_type][opt->quantizer_scale_code]) / 32;
		}else{
			out[i] = 0;
		}
	}

#if 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;
		}
	}
#endif
	
	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;
}



