126fa459cSmrg/* Copyright 2013 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/* Utilities for building Huffman decoding tables. */
826fa459cSmrg
926fa459cSmrg#ifndef BROTLI_DEC_HUFFMAN_H_
1026fa459cSmrg#define BROTLI_DEC_HUFFMAN_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#define BROTLI_HUFFMAN_MAX_CODE_LENGTH 15
2026fa459cSmrg
2126fa459cSmrg/* BROTLI_NUM_BLOCK_LEN_SYMBOLS == 26 */
2226fa459cSmrg#define BROTLI_HUFFMAN_MAX_SIZE_26 396
2326fa459cSmrg/* BROTLI_MAX_BLOCK_TYPE_SYMBOLS == 258 */
2426fa459cSmrg#define BROTLI_HUFFMAN_MAX_SIZE_258 632
2526fa459cSmrg/* BROTLI_MAX_CONTEXT_MAP_SYMBOLS == 272 */
2626fa459cSmrg#define BROTLI_HUFFMAN_MAX_SIZE_272 646
2726fa459cSmrg
2826fa459cSmrg#define BROTLI_HUFFMAN_MAX_CODE_LENGTH_CODE_LENGTH 5
2926fa459cSmrg
3026fa459cSmrg#if ((defined(BROTLI_TARGET_ARMV7) || defined(BROTLI_TARGET_ARMV8_32)) && \
3126fa459cSmrg  BROTLI_GNUC_HAS_ATTRIBUTE(aligned, 2, 7, 0))
3226fa459cSmrg#define BROTLI_HUFFMAN_CODE_FAST_LOAD
3326fa459cSmrg#endif
3426fa459cSmrg
3526fa459cSmrg#if !defined(BROTLI_HUFFMAN_CODE_FAST_LOAD)
3626fa459cSmrg/* Do not create this struct directly - use the ConstructHuffmanCode
3726fa459cSmrg * constructor below! */
3826fa459cSmrgtypedef struct {
3926fa459cSmrg  uint8_t bits;    /* number of bits used for this symbol */
4026fa459cSmrg  uint16_t value;  /* symbol value or table offset */
4126fa459cSmrg} HuffmanCode;
4226fa459cSmrg
4326fa459cSmrgstatic BROTLI_INLINE HuffmanCode ConstructHuffmanCode(const uint8_t bits,
4426fa459cSmrg    const uint16_t value) {
4526fa459cSmrg  HuffmanCode h;
4626fa459cSmrg  h.bits = bits;
4726fa459cSmrg  h.value = value;
4826fa459cSmrg  return h;
4926fa459cSmrg}
5026fa459cSmrg
5126fa459cSmrg/* Please use the following macros to optimize HuffmanCode accesses in hot
5226fa459cSmrg * paths.
5326fa459cSmrg *
5426fa459cSmrg * For example, assuming |table| contains a HuffmanCode pointer:
5526fa459cSmrg *
5626fa459cSmrg *   BROTLI_HC_MARK_TABLE_FOR_FAST_LOAD(table);
5726fa459cSmrg *   BROTLI_HC_ADJUST_TABLE_INDEX(table, index_into_table);
5826fa459cSmrg *   *bits = BROTLI_HC_GET_BITS(table);
5926fa459cSmrg *   *value = BROTLI_HC_GET_VALUE(table);
6026fa459cSmrg *   BROTLI_HC_ADJUST_TABLE_INDEX(table, offset);
6126fa459cSmrg *   *bits2 = BROTLI_HC_GET_BITS(table);
6226fa459cSmrg *   *value2 = BROTLI_HC_GET_VALUE(table);
6326fa459cSmrg *
6426fa459cSmrg */
6526fa459cSmrg
6626fa459cSmrg#define BROTLI_HC_MARK_TABLE_FOR_FAST_LOAD(H)
6726fa459cSmrg#define BROTLI_HC_ADJUST_TABLE_INDEX(H, V) H += (V)
6826fa459cSmrg
6926fa459cSmrg/* These must be given a HuffmanCode pointer! */
7026fa459cSmrg#define BROTLI_HC_FAST_LOAD_BITS(H) (H->bits)
7126fa459cSmrg#define BROTLI_HC_FAST_LOAD_VALUE(H) (H->value)
7226fa459cSmrg
7326fa459cSmrg#else /* BROTLI_HUFFMAN_CODE_FAST_LOAD */
7426fa459cSmrg
7526fa459cSmrgtypedef BROTLI_ALIGNED(4) uint32_t HuffmanCode;
7626fa459cSmrg
7726fa459cSmrgstatic BROTLI_INLINE HuffmanCode ConstructHuffmanCode(const uint8_t bits,
7826fa459cSmrg    const uint16_t value) {
7926fa459cSmrg  return (HuffmanCode) ((value & 0xFFFF) << 16) | (bits & 0xFF);
8026fa459cSmrg}
8126fa459cSmrg
8226fa459cSmrg#define BROTLI_HC_MARK_TABLE_FOR_FAST_LOAD(H) uint32_t __fastload_##H = (*H)
8326fa459cSmrg#define BROTLI_HC_ADJUST_TABLE_INDEX(H, V) H += (V); __fastload_##H = (*H)
8426fa459cSmrg
8526fa459cSmrg/* These must be given a HuffmanCode pointer! */
8626fa459cSmrg#define BROTLI_HC_FAST_LOAD_BITS(H) ((__fastload_##H) & 0xFF)
8726fa459cSmrg#define BROTLI_HC_FAST_LOAD_VALUE(H) ((__fastload_##H) >> 16)
8826fa459cSmrg#endif /* BROTLI_HUFFMAN_CODE_FAST_LOAD */
8926fa459cSmrg
9026fa459cSmrg/* Builds Huffman lookup table assuming code lengths are in symbol order. */
9126fa459cSmrgBROTLI_INTERNAL void BrotliBuildCodeLengthsHuffmanTable(HuffmanCode* root_table,
9226fa459cSmrg    const uint8_t* const code_lengths, uint16_t* count);
9326fa459cSmrg
9426fa459cSmrg/* Builds Huffman lookup table assuming code lengths are in symbol order.
9526fa459cSmrg   Returns size of resulting table. */
9626fa459cSmrgBROTLI_INTERNAL uint32_t BrotliBuildHuffmanTable(HuffmanCode* root_table,
9726fa459cSmrg    int root_bits, const uint16_t* const symbol_lists, uint16_t* count);
9826fa459cSmrg
9926fa459cSmrg/* Builds a simple Huffman table. The |num_symbols| parameter is to be
10026fa459cSmrg   interpreted as follows: 0 means 1 symbol, 1 means 2 symbols,
10126fa459cSmrg   2 means 3 symbols, 3 means 4 symbols with lengths [2, 2, 2, 2],
10226fa459cSmrg   4 means 4 symbols with lengths [1, 2, 3, 3]. */
10326fa459cSmrgBROTLI_INTERNAL uint32_t BrotliBuildSimpleHuffmanTable(HuffmanCode* table,
10426fa459cSmrg    int root_bits, uint16_t* symbols, uint32_t num_symbols);
10526fa459cSmrg
10626fa459cSmrg/* Contains a collection of Huffman trees with the same alphabet size. */
10726fa459cSmrg/* alphabet_size_limit is needed due to simple codes, since
10826fa459cSmrg   log2(alphabet_size_max) could be greater than log2(alphabet_size_limit). */
10926fa459cSmrgtypedef struct {
11026fa459cSmrg  HuffmanCode** htrees;
11126fa459cSmrg  HuffmanCode* codes;
11226fa459cSmrg  uint16_t alphabet_size_max;
11326fa459cSmrg  uint16_t alphabet_size_limit;
11426fa459cSmrg  uint16_t num_htrees;
11526fa459cSmrg} HuffmanTreeGroup;
11626fa459cSmrg
11726fa459cSmrg#if defined(__cplusplus) || defined(c_plusplus)
11826fa459cSmrg}  /* extern "C" */
11926fa459cSmrg#endif
12026fa459cSmrg
12126fa459cSmrg#endif  /* BROTLI_DEC_HUFFMAN_H_ */
122