Path: blob/master/3rdparty/libwebp/src/utils/huffman_utils.c
16358 views
// Copyright 2012 Google Inc. All Rights Reserved.1//2// Use of this source code is governed by a BSD-style license3// that can be found in the COPYING file in the root of the source4// tree. An additional intellectual property rights grant can be found5// in the file PATENTS. All contributing project authors may6// be found in the AUTHORS file in the root of the source tree.7// -----------------------------------------------------------------------------8//9// Utilities for building and looking up Huffman trees.10//11// Author: Urvang Joshi ([email protected])1213#include <assert.h>14#include <stdlib.h>15#include <string.h>16#include "src/utils/huffman_utils.h"17#include "src/utils/utils.h"18#include "src/webp/format_constants.h"1920// Huffman data read via DecodeImageStream is represented in two (red and green)21// bytes.22#define MAX_HTREE_GROUPS 0x100002324HTreeGroup* VP8LHtreeGroupsNew(int num_htree_groups) {25HTreeGroup* const htree_groups =26(HTreeGroup*)WebPSafeMalloc(num_htree_groups, sizeof(*htree_groups));27if (htree_groups == NULL) {28return NULL;29}30assert(num_htree_groups <= MAX_HTREE_GROUPS);31return htree_groups;32}3334void VP8LHtreeGroupsFree(HTreeGroup* const htree_groups) {35if (htree_groups != NULL) {36WebPSafeFree(htree_groups);37}38}3940// Returns reverse(reverse(key, len) + 1, len), where reverse(key, len) is the41// bit-wise reversal of the len least significant bits of key.42static WEBP_INLINE uint32_t GetNextKey(uint32_t key, int len) {43uint32_t step = 1 << (len - 1);44while (key & step) {45step >>= 1;46}47return step ? (key & (step - 1)) + step : key;48}4950// Stores code in table[0], table[step], table[2*step], ..., table[end].51// Assumes that end is an integer multiple of step.52static WEBP_INLINE void ReplicateValue(HuffmanCode* table,53int step, int end,54HuffmanCode code) {55assert(end % step == 0);56do {57end -= step;58table[end] = code;59} while (end > 0);60}6162// Returns the table width of the next 2nd level table. count is the histogram63// of bit lengths for the remaining symbols, len is the code length of the next64// processed symbol65static WEBP_INLINE int NextTableBitSize(const int* const count,66int len, int root_bits) {67int left = 1 << (len - root_bits);68while (len < MAX_ALLOWED_CODE_LENGTH) {69left -= count[len];70if (left <= 0) break;71++len;72left <<= 1;73}74return len - root_bits;75}7677// sorted[code_lengths_size] is a pre-allocated array for sorting symbols78// by code length.79static int BuildHuffmanTable(HuffmanCode* const root_table, int root_bits,80const int code_lengths[], int code_lengths_size,81uint16_t sorted[]) {82HuffmanCode* table = root_table; // next available space in table83int total_size = 1 << root_bits; // total size root table + 2nd level table84int len; // current code length85int symbol; // symbol index in original or sorted table86// number of codes of each length:87int count[MAX_ALLOWED_CODE_LENGTH + 1] = { 0 };88// offsets in sorted table for each length:89int offset[MAX_ALLOWED_CODE_LENGTH + 1];9091assert(code_lengths_size != 0);92assert(code_lengths != NULL);93assert(root_table != NULL);94assert(root_bits > 0);9596// Build histogram of code lengths.97for (symbol = 0; symbol < code_lengths_size; ++symbol) {98if (code_lengths[symbol] > MAX_ALLOWED_CODE_LENGTH) {99return 0;100}101++count[code_lengths[symbol]];102}103104// Error, all code lengths are zeros.105if (count[0] == code_lengths_size) {106return 0;107}108109// Generate offsets into sorted symbol table by code length.110offset[1] = 0;111for (len = 1; len < MAX_ALLOWED_CODE_LENGTH; ++len) {112if (count[len] > (1 << len)) {113return 0;114}115offset[len + 1] = offset[len] + count[len];116}117118// Sort symbols by length, by symbol order within each length.119for (symbol = 0; symbol < code_lengths_size; ++symbol) {120const int symbol_code_length = code_lengths[symbol];121if (code_lengths[symbol] > 0) {122sorted[offset[symbol_code_length]++] = symbol;123}124}125126// Special case code with only one value.127if (offset[MAX_ALLOWED_CODE_LENGTH] == 1) {128HuffmanCode code;129code.bits = 0;130code.value = (uint16_t)sorted[0];131ReplicateValue(table, 1, total_size, code);132return total_size;133}134135{136int step; // step size to replicate values in current table137uint32_t low = -1; // low bits for current root entry138uint32_t mask = total_size - 1; // mask for low bits139uint32_t key = 0; // reversed prefix code140int num_nodes = 1; // number of Huffman tree nodes141int num_open = 1; // number of open branches in current tree level142int table_bits = root_bits; // key length of current table143int table_size = 1 << table_bits; // size of current table144symbol = 0;145// Fill in root table.146for (len = 1, step = 2; len <= root_bits; ++len, step <<= 1) {147num_open <<= 1;148num_nodes += num_open;149num_open -= count[len];150if (num_open < 0) {151return 0;152}153for (; count[len] > 0; --count[len]) {154HuffmanCode code;155code.bits = (uint8_t)len;156code.value = (uint16_t)sorted[symbol++];157ReplicateValue(&table[key], step, table_size, code);158key = GetNextKey(key, len);159}160}161162// Fill in 2nd level tables and add pointers to root table.163for (len = root_bits + 1, step = 2; len <= MAX_ALLOWED_CODE_LENGTH;164++len, step <<= 1) {165num_open <<= 1;166num_nodes += num_open;167num_open -= count[len];168if (num_open < 0) {169return 0;170}171for (; count[len] > 0; --count[len]) {172HuffmanCode code;173if ((key & mask) != low) {174table += table_size;175table_bits = NextTableBitSize(count, len, root_bits);176table_size = 1 << table_bits;177total_size += table_size;178low = key & mask;179root_table[low].bits = (uint8_t)(table_bits + root_bits);180root_table[low].value = (uint16_t)((table - root_table) - low);181}182code.bits = (uint8_t)(len - root_bits);183code.value = (uint16_t)sorted[symbol++];184ReplicateValue(&table[key >> root_bits], step, table_size, code);185key = GetNextKey(key, len);186}187}188189// Check if tree is full.190if (num_nodes != 2 * offset[MAX_ALLOWED_CODE_LENGTH] - 1) {191return 0;192}193}194195return total_size;196}197198// Maximum code_lengths_size is 2328 (reached for 11-bit color_cache_bits).199// More commonly, the value is around ~280.200#define MAX_CODE_LENGTHS_SIZE \201((1 << MAX_CACHE_BITS) + NUM_LITERAL_CODES + NUM_LENGTH_CODES)202// Cut-off value for switching between heap and stack allocation.203#define SORTED_SIZE_CUTOFF 512204int VP8LBuildHuffmanTable(HuffmanCode* const root_table, int root_bits,205const int code_lengths[], int code_lengths_size) {206int total_size;207assert(code_lengths_size <= MAX_CODE_LENGTHS_SIZE);208if (code_lengths_size <= SORTED_SIZE_CUTOFF) {209// use local stack-allocated array.210uint16_t sorted[SORTED_SIZE_CUTOFF];211total_size = BuildHuffmanTable(root_table, root_bits,212code_lengths, code_lengths_size, sorted);213} else { // rare case. Use heap allocation.214uint16_t* const sorted =215(uint16_t*)WebPSafeMalloc(code_lengths_size, sizeof(*sorted));216if (sorted == NULL) return 0;217total_size = BuildHuffmanTable(root_table, root_bits,218code_lengths, code_lengths_size, sorted);219WebPSafeFree(sorted);220}221return total_size;222}223224225