Updates to Brotli compression format, decoder and encoder

This commit contains a batch of changes that were made to the Brotli
compression algorithm in the last month. Most important changes:

   * Fixes to the spec.
   * Change of code length code order.
   * Use a 2-level Huffman lookup table in the decoder.
   * Faster uncompressed meta-block decoding.
   * Optimized encoding of the Huffman code.
   * Detection of UTF-8 input encoding.
   * UTF-8 based literal cost modeling for improved
     backward reference selection.
This commit is contained in:
Zoltan Szabadka
2014-02-14 15:04:23 +01:00
parent dfc5a9f215
commit cbd5cb55f4
16 changed files with 912 additions and 635 deletions
+9 -40
View File
@@ -12,7 +12,7 @@
See the License for the specific language governing permissions and
limitations under the License.
Utilities for building and looking up Huffman trees.
Utilities for building Huffman decoding tables.
*/
#ifndef BROTLI_DEC_HUFFMAN_H_
@@ -25,48 +25,17 @@
extern "C" {
#endif
/* A node of a Huffman tree. */
typedef struct {
int symbol_;
int children_; /* delta offset to both children (contiguous) or 0 if leaf. */
} HuffmanTreeNode;
uint8_t bits; /* number of bits used for this symbol */
uint16_t value; /* symbol value or table offset */
} HuffmanCode;
/* Huffman Tree. */
#define HUFF_LUT_BITS 7
#define HUFF_LUT (1U << HUFF_LUT_BITS)
typedef struct HuffmanTree HuffmanTree;
struct HuffmanTree {
/* Fast lookup for short bit lengths. */
uint8_t lut_bits_[HUFF_LUT];
int16_t lut_symbol_[HUFF_LUT];
int16_t lut_jump_[HUFF_LUT];
/* Complete tree for lookups. */
HuffmanTreeNode* root_; /* all the nodes, starting at root. */
int max_nodes_; /* max number of nodes */
int num_nodes_; /* number of currently occupied nodes */
};
/* Returns true if the given node is not a leaf of the Huffman tree. */
static BROTLI_INLINE int HuffmanTreeNodeIsNotLeaf(
const HuffmanTreeNode* const node) {
return node->children_;
}
/* Go down one level. Most critical function. 'right_child' must be 0 or 1. */
static BROTLI_INLINE const HuffmanTreeNode* HuffmanTreeNextNode(
const HuffmanTreeNode* node, int right_child) {
return node + node->children_ + right_child;
}
/* Releases the nodes of the Huffman tree. */
/* Note: It does NOT free 'tree' itself. */
void BrotliHuffmanTreeRelease(HuffmanTree* const tree);
/* Builds Huffman tree assuming code lengths are implicitly in symbol order. */
/* Builds Huffman lookup table assuming code lengths are in symbol order. */
/* Returns false in case of error (invalid tree or memory error). */
int BrotliHuffmanTreeBuildImplicit(HuffmanTree* const tree,
const uint8_t* const code_lengths,
int code_lengths_size);
int BrotliBuildHuffmanTable(HuffmanCode* root_table,
int root_bits,
const uint8_t* const code_lengths,
int code_lengths_size);
#if defined(__cplusplus) || defined(c_plusplus)
} /* extern "C" */