entropy_encode.h revision 26fa459c
126fa459cSmrg/* Copyright 2010 Google Inc. All Rights Reserved. 226fa459cSmrg 326fa459cSmrg Distributed under MIT license. 426fa459cSmrg See file LICENSE for detail or copy at https://opensource.org/licenses/MIT 526fa459cSmrg*/ 626fa459cSmrg 726fa459cSmrg/* Entropy encoding (Huffman) utilities. */ 826fa459cSmrg 926fa459cSmrg#ifndef BROTLI_ENC_ENTROPY_ENCODE_H_ 1026fa459cSmrg#define BROTLI_ENC_ENTROPY_ENCODE_H_ 1126fa459cSmrg 1226fa459cSmrg#include "../common/platform.h" 1326fa459cSmrg#include <brotli/types.h> 1426fa459cSmrg 1526fa459cSmrg#if defined(__cplusplus) || defined(c_plusplus) 1626fa459cSmrgextern "C" { 1726fa459cSmrg#endif 1826fa459cSmrg 1926fa459cSmrg/* A node of a Huffman tree. */ 2026fa459cSmrgtypedef struct HuffmanTree { 2126fa459cSmrg uint32_t total_count_; 2226fa459cSmrg int16_t index_left_; 2326fa459cSmrg int16_t index_right_or_value_; 2426fa459cSmrg} HuffmanTree; 2526fa459cSmrg 2626fa459cSmrgstatic BROTLI_INLINE void InitHuffmanTree(HuffmanTree* self, uint32_t count, 2726fa459cSmrg int16_t left, int16_t right) { 2826fa459cSmrg self->total_count_ = count; 2926fa459cSmrg self->index_left_ = left; 3026fa459cSmrg self->index_right_or_value_ = right; 3126fa459cSmrg} 3226fa459cSmrg 3326fa459cSmrg/* Returns 1 is assignment of depths succeeded, otherwise 0. */ 3426fa459cSmrgBROTLI_INTERNAL BROTLI_BOOL BrotliSetDepth( 3526fa459cSmrg int p, HuffmanTree* pool, uint8_t* depth, int max_depth); 3626fa459cSmrg 3726fa459cSmrg/* This function will create a Huffman tree. 3826fa459cSmrg 3926fa459cSmrg The (data,length) contains the population counts. 4026fa459cSmrg The tree_limit is the maximum bit depth of the Huffman codes. 4126fa459cSmrg 4226fa459cSmrg The depth contains the tree, i.e., how many bits are used for 4326fa459cSmrg the symbol. 4426fa459cSmrg 4526fa459cSmrg The actual Huffman tree is constructed in the tree[] array, which has to 4626fa459cSmrg be at least 2 * length + 1 long. 4726fa459cSmrg 4826fa459cSmrg See http://en.wikipedia.org/wiki/Huffman_coding */ 4926fa459cSmrgBROTLI_INTERNAL void BrotliCreateHuffmanTree(const uint32_t* data, 5026fa459cSmrg const size_t length, 5126fa459cSmrg const int tree_limit, 5226fa459cSmrg HuffmanTree* tree, 5326fa459cSmrg uint8_t* depth); 5426fa459cSmrg 5526fa459cSmrg/* Change the population counts in a way that the consequent 5626fa459cSmrg Huffman tree compression, especially its RLE-part will be more 5726fa459cSmrg likely to compress this data more efficiently. 5826fa459cSmrg 5926fa459cSmrg length contains the size of the histogram. 6026fa459cSmrg counts contains the population counts. 6126fa459cSmrg good_for_rle is a buffer of at least length size */ 6226fa459cSmrgBROTLI_INTERNAL void BrotliOptimizeHuffmanCountsForRle( 6326fa459cSmrg size_t length, uint32_t* counts, uint8_t* good_for_rle); 6426fa459cSmrg 6526fa459cSmrg/* Write a Huffman tree from bit depths into the bit-stream representation 6626fa459cSmrg of a Huffman tree. The generated Huffman tree is to be compressed once 6726fa459cSmrg more using a Huffman tree */ 6826fa459cSmrgBROTLI_INTERNAL void BrotliWriteHuffmanTree(const uint8_t* depth, 6926fa459cSmrg size_t num, 7026fa459cSmrg size_t* tree_size, 7126fa459cSmrg uint8_t* tree, 7226fa459cSmrg uint8_t* extra_bits_data); 7326fa459cSmrg 7426fa459cSmrg/* Get the actual bit values for a tree of bit depths. */ 7526fa459cSmrgBROTLI_INTERNAL void BrotliConvertBitDepthsToSymbols(const uint8_t* depth, 7626fa459cSmrg size_t len, 7726fa459cSmrg uint16_t* bits); 7826fa459cSmrg 7926fa459cSmrgBROTLI_INTERNAL extern const size_t kBrotliShellGaps[6]; 8026fa459cSmrg/* Input size optimized Shell sort. */ 8126fa459cSmrgtypedef BROTLI_BOOL (*HuffmanTreeComparator)( 8226fa459cSmrg const HuffmanTree*, const HuffmanTree*); 8326fa459cSmrgstatic BROTLI_INLINE void SortHuffmanTreeItems(HuffmanTree* items, 8426fa459cSmrg const size_t n, HuffmanTreeComparator comparator) { 8526fa459cSmrg if (n < 13) { 8626fa459cSmrg /* Insertion sort. */ 8726fa459cSmrg size_t i; 8826fa459cSmrg for (i = 1; i < n; ++i) { 8926fa459cSmrg HuffmanTree tmp = items[i]; 9026fa459cSmrg size_t k = i; 9126fa459cSmrg size_t j = i - 1; 9226fa459cSmrg while (comparator(&tmp, &items[j])) { 9326fa459cSmrg items[k] = items[j]; 9426fa459cSmrg k = j; 9526fa459cSmrg if (!j--) break; 9626fa459cSmrg } 9726fa459cSmrg items[k] = tmp; 9826fa459cSmrg } 9926fa459cSmrg return; 10026fa459cSmrg } else { 10126fa459cSmrg /* Shell sort. */ 10226fa459cSmrg int g = n < 57 ? 2 : 0; 10326fa459cSmrg for (; g < 6; ++g) { 10426fa459cSmrg size_t gap = kBrotliShellGaps[g]; 10526fa459cSmrg size_t i; 10626fa459cSmrg for (i = gap; i < n; ++i) { 10726fa459cSmrg size_t j = i; 10826fa459cSmrg HuffmanTree tmp = items[i]; 10926fa459cSmrg for (; j >= gap && comparator(&tmp, &items[j - gap]); j -= gap) { 11026fa459cSmrg items[j] = items[j - gap]; 11126fa459cSmrg } 11226fa459cSmrg items[j] = tmp; 11326fa459cSmrg } 11426fa459cSmrg } 11526fa459cSmrg } 11626fa459cSmrg} 11726fa459cSmrg 11826fa459cSmrg#if defined(__cplusplus) || defined(c_plusplus) 11926fa459cSmrg} /* extern "C" */ 12026fa459cSmrg#endif 12126fa459cSmrg 12226fa459cSmrg#endif /* BROTLI_ENC_ENTROPY_ENCODE_H_ */ 123