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