#ifndef __layer3_h
#define __layer3_h

#include "buffer.h"

/***********************************************************************
*
*  Global Type Definitions
*
***********************************************************************/

// Layer III side information.
typedef struct gr_info_s
{
	unsigned part2_3_length;
	unsigned big_values;
	unsigned global_gain;
	unsigned scalefac_compress;
	unsigned window_switching_flag;
	unsigned block_type;
	unsigned mixed_block_flag;
	unsigned table_select[3];
	unsigned subblock_gain[3];
	unsigned region0_count;
	unsigned region1_count;
	unsigned huffman_count;
	unsigned preflag;
	unsigned scalefac_scale;
	unsigned count1table_select;
	unsigned scfsi;
} gr_info_s ;

typedef struct
{
	unsigned main_data_begin;
	unsigned private_bits;
	struct
	{
		gr_info_s gr[2];
	} ch[2];
} III_side_info_t;

#define SFBSMAX 39
#define SFBLMAX 22
#define SFBSMIX 9
#define SFBLMIX 8

typedef struct
{
	int l[SFBLMAX+1];
	int s[SFBSMAX+1];
} sfBandIndex;

// Layer III scale factors.

typedef struct
{
	int l[SFBLMAX];            // [cb]
	int s[SFBSMAX];            // [window=3][cb=13]
} III_scalefac_t;


#define         HBUFSIZE        4096

typedef struct
{
	// hbuff
	bytebuf			hbuf;
	char			buf_data[HBUFSIZE];
	// III_hybrid
	int 			block[2][SBSLIMIT];
	// layer III
	III_scalefac_t		III_scalefac[2];
	III_side_info_t		III_side_info;
	const sfBandIndex*	sfBand;
	int			lr[2][SBSLIMIT];
	int			hybridIn[SBSLIMIT];
	int			hybridOut[SSLIMIT][SBLIMIT]; // Inverted dims
} layer3;

void init_layer3(layer3*);

#endif
