// Maximum size of dynamic tree.  The maximum found in a long but non-
// exhaustive search was 1004 huft structures (850 for length/literals
// and 154 for distances, the latter actually the result of an
// exhaustive search).  The actual maximum is not known, but the
// value below is more than safe.

#define MANY					1440

// maximum bit length of any code (if BMAX needs to be larger than 16, then h and x[] should be uint32_t.)
#define BMAX					15

typedef uint32_t (*check_func) (uint32_t check, const byte *buf, uint32_t len);

typedef enum 
{
	TYPE,		// get type bits (3, including end bit)
	LENS,		// get lengths for stored
	STORED,		// processing stored block
	TABLE,		// get table lengths
	BTREE,		// get bit lengths tree for a dynamic block
	DTREE,		// get length, distance trees for a dynamic block
	CODES,		// processing fixed or dynamic block
	DRY,		// output remaining window bytes
	DONE,		// finished last block, done
	BAD			// got a data error--stuck here
} inflate_block_mode;

// waiting for "i:"=input, "o:"=output, "x:"=nothing
typedef enum 
{        
	START,		// x: set up for LEN
	LEN,		// i: get length/literal/eob next
	LENEXT,		// i: getting length extra (have base)
	DIST,		// i: get distance next
	DISTEXT,	// i: getting distance extra
	COPY,		// o: copying bytes in window, waiting for space
	LIT,		// o: got literal, waiting for output space
	WASH,		// o: got eob, possibly still output waiting
	END,		// x: got eob and all data flushed
	BADCODE		// x: got error
} inflate_codes_mode;

typedef enum 
{
	imMETHOD,	// waiting for method byte
	imFLAG,		// waiting for flag byte
	imBLOCKS,	// decompressing blocks
	imCHECK4,	// four check bytes to go
	imCHECK3,	// three check bytes to go
	imCHECK2,	// two check bytes to go
	imCHECK1,	// one check byte to go
	imDONE,		// finished check, done
	imBAD		// got an error--stay here
} inflate_mode;

typedef struct inflate_huft_s 
{
	byte	Exop;							// number of extra bits or operation
	byte	Bits;							// number of bits in this code or subcode
	uint32_t	base;							// literal, length base, distance base, or table offset
} inflate_huft_t;

// inflate codes private state
typedef struct inflate_codes_state_s 
{
	inflate_codes_mode	mode;				// current inflate_codes mode
											
	// mode dependent information			
	uint32_t len;								
	union									
	{										
		struct								
		{									
			inflate_huft_t	*tree;			// pointer into tree
			uint32_t			need;			// bits needed
		} code;								// if LEN or DIST, where in tree
		uint32_t			lit;				// if LIT, literal
		struct								
		{									
			uint32_t			get;			// bits to get for extra
			uint32_t			dist;			// distance back to copy from
		} copy;								// if EXT or COPY, where and how much
	};										// submode
											
	// mode independent information			
	byte			lbits;					// ltree bits decoded per branch
	byte			dbits;					// dtree bits decoder per branch
	inflate_huft_t	*ltree;					// literal/length/eob tree
	inflate_huft_t	*dtree;					// distance tree
} inflate_codes_state_t;

// inflate blocks semi-private state
typedef struct inflate_blocks_state_s 
{
	// mode
	inflate_block_mode		mode;			// current inflate_block mode

	// mode dependent information
	union
	{
		uint32_t		left;					// if STORED, bytes left to copy
		struct								
		{									
			uint32_t			table;			// table lengths (14 bits)
			uint32_t			index;			// index into blens (or border)
			uint32_t			*blens;			// bit lengths of codes
			uint32_t			bb;				// bit length tree depth
			inflate_huft_t	*tb;			// bit length decoding tree
		} trees;							// if DTREE, decoding info for trees
		struct 
		{
			inflate_codes_state_t *codes;
		} decode;							// if CODES, current state
	};										// submode
	bool			last;					// true if this block is the last block
											
	// mode independent information			
	uint32_t			bitk;					// bits in bit buffer
	uint32_t			bitb;					// bit buffer
	inflate_huft_t	*hufts;					// single malloc for tree space
	byte			window[WINDOW_SIZE];	// sliding window
	byte			*end;					// one byte after sliding window
	byte			*read;					// window read pointer
	byte			*write;					// window write pointer
	uint32_t			check;					// check on output
} inflate_blocks_state_t;

// inflate private state
typedef struct inflate_state_s 
{
	inflate_mode			mode;	  		// current inflate mode
											
	uint32_t					method;			// if FLAGS, method byte
											
	// mode independent information			
	int						nowrap;			// flag for no wrapper
	uint32_t					wbits;			// log2(window size)  (8..15, defaults to 15)
	inflate_blocks_state_t	*blocks;		// current inflate_blocks state

	uint32_t					adler;
	uint32_t					calcadler;
} inflate_state;


// end
