]> git.proxmox.com Git - ceph.git/blobdiff - ceph/src/isa-l/include/igzip_lib.h
Import ceph 15.2.8
[ceph.git] / ceph / src / isa-l / include / igzip_lib.h
index 3cba3fafacf479d56be7467beca149f27891027f..a8b87791874568c3c855028aff10cba18791c4e2 100644 (file)
@@ -2,7 +2,7 @@
   Copyright(c) 2011-2016 Intel Corporation All rights reserved.
 
   Redistribution and use in source and binary forms, with or without
-  modification, are permitted provided that the following conditions 
+  modification, are permitted provided that the following conditions
   are met:
     * Redistributions of source code must retain the above copyright
       notice, this list of conditions and the following disclaimer.
@@ -53,8 +53,8 @@
  * Igzip also supports compression levels from ISAL_DEF_MIN_LEVEL to
  * ISAL_DEF_MAX_LEVEL.
  *
- * Igzip contains some behaviour configurable at compile time. These
- * configureable options are:
+ * Igzip contains some behavior configurable at compile time. These
+ * configurable options are:
  *
  * - IGZIP_HIST_SIZE - Defines the window size. The default value is 32K (note K
  *   represents 1024), but 8K is also supported. Powers of 2 which are at most
@@ -62,7 +62,7 @@
  *
  * - LONGER_HUFFTABLES - Defines whether to use a larger hufftables structure
  *   which may increase performance with smaller IGZIP_HIST_SIZE values. By
- *   default this optoin is not defined. This define sets IGZIP_HIST_SIZE to be
+ *   default this option is not defined. This define sets IGZIP_HIST_SIZE to be
  *   8 if IGZIP_HIST_SIZE > 8K.
  *
  *   As an example, to compile gzip with an 8K window size, in a terminal run
@@ -72,7 +72,6 @@
  *
  */
 #include <stdint.h>
-#include "types.h"
 
 #ifdef __cplusplus
 extern "C" {
@@ -85,16 +84,20 @@ extern "C" {
 #define ISAL_DEF_MAX_HDR_SIZE 328
 #define ISAL_DEF_MAX_CODE_LEN 15
 #define ISAL_DEF_HIST_SIZE (32*IGZIP_K)
+#define ISAL_DEF_MAX_HIST_BITS 15
+#define ISAL_DEF_MAX_MATCH 258
+#define ISAL_DEF_MIN_MATCH 3
 
 #define ISAL_DEF_LIT_SYMBOLS 257
 #define ISAL_DEF_LEN_SYMBOLS 29
 #define ISAL_DEF_DIST_SYMBOLS 30
 #define ISAL_DEF_LIT_LEN_SYMBOLS (ISAL_DEF_LIT_SYMBOLS + ISAL_DEF_LEN_SYMBOLS)
 
-#define ISAL_LOOK_AHEAD (18 * 16)      /* Max repeat length, rounded up to 32 byte boundary */
+/* Max repeat length, rounded up to 32 byte boundary */
+#define ISAL_LOOK_AHEAD ((ISAL_DEF_MAX_MATCH + 31) & ~31)
 
 /******************************************************************************/
-/* Deflate Implemenation Specific Defines */
+/* Deflate Implementation Specific Defines */
 /******************************************************************************/
 /* Note IGZIP_HIST_SIZE must be a power of two */
 #ifndef IGZIP_HIST_SIZE
@@ -115,9 +118,14 @@ extern "C" {
 
 #define ISAL_LIMIT_HASH_UPDATE
 
-#ifndef IGZIP_HASH_SIZE
-#define IGZIP_HASH_SIZE  (8 * IGZIP_K)
-#endif
+#define IGZIP_HASH8K_HASH_SIZE (8 * IGZIP_K)
+#define IGZIP_HASH_HIST_SIZE IGZIP_HIST_SIZE
+#define IGZIP_HASH_MAP_HASH_SIZE IGZIP_HIST_SIZE
+
+#define IGZIP_LVL0_HASH_SIZE  (8 * IGZIP_K)
+#define IGZIP_LVL1_HASH_SIZE  IGZIP_HASH8K_HASH_SIZE
+#define IGZIP_LVL2_HASH_SIZE  IGZIP_HASH_HIST_SIZE
+#define IGZIP_LVL3_HASH_SIZE  IGZIP_HASH_MAP_HASH_SIZE
 
 #ifdef LONGER_HUFFTABLE
 enum {IGZIP_DIST_TABLE_SIZE = 8*1024};
@@ -146,6 +154,8 @@ enum {IGZIP_LIT_TABLE_SIZE = ISAL_DEF_LIT_SYMBOLS};
 #define IGZIP_DEFLATE  0       /* Default */
 #define IGZIP_GZIP     1
 #define IGZIP_GZIP_NO_HDR      2
+#define IGZIP_ZLIB     3
+#define IGZIP_ZLIB_NO_HDR      4
 
 /* Compression Return values */
 #define COMP_OK 0
@@ -153,7 +163,9 @@ enum {IGZIP_LIT_TABLE_SIZE = ISAL_DEF_LIT_SYMBOLS};
 #define INVALID_PARAM -8
 #define STATELESS_OVERFLOW -1
 #define ISAL_INVALID_OPERATION -9
+#define ISAL_INVALID_STATE -3
 #define ISAL_INVALID_LEVEL -4  /* Invalid Compression level set */
+#define ISAL_INVALID_LEVEL_BUF -5 /* Invalid buffer specified for the compression level */
 
 /**
  *  @enum isal_zstate_state
@@ -171,6 +183,8 @@ enum isal_zstate_state {
        ZSTATE_BODY,    //!< Body state
        ZSTATE_FLUSH_READ_BUFFER, //!< Flush buffer
        ZSTATE_FLUSH_ICF_BUFFER,
+       ZSTATE_TYPE0_HDR, //! Type0 block header to be written
+       ZSTATE_TYPE0_BODY, //!< Type0 block body to be written
        ZSTATE_SYNC_FLUSH, //!< Write sync flush block
        ZSTATE_FLUSH_WRITE_BUFFER, //!< Flush bitbuf
        ZSTATE_TRL,     //!< Trailer state
@@ -181,6 +195,8 @@ enum isal_zstate_state {
        ZSTATE_TMP_BODY,        //!< Temporary Body state
        ZSTATE_TMP_FLUSH_READ_BUFFER, //!< Flush buffer
        ZSTATE_TMP_FLUSH_ICF_BUFFER,
+       ZSTATE_TMP_TYPE0_HDR, //! Temporary Type0 block header to be written
+       ZSTATE_TMP_TYPE0_BODY, //!< Temporary Type0 block body to be written
        ZSTATE_TMP_SYNC_FLUSH, //!< Write sync flush block
        ZSTATE_TMP_FLUSH_WRITE_BUFFER, //!< Flush bitbuf
        ZSTATE_TMP_TRL, //!< Temporary Trailer state
@@ -203,16 +219,40 @@ enum isal_block_state {
        ISAL_BLOCK_TYPE0,       /* Decoding a type 0 block */
        ISAL_BLOCK_CODED,       /* Decoding a huffman coded block */
        ISAL_BLOCK_INPUT_DONE,  /* Decompression of input is completed */
-       ISAL_BLOCK_FINISH       /* Decompression of input is completed and all data has been flushed to output */
+       ISAL_BLOCK_FINISH,      /* Decompression of input is completed and all data has been flushed to output */
+       ISAL_GZIP_EXTRA_LEN,
+       ISAL_GZIP_EXTRA,
+       ISAL_GZIP_NAME,
+       ISAL_GZIP_COMMENT,
+       ISAL_GZIP_HCRC,
+       ISAL_ZLIB_DICT,
+       ISAL_CHECKSUM_CHECK,
 };
 
+
+/* Inflate Flags */
+#define ISAL_DEFLATE   0       /* Default */
+#define ISAL_GZIP      1
+#define ISAL_GZIP_NO_HDR       2
+#define ISAL_ZLIB      3
+#define ISAL_ZLIB_NO_HDR       4
+#define ISAL_ZLIB_NO_HDR_VER   5
+#define ISAL_GZIP_NO_HDR_VER   6
+
 /* Inflate Return values */
 #define ISAL_DECOMP_OK 0       /* No errors encountered while decompressing */
 #define ISAL_END_INPUT 1       /* End of input reached */
 #define ISAL_OUT_OVERFLOW 2    /* End of output reached */
+#define ISAL_NAME_OVERFLOW 3   /* End of gzip name buffer reached */
+#define ISAL_COMMENT_OVERFLOW 4        /* End of gzip name buffer reached */
+#define ISAL_EXTRA_OVERFLOW 5  /* End of extra buffer reached */
+#define ISAL_NEED_DICT 6 /* Stream needs a dictionary to continue */
 #define ISAL_INVALID_BLOCK -1  /* Invalid deflate block found */
 #define ISAL_INVALID_SYMBOL -2 /* Invalid deflate symbol found */
 #define ISAL_INVALID_LOOKBACK -3       /* Invalid lookback distance found */
+#define ISAL_INVALID_WRAPPER -4 /* Invalid gzip/zlib wrapper found */
+#define ISAL_UNSUPPORTED_METHOD -5     /* Gzip/zlib wrapper specifies unsupported compress method */
+#define ISAL_INCORRECT_CHECKSUM -6 /* Incorrect checksum found */
 
 /******************************************************************************/
 /* Compression structures */
@@ -221,7 +261,7 @@ enum isal_block_state {
 struct isal_huff_histogram {
        uint64_t lit_len_histogram[ISAL_DEF_LIT_LEN_SYMBOLS]; //!< Histogram of Literal/Len symbols seen
        uint64_t dist_histogram[ISAL_DEF_DIST_SYMBOLS]; //!< Histogram of Distance Symbols seen
-       uint16_t hash_table[IGZIP_HASH_SIZE]; //!< Tmp space used as a hash table
+       uint16_t hash_table[IGZIP_LVL0_HASH_SIZE]; //!< Tmp space used as a hash table
 };
 
 struct isal_mod_hist {
@@ -230,12 +270,17 @@ struct isal_mod_hist {
 };
 
 #define ISAL_DEF_MIN_LEVEL 0
-#define ISAL_DEF_MAX_LEVEL 1
+#define ISAL_DEF_MAX_LEVEL 3
 
 /* Defines used set level data sizes */
+/* has to be at least sizeof(struct level_buf) + sizeof(struct lvlX_buf */
 #define ISAL_DEF_LVL0_REQ 0
-#define ISAL_DEF_LVL1_REQ 4 * IGZIP_K /* has to be at least sizeof(struct level_2_buf) */
+#define ISAL_DEF_LVL1_REQ (4 * IGZIP_K + 2 * IGZIP_LVL1_HASH_SIZE)
 #define ISAL_DEF_LVL1_TOKEN_SIZE 4
+#define ISAL_DEF_LVL2_REQ (4 * IGZIP_K + 2 * IGZIP_LVL2_HASH_SIZE)
+#define ISAL_DEF_LVL2_TOKEN_SIZE 4
+#define ISAL_DEF_LVL3_REQ 4 * IGZIP_K + 4 * 4 * IGZIP_K + 2 * IGZIP_LVL3_HASH_SIZE
+#define ISAL_DEF_LVL3_TOKEN_SIZE 4
 
 /* Data sizes for level specific data options */
 #define ISAL_DEF_LVL0_MIN ISAL_DEF_LVL0_REQ
@@ -252,6 +297,24 @@ struct isal_mod_hist {
 #define ISAL_DEF_LVL1_EXTRA_LARGE (ISAL_DEF_LVL1_REQ + ISAL_DEF_LVL1_TOKEN_SIZE * 128 * IGZIP_K)
 #define ISAL_DEF_LVL1_DEFAULT ISAL_DEF_LVL1_LARGE
 
+#define ISAL_DEF_LVL2_MIN (ISAL_DEF_LVL2_REQ + ISAL_DEF_LVL2_TOKEN_SIZE * 1 * IGZIP_K)
+#define ISAL_DEF_LVL2_SMALL (ISAL_DEF_LVL2_REQ + ISAL_DEF_LVL2_TOKEN_SIZE * 16 * IGZIP_K)
+#define ISAL_DEF_LVL2_MEDIUM (ISAL_DEF_LVL2_REQ + ISAL_DEF_LVL2_TOKEN_SIZE * 32 * IGZIP_K)
+#define ISAL_DEF_LVL2_LARGE (ISAL_DEF_LVL2_REQ + ISAL_DEF_LVL2_TOKEN_SIZE * 64 * IGZIP_K)
+#define ISAL_DEF_LVL2_EXTRA_LARGE (ISAL_DEF_LVL2_REQ + ISAL_DEF_LVL2_TOKEN_SIZE * 128 * IGZIP_K)
+#define ISAL_DEF_LVL2_DEFAULT ISAL_DEF_LVL2_LARGE
+
+#define ISAL_DEF_LVL3_MIN (ISAL_DEF_LVL3_REQ + ISAL_DEF_LVL3_TOKEN_SIZE * 1 * IGZIP_K)
+#define ISAL_DEF_LVL3_SMALL (ISAL_DEF_LVL3_REQ + ISAL_DEF_LVL3_TOKEN_SIZE * 16 * IGZIP_K)
+#define ISAL_DEF_LVL3_MEDIUM (ISAL_DEF_LVL3_REQ + ISAL_DEF_LVL3_TOKEN_SIZE * 32 * IGZIP_K)
+#define ISAL_DEF_LVL3_LARGE (ISAL_DEF_LVL3_REQ + ISAL_DEF_LVL3_TOKEN_SIZE * 64 * IGZIP_K)
+#define ISAL_DEF_LVL3_EXTRA_LARGE (ISAL_DEF_LVL3_REQ + ISAL_DEF_LVL3_TOKEN_SIZE * 128 * IGZIP_K)
+#define ISAL_DEF_LVL3_DEFAULT ISAL_DEF_LVL3_LARGE
+
+#define IGZIP_NO_HIST 0
+#define IGZIP_HIST 1
+#define IGZIP_DICT_HIST 2
+
 /** @brief Holds Bit Buffer information*/
 struct BitBuf2 {
        uint64_t m_bits;        //!< bits in the bit buffer
@@ -261,6 +324,29 @@ struct BitBuf2 {
        uint8_t *m_out_start;   //!< start of buffer to write to
 };
 
+struct isal_zlib_header {
+       uint32_t info;          //!< base-2 logarithm of the LZ77 window size minus 8
+       uint32_t level;         //!< Compression level (fastest, fast, default, maximum)
+       uint32_t dict_id;       //!< Dictionary id
+       uint32_t dict_flag;     //!< Whether to use a dictionary
+};
+
+struct isal_gzip_header {
+       uint32_t text;          //!< Optional Text hint
+       uint32_t time;          //!< Unix modification time in gzip header
+       uint32_t xflags;                //!< xflags in gzip header
+       uint32_t os;            //!< OS in gzip header
+       uint8_t *extra;         //!< Extra field in gzip header
+       uint32_t extra_buf_len; //!< Length of extra buffer
+       uint32_t extra_len;     //!< Actual length of gzip header extra field
+       char *name;             //!< Name in gzip header
+       uint32_t name_buf_len;  //!< Length of name buffer
+       char *comment;          //!< Comments in gzip header
+       uint32_t comment_buf_len;       //!< Length of comment buffer
+       uint32_t hcrc;          //!< Header crc or header crc flag
+       uint32_t flags;         //!< Internal data
+};
+
 /* Variable prefixes:
  * b_ : Measured wrt the start of the buffer
  * f_ : Measured wrt the start of the file (aka file_start)
@@ -268,25 +354,29 @@ struct BitBuf2 {
 
 /** @brief Holds the internal state information for input and output compression streams*/
 struct isal_zstate {
-       uint32_t b_bytes_valid; //!< number of bytes of valid data in buffer
-       uint32_t b_bytes_processed;     //!< keeps track of the number of bytes processed in isal_zstate.buffer
-       uint8_t *file_start;    //!< pointer to where file would logically start
-       uint32_t crc;           //!< Current crc
-       struct BitBuf2 bitbuf;  //!< Bit Buffer
+       uint32_t total_in_start; //!< Not used, may be replaced with something else
+       uint32_t block_next;    //!< Start of current deflate block in the input
+       uint32_t block_end;     //!< End of current deflate block in the input
+       uint32_t dist_mask;     //!< Distance mask used.
+       uint32_t hash_mask;
        enum isal_zstate_state state;   //!< Current state in processing the data stream
+       struct BitBuf2 bitbuf;  //!< Bit Buffer
+       uint32_t crc;           //!< Current checksum without finalize step if any (adler)
+       uint8_t has_wrap_hdr;   //!< keeps track of wrapper header
+       uint8_t has_eob_hdr;    //!< keeps track of eob hdr (with BFINAL set)
+       uint8_t has_eob;        //!< keeps track of eob on the last deflate block
+       uint8_t has_hist;       //!< flag to track if there is match history
+       uint16_t has_level_buf_init; //!< flag to track if user supplied memory has been initialized.
        uint32_t count; //!< used for partial header/trailer writes
        uint8_t tmp_out_buff[16];       //!< temporary array
        uint32_t tmp_out_start; //!< temporary variable
        uint32_t tmp_out_end;   //!< temporary variable
-       uint32_t has_eob;       //!< keeps track of eob on the last deflate block
-       uint32_t has_eob_hdr;   //!< keeps track of eob hdr (with BFINAL set)
-       uint32_t has_hist;      //!< flag to track if there is match history
-
-       struct isal_mod_hist hist;
-
-       DECLARE_ALIGNED(uint8_t buffer[2 * IGZIP_HIST_SIZE + ISAL_LOOK_AHEAD], 32);     //!< Internal buffer
-       DECLARE_ALIGNED(uint16_t head[IGZIP_HASH_SIZE], 16);    //!< Hash array
+       uint32_t b_bytes_valid; //!< number of valid bytes in buffer
+       uint32_t b_bytes_processed;     //!< number of bytes processed in buffer
+       uint8_t buffer[2 * IGZIP_HIST_SIZE + ISAL_LOOK_AHEAD];  //!< Internal buffer
 
+       /* Stream should be setup such that the head is cache aligned*/
+       uint16_t head[IGZIP_LVL0_HASH_SIZE];    //!< Hash array
 };
 
 /** @brief Holds the huffman tree used to huffman encode the input stream **/
@@ -318,10 +408,10 @@ struct isal_zstream {
        uint32_t level; //!< Compression level to use
        uint32_t level_buf_size; //!< Size of level_buf
        uint8_t * level_buf; //!< User allocated buffer required for different compression levels
-       uint32_t end_of_stream; //!< non-zero if this is the last input buffer
-       uint32_t flush; //!< Flush type can be NO_FLUSH, SYNC_FLUSH or FULL_FLUSH
-       uint32_t gzip_flag; //!< Indicate if gzip compression is to be performed
-
+       uint16_t end_of_stream; //!< non-zero if this is the last input buffer
+       uint16_t flush; //!< Flush type can be NO_FLUSH, SYNC_FLUSH or FULL_FLUSH
+       uint16_t gzip_flag; //!< Indicate if gzip compression is to be performed
+       uint16_t hist_bits; //!< Log base 2 of maximum lookback distance, 0 is use default
        struct isal_zstate internal_state;      //!< Internal state for this stream
 };
 
@@ -362,34 +452,57 @@ struct isal_zstream {
  * Since small_code_lookup is a lookup on DECODE_LOOKUP_SIZE bits, it must have
  * size 2^DECODE_LOOKUP_SIZE.
  *
- * Since deflate Huffman are stored such that the code size and the code value
- * form an increasing function, At most 2^(15 - DECODE_LOOKUP_SIZE) - 1 elements
- * of long_code_lookup duplicate an existing symbol. Since there are at most 285
- * - DECODE_LOOKUP_SIZE possible symbols contained in long_code lookup. Rounding
- * this to the nearest 16 byte boundary yields the size of long_code_lookup of
- * 288 + 2^(15 - DECODE_LOOKUP_SIZE).
+ * To determine the amount of memory required for long_code_lookup, note that
+ * any element of long_code_lookup corresponds to a code, a duplicate of an
+ * existing code, or a invalid code. Since deflate Huffman are stored such that
+ * the code size and the code value form an increasing function, the number of
+ * duplicates is maximized when all the duplicates are contained in a single
+ * array, thus there are at most 2^(15 - DECODE_LOOKUP_SIZE) -
+ * (DECODE_LOOKUP_SIZE + 1) duplicate elements. Similarly the number of invalid
+ * elements is maximized at 2^(15 - DECODE_LOOKUP_SIZE) - 2^(floor((15 -
+ * DECODE_LOOKUP_SIZE)/2) - 2^(ceil((15 - DECODE_LOOKUP_SIZE)/2) + 1. Thus the
+ * amount of memory required is: NUM_CODES + 2^(16 - DECODE_LOOKUP_SIZE) -
+ * (DECODE_LOOKUP_SIZE + 1) - 2^(floor((15 - DECODE_LOOKUP_SIZE)/2) -
+ * 2^(ceil((15 - DECODE_LOOKUP_SIZE)/2) + 1. The values used below are those
+ * values rounded up to the nearest 16 byte boundary
  *
  * Note that DECODE_LOOKUP_SIZE can be any length even though the offset in
  * small_lookup_code is 9 bits long because the increasing relationship between
  * code length and code value forces the maximum offset to be less than 288.
  */
 
+/* In the following defines, L stands for LARGE and S for SMALL */
+#define ISAL_L_REM (21 - ISAL_DECODE_LONG_BITS)
+#define ISAL_S_REM (15 - ISAL_DECODE_SHORT_BITS)
+
+#define ISAL_L_DUP ((1 << ISAL_L_REM) - (ISAL_L_REM + 1))
+#define ISAL_S_DUP ((1 << ISAL_S_REM) - (ISAL_S_REM + 1))
+
+#define ISAL_L_UNUSED ((1 << ISAL_L_REM) - (1 << ((ISAL_L_REM)/2)) - (1 << ((ISAL_L_REM + 1)/2)) + 1)
+#define ISAL_S_UNUSED ((1 << ISAL_S_REM) - (1 << ((ISAL_S_REM)/2)) - (1 << ((ISAL_S_REM + 1)/2)) + 1)
+
+#define ISAL_L_SIZE (ISAL_DEF_LIT_LEN_SYMBOLS + ISAL_L_DUP + ISAL_L_UNUSED)
+#define ISAL_S_SIZE (ISAL_DEF_DIST_SYMBOLS + ISAL_S_DUP + ISAL_S_UNUSED)
+
+#define ISAL_HUFF_CODE_LARGE_LONG_ALIGNED (ISAL_L_SIZE + (-ISAL_L_SIZE & 0xf))
+#define ISAL_HUFF_CODE_SMALL_LONG_ALIGNED (ISAL_S_SIZE + (-ISAL_S_SIZE & 0xf))
+
 /* Large lookup table for decoding huffman codes */
 struct inflate_huff_code_large {
-       uint16_t short_code_lookup[1 << (ISAL_DECODE_LONG_BITS)];
-       uint16_t long_code_lookup[288 + (1 << (15 - ISAL_DECODE_LONG_BITS))];
+       uint32_t short_code_lookup[1 << (ISAL_DECODE_LONG_BITS)];
+       uint16_t long_code_lookup[ISAL_HUFF_CODE_LARGE_LONG_ALIGNED];
 };
 
 /* Small lookup table for decoding huffman codes */
 struct inflate_huff_code_small {
        uint16_t short_code_lookup[1 << (ISAL_DECODE_SHORT_BITS)];
-       uint16_t long_code_lookup[32 + (1 << (15 - ISAL_DECODE_SHORT_BITS))];
+       uint16_t long_code_lookup[ISAL_HUFF_CODE_SMALL_LONG_ALIGNED];
 };
 
 /** @brief Holds decompression state information*/
 struct inflate_state {
        uint8_t *next_out;      //!< Next output Byte
-       uint32_t avail_out;     //!< Number of bytes available at next_out 
+       uint32_t avail_out;     //!< Number of bytes available at next_out
        uint32_t total_out;     //!< Total bytes written out so far
        uint8_t *next_in;       //!< Next input byte
        uint64_t read_in;       //!< Bits buffered to handle unaligned streams
@@ -398,13 +511,22 @@ struct inflate_state {
        struct inflate_huff_code_large lit_huff_code;   //!< Structure for decoding lit/len symbols
        struct inflate_huff_code_small dist_huff_code;  //!< Structure for decoding dist symbols
        enum isal_block_state block_state;      //!< Current decompression state
+       uint32_t dict_length;   //!< Length of dictionary used
        uint32_t bfinal;        //!< Flag identifying final block
        uint32_t crc_flag;      //!< Flag identifying whether to track of crc
-       uint32_t crc;           //!< Contains crc of output if crc_flag is set
-       int32_t type0_block_len;        //!< Length left to read of type 0 block when outbuffer overflow occured
-       int32_t copy_overflow_length;   //!< Length left to copy when outbuffer overflow occured
-       int32_t copy_overflow_distance; //!< Lookback distance when outbuffer overlow occured
-       int32_t tmp_in_size;    //!< Number of bytes in tmp_in_buffer
+       uint32_t crc;           //!< Contains crc or adler32 of output if crc_flag is set
+       uint32_t hist_bits; //!< Log base 2 of maximum lookback distance
+       union {
+               int32_t type0_block_len;        //!< Length left to read of type 0 block when outbuffer overflow occurred
+               int32_t count; //!< Count of bytes remaining to be parsed
+               uint32_t dict_id;
+       };
+       int32_t write_overflow_lits;
+       int32_t write_overflow_len;
+       int32_t copy_overflow_length;   //!< Length left to copy when outbuffer overflow occurred
+       int32_t copy_overflow_distance; //!< Lookback distance when outbuffer overflow occurred
+       int16_t wrapper_flag;
+       int16_t tmp_in_size;    //!< Number of bytes in tmp_in_buffer
        int32_t tmp_out_valid;  //!< Number of bytes in tmp_out_buffer
        int32_t tmp_out_processed;      //!< Number of bytes processed in tmp_out_buffer
        uint8_t tmp_in_buffer[ISAL_DEF_MAX_HDR_SIZE];   //!< Temporary buffer containing data from the input stream
@@ -462,11 +584,64 @@ int isal_create_hufftables_subset(struct isal_hufftables * hufftables,
  */
 void isal_deflate_init(struct isal_zstream *stream);
 
+/**
+ * @brief Reinitialize compression stream data structure. Performs the same
+ * action as isal_deflate_init, but does not change user supplied input such as
+ * the level, flush type, compression wrapper (like gzip), hufftables, and
+ * end_of_stream_flag.
+ *
+ * @param stream Structure holding state information on the compression streams.
+ * @returns none
+ */
+void isal_deflate_reset(struct isal_zstream *stream);
+
+
+/**
+ * @brief Set gzip header default values
+ *
+ * @param gz_hdr: Gzip header to initialize.
+ */
+void isal_gzip_header_init(struct isal_gzip_header *gz_hdr);
+
+/**
+ * @brief Write gzip header to output stream
+ *
+ * Writes the gzip header to the output stream. On entry this function assumes
+ * that the output buffer has been initialized, so stream->next_out,
+ * stream->avail_out and stream->total_out have been set. If the output buffer
+ * contains insufficient space, stream is not modified.
+ *
+ * @param stream: Structure holding state information on the compression stream.
+ * @param gz_hdr: Structure holding the gzip header information to encode.
+ *
+ * @returns Returns 0 if the header is successfully written, otherwise returns
+ * the minimum size required to successfully write the gzip header to the output
+ * buffer.
+ */
+uint32_t isal_write_gzip_header(struct isal_zstream * stream, struct isal_gzip_header *gz_hdr);
+
+/**
+ * @brief Write zlib header to output stream
+ *
+ * Writes the zlib header to the output stream. On entry this function assumes
+ * that the output buffer has been initialized, so stream->next_out,
+ * stream->avail_out and stream->total_out have been set. If the output buffer
+ * contains insufficient space, stream is not modified.
+ *
+ * @param stream: Structure holding state information on the compression stream.
+ * @param z_hdr: Structure holding the zlib header information to encode.
+ *
+ * @returns Returns 0 if the header is successfully written, otherwise returns
+ * the minimum size required to successfully write the zlib header to the output
+ * buffer.
+ */
+uint32_t isal_write_zlib_header(struct isal_zstream * stream, struct isal_zlib_header *z_hdr);
+
 /**
  * @brief Set stream to use a new Huffman code
  *
  * Sets the Huffman code to be used in compression before compression start or
- * after the sucessful completion of a SYNC_FLUSH or FULL_FLUSH. If type has
+ * after the successful completion of a SYNC_FLUSH or FULL_FLUSH. If type has
  * value IGZIP_HUFFTABLE_DEFAULT, the stream is set to use the default Huffman
  * code. If type has value IGZIP_HUFFTABLE_STATIC, the stream is set to use the
  * deflate standard static Huffman code, or if type has value
@@ -494,6 +669,22 @@ int isal_deflate_set_hufftables(struct isal_zstream *stream,
 void isal_deflate_stateless_init(struct isal_zstream *stream);
 
 
+/**
+ * @brief Set compression dictionary to use
+ *
+ * This function is to be called after isal_deflate_init, or after completing a
+ * SYNC_FLUSH or FULL_FLUSH and before the next call do isal_deflate. If the
+ * dictionary is longer than IGZIP_HIST_SIZE, only the last IGZIP_HIST_SIZE
+ * bytes will be used.
+ *
+ * @param stream Structure holding state information on the compression streams.
+ * @param dict: Array containing dictionary to use.
+ * @param dict_len: Length of dict.
+ * @returns COMP_OK,
+ *          ISAL_INVALID_STATE (dictionary could not be set)
+ */
+int isal_deflate_set_dict(struct isal_zstream *stream, uint8_t *dict, uint32_t dict_len);
+
 /**
  * @brief Fast data (deflate) compression for storage applications.
  *
@@ -534,14 +725,19 @@ void isal_deflate_stateless_init(struct isal_zstream *stream);
  * not include previous blocks so new blocks are fully independent. Switching
  * between flush types is supported.
  *
+ * If a compression dictionary is required, the dictionary can be set calling
+ * isal_deflate_set_dictionary before calling isal_deflate.
+ *
  * If the gzip_flag is set to IGZIP_GZIP, a generic gzip header and the gzip
  * trailer are written around the deflate compressed data. If gzip_flag is set
- * to IGZIP_GZIP_NO_HDR, then only the gzip trailer is written.
+ * to IGZIP_GZIP_NO_HDR, then only the gzip trailer is written. A full-featured
+ * header is supported by the isal_write_{gzip,zlib}_header() functions.
  *
  * @param  stream Structure holding state information on the compression streams.
  * @return COMP_OK (if everything is ok),
  *         INVALID_FLUSH (if an invalid FLUSH is selected),
- *         ISAL_INVALID_LEVEL (if an invalid compression level is selected).
+ *         ISAL_INVALID_LEVEL (if an invalid compression level is selected),
+ *         ISAL_INVALID_LEVEL_BUF (if the level buffer is not large enough).
  */
 int isal_deflate(struct isal_zstream *stream);
 
@@ -556,7 +752,7 @@ int isal_deflate(struct isal_zstream *stream);
  * block.
  *
  * When the compression level is set to 1, unlike in isal_deflate(), level_buf
- * may be optionally set depending on what what permormance is desired.
+ * may be optionally set depending on what what performance is desired.
  *
  * For stateless the flush types NO_FLUSH and FULL_FLUSH are supported.
  * FULL_FLUSH will byte align the output deflate block so additional blocks can
@@ -570,6 +766,7 @@ int isal_deflate(struct isal_zstream *stream);
  * @return COMP_OK (if everything is ok),
  *         INVALID_FLUSH (if an invalid FLUSH is selected),
  *         ISAL_INVALID_LEVEL (if an invalid compression level is selected),
+ *         ISAL_INVALID_LEVEL_BUF (if the level buffer is not large enough),
  *         STATELESS_OVERFLOW (if output buffer will not fit output).
  */
 int isal_deflate_stateless(struct isal_zstream *stream);
@@ -586,6 +783,67 @@ int isal_deflate_stateless(struct isal_zstream *stream);
  */
 void isal_inflate_init(struct inflate_state *state);
 
+/**
+ * @brief Reinitialize decompression state data structure
+ *
+ * @param state Structure holding state information on the compression streams.
+ * @returns none
+ */
+void isal_inflate_reset(struct inflate_state *state);
+
+/**
+ * @brief Set decompression dictionary to use
+ *
+ * This function is to be called after isal_inflate_init. If the dictionary is
+ * longer than IGZIP_HIST_SIZE, only the last IGZIP_HIST_SIZE bytes will be
+ * used.
+ *
+ * @param state: Structure holding state information on the decompression stream.
+ * @param dict: Array containing dictionary to use.
+ * @param dict_len: Length of dict.
+ * @returns COMP_OK,
+ *          ISAL_INVALID_STATE (dictionary could not be set)
+ */
+int isal_inflate_set_dict(struct inflate_state *state, uint8_t *dict, uint32_t dict_len);
+
+/**
+ * @brief Read and return gzip header information
+ *
+ * On entry state must be initialized and next_in pointing to a gzip compressed
+ * buffer. The buffers gz_hdr->extra, gz_hdr->name, gz_hdr->comments and the
+ * buffer lengths must be set to record the corresponding field, or set to NULL
+ * to disregard that gzip header information. If one of these buffers overflows,
+ * the user can reallocate a larger buffer and call this function again to
+ * continue reading the header information.
+ *
+ * @param state: Structure holding state information on the decompression stream.
+ * @param gz_hdr: Structure to return data encoded in the gzip header
+ * @returns ISAL_DECOMP_OK (header was successfully parsed)
+ *          ISAL_END_INPUT (all input was parsed),
+ *          ISAL_NAME_OVERFLOW (gz_hdr->name overflowed while parsing),
+ *          ISAL_COMMENT_OVERFLOW (gz_hdr->comment overflowed while parsing),
+ *          ISAL_EXTRA_OVERFLOW (gz_hdr->extra overflowed while parsing),
+ *          ISAL_INVALID_WRAPPER (invalid gzip header found),
+ *          ISAL_UNSUPPORTED_METHOD (deflate is not the compression method),
+ *          ISAL_INCORRECT_CHECKSUM (gzip header checksum was incorrect)
+ */
+int isal_read_gzip_header (struct inflate_state *state, struct isal_gzip_header *gz_hdr);
+
+/**
+ * @brief Read and return zlib header information
+ *
+ * On entry state must be initialized and next_in pointing to a zlib compressed
+ * buffer.
+ *
+ * @param state: Structure holding state information on the decompression stream.
+ * @param zlib_hdr: Structure to return data encoded in the zlib header
+ * @returns ISAL_DECOMP_OK (header was successfully parsed),
+ *          ISAL_END_INPUT (all input was parsed),
+ *          ISAL_UNSUPPORTED_METHOD (deflate is not the compression method),
+ *          ISAL_INCORRECT_CHECKSUM (zlib header checksum was incorrect)
+ */
+int isal_read_zlib_header (struct inflate_state *state, struct isal_zlib_header *zlib_hdr);
+
 /**
  * @brief Fast data (deflate) decompression for storage applications.
  *
@@ -599,18 +857,39 @@ void isal_inflate_init(struct inflate_state *state);
  * The call to isal_inflate() will take data from the input buffer (updating
  * next_in, avail_in and write a decompressed stream to the output buffer
  * (updating next_out and avail_out). The function returns when the input buffer
- * is empty, the output buffer is full or invalid data is found. The current
- * state of the decompression on exit can be read from state->block-state. If
- * the crc_flag is set, the gzip crc of the output is stored in state->crc.
+ * is empty, the output buffer is full, invalid data is found, or in the case of
+ * zlib formatted data if a dictionary is specified. The current state of the
+ * decompression on exit can be read from state->block-state.
+ *
+ * If the crc_flag is set to ISAL_GZIP_NO_HDR the gzip crc of the output is
+ * stored in state->crc. Alternatively, if the crc_flag is set to
+ * ISAL_ZLIB_NO_HDR the adler32 of the output is stored in state->crc (checksum
+ * may not be updated until decompression is complete). When the crc_flag is set
+ * to ISAL_GZIP_NO_HDR_VER or ISAL_ZLIB_NO_HDR_VER, the behavior is the same,
+ * except the checksum is verified with the checksum after immediately following
+ * the deflate data. If the crc_flag is set to ISAL_GZIP or ISAL_ZLIB, the
+ * gzip/zlib header is parsed, state->crc is set to the appropriate checksum,
+ * and the checksum is verified. If the crc_flag is set to ISAL_DEFLATE
+ * (default), then the data is treated as a raw deflate block.
+ *
+ * The element state->hist_bits has values from 0 to 15, where values of 1 to 15
+ * are the log base 2 size of the matching window and 0 is the default with
+ * maximum history size.
+ *
+ * If a dictionary is required, a call to isal_inflate_set_dict will set the
+ * dictionary.
  *
  * @param  state Structure holding state information on the compression streams.
  * @return ISAL_DECOMP_OK (if everything is ok),
- *         ISAL_END_INPUT (if all input was decompressed),
- *         ISAL_OUT_OVERFLOW (if output buffer ran out of space),
  *         ISAL_INVALID_BLOCK,
+ *         ISAL_NEED_DICT,
  *         ISAL_INVALID_SYMBOL,
- *         ISAL_INVALID_LOOKBACK.
+ *         ISAL_INVALID_LOOKBACK,
+ *         ISAL_INVALID_WRAPPER,
+ *         ISAL_UNSUPPORTED_METHOD,
+ *         ISAL_INCORRECT_CHECKSUM.
  */
+
 int isal_inflate(struct inflate_state *state);
 
 /**
@@ -618,18 +897,40 @@ int isal_inflate(struct inflate_state *state);
  *
  * Stateless (one shot) decompression routine with a similar interface to
  * isal_inflate() but operates on entire input buffer at one time. Parameter
- * avail_out must be large enough to fit the entire decompressed output.
+ * avail_out must be large enough to fit the entire decompressed
+ * output. Dictionaries are not supported.
  *
  * @param  state Structure holding state information on the compression streams.
  * @return ISAL_DECOMP_OK (if everything is ok),
  *         ISAL_END_INPUT (if all input was decompressed),
+ *         ISAL_NEED_DICT,
  *         ISAL_OUT_OVERFLOW (if output buffer ran out of space),
  *         ISAL_INVALID_BLOCK,
  *         ISAL_INVALID_SYMBOL,
- *         ISAL_INVALID_LOOKBACK.
+ *         ISAL_INVALID_LOOKBACK,
+ *         ISAL_INVALID_WRAPPER,
+ *         ISAL_UNSUPPORTED_METHOD,
+ *         ISAL_INCORRECT_CHECKSUM.
  */
 int isal_inflate_stateless(struct inflate_state *state);
 
+/******************************************************************************/
+/* Other functions */
+/******************************************************************************/
+/**
+ * @brief Calculate Adler-32 checksum, runs appropriate version.
+ *
+ * This function determines what instruction sets are enabled and selects the
+ * appropriate version at runtime.
+ *
+ * @param init: initial Adler-32 value
+ * @param buf: buffer to calculate checksum on
+ * @param len: buffer length in bytes
+ *
+ * @returns 32-bit Adler-32 checksum
+ */
+uint32_t isal_adler32(uint32_t init, const unsigned char *buf, uint64_t len);
+
 #ifdef __cplusplus
 }
 #endif