inflate.h 2.14 KB
#include <stdbool.h> 

#ifndef _INFLATE_H_
#define _INFLATE_H_

/* Maximum length for any Huffman code */ 
#define MAX_LENGTH 15

typedef struct huffman {
    /* bl_counts[i] = number of codes of length i */
    int bl_counts[MAX_LENGTH + 1]; 

    /* This stores the alphabet.
     * alphabet[i] returns an array of alphabet symbols of length bl_counts[i]. 
     */
    int *alphabet[MAX_LENGTH + 1]; 

    /* Suppose we are reading a code and we want an index into the alphabet array. 
     * These are basically the numerical offsets for such an index. 
     * So if the code we are reading has value c and is of length i, 
     * its alphabet character is indexed by (c - min_codes[i]). 
     */
    int min_codes[MAX_LENGTH + 1]; 

} huffman_t;

extern huffman_t HUFFMAN_FIXED_DISTS;
extern huffman_t HUFFMAN_FIXED; 

/* Reset the position state variable */
void reset_pos();

/*
 * Create a Huffman mapping from a sequence of lengths. 
 * The alphabet used is (0, 1, ..., n_symbols - 1) 
 */
huffman_t *make_huffman(int *lens, int n_symbols);

/* Clean up a heap allocated Huffman map */
void destroy_huffman(huffman_t *hf);

/* Get the next bit from a buffer of bytes read from memory */ 
int get_next_bit(char *buf);

/* 
 * Get the numerical value of n bits read from a buffer. 
 * If reverse is set true, interpret the bytes in 
 * reverse stream order. 
 */
int get_n_bits(char *buf, int n, bool reverse); 

/* 
 * Given a Huffman map, read ONE code from the buffer and 
 * return its numerical value in stream order.
 */
int read_chunk(char *buf, huffman_t hf);

/*
 * For the DYNAMIC Huffman type. 
 * Read a sequence of code lengths (between 0 and 18) from the buffer.
 * The number of codes read is specified by "num_codes", however, 
 * the returned sequence of lengths is 0-padded to the length 
 * of the whole alphabet given by "num_symbols". 
 */  
int *read_lens(char *buf, huffman_t *hf_codes, 
               int num_symbols, int num_codes);

/*
 * Read a single block from the buffer, and write the deflated 
 * results to "out". 
 */
bool read_block(char *buf, FILE *out);

/*
 * Inflate the file fp. 
 */
void inflate(FILE *fp, long size, char *fname); 

#endif