/*******************************************************************
            MPEG Video picture header reading routine
 *******************************************************************/

#define PICTURE_HEADER_C
#include "picture_header.h"

int read_picture_header(MPEG_IO *in, PICTURE_HEADER *out);
static int read_picture_coding_extension(MPEG_IO *in, PICTURE_CODING_EXTENSION *out);
static int read_quant_matrix_extension(MPEG_IO *in, QUANT_MATRIX_EXTENSION *out);
static int read_picture_display_extension(MPEG_IO *in, PICTURE_DISPLAY_EXTENSION *out);
static int read_picture_spatial_scalable_extension(MPEG_IO *in, PICTURE_SPATIAL_SCALABLE_EXTENSION *out);
static int read_temporal_scalable_extension(MPEG_IO *in, PICTURE_TEMPORAL_SCALABLE_EXTENSION *out);

/*******************************************************************/
int read_picture_header(MPEG_IO *in, PICTURE_HEADER *out)
{
	int code;
	
	out->temporal_reference = get_bits(in, 10);
	out->picture_coding_type = get_bits(in, 3);
	out->vbv_delay = get_bits(in, 16);
	out->full_pel_forward_vector = get_bits(in, 1);
	out->forward_f_code = get_bits(in, 3);
	out->full_pel_backward_vector = get_bits(in, 1);
	out->backward_f_code = get_bits(in, 3);

	while((code = get_bits(in, 1)) == 1){
		get_bits(in, 8);  /* read skip EBP & EIP */
	}

	while(next_marker(in)){
		code = read_bits(in, 32);
		if(code != 0x1B5){
			break;
		}
		erase_bits(in, 32);
		
		code = get_bits(in, 4);
		switch(code){
		case 8:
			out->has_picture_coding_extension = 1;
			read_picture_coding_extension(in, &(out->pc));
			break;
		case 3:
			out->has_quant_matrix_extension = 1;
			read_quant_matrix_extension(in, &(out->qm));
			break;
		case 7:
			out->has_picture_display_extension = 1;
			read_picture_display_extension(in, &(out->pd));
			break;
		case 9:
			out->has_picture_spatial_scalable_extension = 1;
			read_picture_spatial_scalable_extension(in, &(out->pss));
			break;
		case 10:
			out->has_temporal_scalable_extension = 1;
			read_temporal_scalable_extension(in, &(out->pts));
			break;
		default:
			break;
		}
	}

	return 1;
}
/*-----------------------------------------------------------------*/
static read_picture_coding_extension(MPEG_IO *in, PICTURE_CODING_EXTENSION *out)
{
	out->forward_hrizontal_f_code = get_bits(in, 4);
	out->forward_vertical_f_code = get_bits(in, 4); 
	out->backward_hrizontal_f_code = get_bits(in, 4);
	out->backward_vertical_f_code = get_bits(in, 4);
	out->intra_dc_precision = get_bits(in, 2);
	out->picture_structure = get_bits(in, 2);
	out->top_field_first = get_bits(in, 1);
	out->frame_predictive_frame_dct = get_bits(in, 1);
	out->concealment_motion_vectors = get_bits(in, 1);
	out->q_scale_type = get_bits(in, 1);
	out->intra_vlc_format = get_bits(in, 1);
	out->alternate_scan = get_bits(in, 1);
	out->repeat_first_field = get_bits(in, 1);
	out->chroma_420_type = get_bits(in, 1);
	out->progressive_frame = get_bits(in, 1);
	out->composit_display_flag = get_bits(in, 1);
	out->v_axis = get_bits(in, 1);
	out->field_sequence = get_bits(in, 3);
	out->sub_carrier = get_bits(in, 1);
	out->burst_amplitude = get_bits(in, 7);
	out->sub_carrier_phase = get_bits(in, 8);

	return 1;
}
/*-----------------------------------------------------------------*/
static read_quant_matrix_extension(MPEG_IO *in, QUANT_MATRIX_EXTENSION *out)
{
	int i;

	out->load_intra_quantizer_matrix = get_bits(in, 1);
	if(out->load_intra_quantizer_matrix){
		for(i=0;i<64;i++){
			out->iqm[i] = get_bits(in,8);
		}
	}

	out->load_nonintra_quantizer_matrix = get_bits(in, 1);
	if(out->load_nonintra_quantizer_matrix){
		for(i=0;i<64;i++){
			out->nqm[i] = get_bits(in,8);
		}
	}
	
	out->load_chroma_intra_quantizer_matrix = get_bits(in, 1);
	if(out->load_chroma_intra_quantizer_matrix){
		for(i=0;i<64;i++){
			out->ciqm[i] = get_bits(in,8);
		}
	}

	out->load_chroma_nonintra_quantizer_matrix = get_bits(in, 1);
	if(out->load_chroma_nonintra_quantizer_matrix){
		for(i=0;i<64;i++){
			out->cnqm[i] = get_bits(in,8);
		}
	}

	return 1;
}
/*-----------------------------------------------------------------*/
static read_picture_display_extension(MPEG_IO *in, PICTURE_DISPLAY_EXTENSION *out)
{
	out->frame_center_horizontal_offset = get_bits(in, 16);
	out->frame_center_vertical_offset = get_bits(in, 16);

	return 1;
}
/*-----------------------------------------------------------------*/
static read_picture_spatial_scalable_extension(MPEG_IO *in, PICTURE_SPATIAL_SCALABLE_EXTENSION *out)
{
	out->low_layer_temporal_reference = get_bits(in, 10);
	out->lower_layer_horizontal_offset = get_bits(in, 15);
	out->lower_layer_vertical_offset = get_bits(in, 15);
	out->spatial_temporal_weight_code_table_index = get_bits(in, 2);
	out->lower_layer_progressive_frame = get_bits(in, 1);
	out->lower_layer_deinterlaced_field_select = get_bits(in, 1);

	return 1;
}
/*-----------------------------------------------------------------*/
static read_temporal_scalable_extension(MPEG_IO *in, PICTURE_TEMPORAL_SCALABLE_EXTENSION *out)
{
	out->reference_select_code = get_bits(in, 2);
	out->forward_temporal_reference = get_bits(in, 10);
	out->backward_temporal_reference = get_bits(in, 10);

	return 1;
}

