// 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