Blame src/utils/huffman_encode_utils.c

Packit 9c6abc
// Copyright 2011 Google Inc. All Rights Reserved.
Packit 9c6abc
//
Packit 9c6abc
// Use of this source code is governed by a BSD-style license
Packit 9c6abc
// that can be found in the COPYING file in the root of the source
Packit 9c6abc
// tree. An additional intellectual property rights grant can be found
Packit 9c6abc
// in the file PATENTS. All contributing project authors may
Packit 9c6abc
// be found in the AUTHORS file in the root of the source tree.
Packit 9c6abc
// -----------------------------------------------------------------------------
Packit 9c6abc
//
Packit 9c6abc
// Author: Jyrki Alakuijala (jyrki@google.com)
Packit 9c6abc
//
Packit 9c6abc
// Entropy encoding (Huffman) for webp lossless.
Packit 9c6abc
Packit 9c6abc
#include <assert.h>
Packit 9c6abc
#include <stdlib.h>
Packit 9c6abc
#include <string.h>
Packit 9c6abc
#include "src/utils/huffman_encode_utils.h"
Packit 9c6abc
#include "src/utils/utils.h"
Packit 9c6abc
#include "src/webp/format_constants.h"
Packit 9c6abc
Packit 9c6abc
// -----------------------------------------------------------------------------
Packit 9c6abc
// Util function to optimize the symbol map for RLE coding
Packit 9c6abc
Packit 9c6abc
// Heuristics for selecting the stride ranges to collapse.
Packit 9c6abc
static int ValuesShouldBeCollapsedToStrideAverage(int a, int b) {
Packit 9c6abc
  return abs(a - b) < 4;
Packit 9c6abc
}
Packit 9c6abc
Packit 9c6abc
// Change the population counts in a way that the consequent
Packit 9c6abc
// Huffman tree compression, especially its RLE-part, give smaller output.
Packit 9c6abc
static void OptimizeHuffmanForRle(int length, uint8_t* const good_for_rle,
Packit 9c6abc
                                  uint32_t* const counts) {
Packit 9c6abc
  // 1) Let's make the Huffman code more compatible with rle encoding.
Packit 9c6abc
  int i;
Packit 9c6abc
  for (; length >= 0; --length) {
Packit 9c6abc
    if (length == 0) {
Packit 9c6abc
      return;  // All zeros.
Packit 9c6abc
    }
Packit 9c6abc
    if (counts[length - 1] != 0) {
Packit 9c6abc
      // Now counts[0..length - 1] does not have trailing zeros.
Packit 9c6abc
      break;
Packit 9c6abc
    }
Packit 9c6abc
  }
Packit 9c6abc
  // 2) Let's mark all population counts that already can be encoded
Packit 9c6abc
  // with an rle code.
Packit 9c6abc
  {
Packit 9c6abc
    // Let's not spoil any of the existing good rle codes.
Packit 9c6abc
    // Mark any seq of 0's that is longer as 5 as a good_for_rle.
Packit 9c6abc
    // Mark any seq of non-0's that is longer as 7 as a good_for_rle.
Packit 9c6abc
    uint32_t symbol = counts[0];
Packit 9c6abc
    int stride = 0;
Packit 9c6abc
    for (i = 0; i < length + 1; ++i) {
Packit 9c6abc
      if (i == length || counts[i] != symbol) {
Packit 9c6abc
        if ((symbol == 0 && stride >= 5) ||
Packit 9c6abc
            (symbol != 0 && stride >= 7)) {
Packit 9c6abc
          int k;
Packit 9c6abc
          for (k = 0; k < stride; ++k) {
Packit 9c6abc
            good_for_rle[i - k - 1] = 1;
Packit 9c6abc
          }
Packit 9c6abc
        }
Packit 9c6abc
        stride = 1;
Packit 9c6abc
        if (i != length) {
Packit 9c6abc
          symbol = counts[i];
Packit 9c6abc
        }
Packit 9c6abc
      } else {
Packit 9c6abc
        ++stride;
Packit 9c6abc
      }
Packit 9c6abc
    }
Packit 9c6abc
  }
Packit 9c6abc
  // 3) Let's replace those population counts that lead to more rle codes.
Packit 9c6abc
  {
Packit 9c6abc
    uint32_t stride = 0;
Packit 9c6abc
    uint32_t limit = counts[0];
Packit 9c6abc
    uint32_t sum = 0;
Packit 9c6abc
    for (i = 0; i < length + 1; ++i) {
Packit 9c6abc
      if (i == length || good_for_rle[i] ||
Packit 9c6abc
          (i != 0 && good_for_rle[i - 1]) ||
Packit 9c6abc
          !ValuesShouldBeCollapsedToStrideAverage(counts[i], limit)) {
Packit 9c6abc
        if (stride >= 4 || (stride >= 3 && sum == 0)) {
Packit 9c6abc
          uint32_t k;
Packit 9c6abc
          // The stride must end, collapse what we have, if we have enough (4).
Packit 9c6abc
          uint32_t count = (sum + stride / 2) / stride;
Packit 9c6abc
          if (count < 1) {
Packit 9c6abc
            count = 1;
Packit 9c6abc
          }
Packit 9c6abc
          if (sum == 0) {
Packit 9c6abc
            // Don't make an all zeros stride to be upgraded to ones.
Packit 9c6abc
            count = 0;
Packit 9c6abc
          }
Packit 9c6abc
          for (k = 0; k < stride; ++k) {
Packit 9c6abc
            // We don't want to change value at counts[i],
Packit 9c6abc
            // that is already belonging to the next stride. Thus - 1.
Packit 9c6abc
            counts[i - k - 1] = count;
Packit 9c6abc
          }
Packit 9c6abc
        }
Packit 9c6abc
        stride = 0;
Packit 9c6abc
        sum = 0;
Packit 9c6abc
        if (i < length - 3) {
Packit 9c6abc
          // All interesting strides have a count of at least 4,
Packit 9c6abc
          // at least when non-zeros.
Packit 9c6abc
          limit = (counts[i] + counts[i + 1] +
Packit 9c6abc
                   counts[i + 2] + counts[i + 3] + 2) / 4;
Packit 9c6abc
        } else if (i < length) {
Packit 9c6abc
          limit = counts[i];
Packit 9c6abc
        } else {
Packit 9c6abc
          limit = 0;
Packit 9c6abc
        }
Packit 9c6abc
      }
Packit 9c6abc
      ++stride;
Packit 9c6abc
      if (i != length) {
Packit 9c6abc
        sum += counts[i];
Packit 9c6abc
        if (stride >= 4) {
Packit 9c6abc
          limit = (sum + stride / 2) / stride;
Packit 9c6abc
        }
Packit 9c6abc
      }
Packit 9c6abc
    }
Packit 9c6abc
  }
Packit 9c6abc
}
Packit 9c6abc
Packit 9c6abc
// A comparer function for two Huffman trees: sorts first by 'total count'
Packit 9c6abc
// (more comes first), and then by 'value' (more comes first).
Packit 9c6abc
static int CompareHuffmanTrees(const void* ptr1, const void* ptr2) {
Packit 9c6abc
  const HuffmanTree* const t1 = (const HuffmanTree*)ptr1;
Packit 9c6abc
  const HuffmanTree* const t2 = (const HuffmanTree*)ptr2;
Packit 9c6abc
  if (t1->total_count_ > t2->total_count_) {
Packit 9c6abc
    return -1;
Packit 9c6abc
  } else if (t1->total_count_ < t2->total_count_) {
Packit 9c6abc
    return 1;
Packit 9c6abc
  } else {
Packit 9c6abc
    assert(t1->value_ != t2->value_);
Packit 9c6abc
    return (t1->value_ < t2->value_) ? -1 : 1;
Packit 9c6abc
  }
Packit 9c6abc
}
Packit 9c6abc
Packit 9c6abc
static void SetBitDepths(const HuffmanTree* const tree,
Packit 9c6abc
                         const HuffmanTree* const pool,
Packit 9c6abc
                         uint8_t* const bit_depths, int level) {
Packit 9c6abc
  if (tree->pool_index_left_ >= 0) {
Packit 9c6abc
    SetBitDepths(&pool[tree->pool_index_left_], pool, bit_depths, level + 1);
Packit 9c6abc
    SetBitDepths(&pool[tree->pool_index_right_], pool, bit_depths, level + 1);
Packit 9c6abc
  } else {
Packit 9c6abc
    bit_depths[tree->value_] = level;
Packit 9c6abc
  }
Packit 9c6abc
}
Packit 9c6abc
Packit 9c6abc
// Create an optimal Huffman tree.
Packit 9c6abc
//
Packit 9c6abc
// (data,length): population counts.
Packit 9c6abc
// tree_limit: maximum bit depth (inclusive) of the codes.
Packit 9c6abc
// bit_depths[]: how many bits are used for the symbol.
Packit 9c6abc
//
Packit 9c6abc
// Returns 0 when an error has occurred.
Packit 9c6abc
//
Packit 9c6abc
// The catch here is that the tree cannot be arbitrarily deep
Packit 9c6abc
//
Packit 9c6abc
// count_limit is the value that is to be faked as the minimum value
Packit 9c6abc
// and this minimum value is raised until the tree matches the
Packit 9c6abc
// maximum length requirement.
Packit 9c6abc
//
Packit 9c6abc
// This algorithm is not of excellent performance for very long data blocks,
Packit 9c6abc
// especially when population counts are longer than 2**tree_limit, but
Packit 9c6abc
// we are not planning to use this with extremely long blocks.
Packit 9c6abc
//
Packit 9c6abc
// See http://en.wikipedia.org/wiki/Huffman_coding
Packit 9c6abc
static void GenerateOptimalTree(const uint32_t* const histogram,
Packit 9c6abc
                                int histogram_size,
Packit 9c6abc
                                HuffmanTree* tree, int tree_depth_limit,
Packit 9c6abc
                                uint8_t* const bit_depths) {
Packit 9c6abc
  uint32_t count_min;
Packit 9c6abc
  HuffmanTree* tree_pool;
Packit 9c6abc
  int tree_size_orig = 0;
Packit 9c6abc
  int i;
Packit 9c6abc
Packit 9c6abc
  for (i = 0; i < histogram_size; ++i) {
Packit 9c6abc
    if (histogram[i] != 0) {
Packit 9c6abc
      ++tree_size_orig;
Packit 9c6abc
    }
Packit 9c6abc
  }
Packit 9c6abc
Packit 9c6abc
  if (tree_size_orig == 0) {   // pretty optimal already!
Packit 9c6abc
    return;
Packit 9c6abc
  }
Packit 9c6abc
Packit 9c6abc
  tree_pool = tree + tree_size_orig;
Packit 9c6abc
Packit 9c6abc
  // For block sizes with less than 64k symbols we never need to do a
Packit 9c6abc
  // second iteration of this loop.
Packit 9c6abc
  // If we actually start running inside this loop a lot, we would perhaps
Packit 9c6abc
  // be better off with the Katajainen algorithm.
Packit 9c6abc
  assert(tree_size_orig <= (1 << (tree_depth_limit - 1)));
Packit 9c6abc
  for (count_min = 1; ; count_min *= 2) {
Packit 9c6abc
    int tree_size = tree_size_orig;
Packit 9c6abc
    // We need to pack the Huffman tree in tree_depth_limit bits.
Packit 9c6abc
    // So, we try by faking histogram entries to be at least 'count_min'.
Packit 9c6abc
    int idx = 0;
Packit 9c6abc
    int j;
Packit 9c6abc
    for (j = 0; j < histogram_size; ++j) {
Packit 9c6abc
      if (histogram[j] != 0) {
Packit 9c6abc
        const uint32_t count =
Packit 9c6abc
            (histogram[j] < count_min) ? count_min : histogram[j];
Packit 9c6abc
        tree[idx].total_count_ = count;
Packit 9c6abc
        tree[idx].value_ = j;
Packit 9c6abc
        tree[idx].pool_index_left_ = -1;
Packit 9c6abc
        tree[idx].pool_index_right_ = -1;
Packit 9c6abc
        ++idx;
Packit 9c6abc
      }
Packit 9c6abc
    }
Packit 9c6abc
Packit 9c6abc
    // Build the Huffman tree.
Packit 9c6abc
    qsort(tree, tree_size, sizeof(*tree), CompareHuffmanTrees);
Packit 9c6abc
Packit 9c6abc
    if (tree_size > 1) {  // Normal case.
Packit 9c6abc
      int tree_pool_size = 0;
Packit 9c6abc
      while (tree_size > 1) {  // Finish when we have only one root.
Packit 9c6abc
        uint32_t count;
Packit 9c6abc
        tree_pool[tree_pool_size++] = tree[tree_size - 1];
Packit 9c6abc
        tree_pool[tree_pool_size++] = tree[tree_size - 2];
Packit 9c6abc
        count = tree_pool[tree_pool_size - 1].total_count_ +
Packit 9c6abc
                tree_pool[tree_pool_size - 2].total_count_;
Packit 9c6abc
        tree_size -= 2;
Packit 9c6abc
        {
Packit 9c6abc
          // Search for the insertion point.
Packit 9c6abc
          int k;
Packit 9c6abc
          for (k = 0; k < tree_size; ++k) {
Packit 9c6abc
            if (tree[k].total_count_ <= count) {
Packit 9c6abc
              break;
Packit 9c6abc
            }
Packit 9c6abc
          }
Packit 9c6abc
          memmove(tree + (k + 1), tree + k, (tree_size - k) * sizeof(*tree));
Packit 9c6abc
          tree[k].total_count_ = count;
Packit 9c6abc
          tree[k].value_ = -1;
Packit 9c6abc
Packit 9c6abc
          tree[k].pool_index_left_ = tree_pool_size - 1;
Packit 9c6abc
          tree[k].pool_index_right_ = tree_pool_size - 2;
Packit 9c6abc
          tree_size = tree_size + 1;
Packit 9c6abc
        }
Packit 9c6abc
      }
Packit 9c6abc
      SetBitDepths(&tree[0], tree_pool, bit_depths, 0);
Packit 9c6abc
    } else if (tree_size == 1) {  // Trivial case: only one element.
Packit 9c6abc
      bit_depths[tree[0].value_] = 1;
Packit 9c6abc
    }
Packit 9c6abc
Packit 9c6abc
    {
Packit 9c6abc
      // Test if this Huffman tree satisfies our 'tree_depth_limit' criteria.
Packit 9c6abc
      int max_depth = bit_depths[0];
Packit 9c6abc
      for (j = 1; j < histogram_size; ++j) {
Packit 9c6abc
        if (max_depth < bit_depths[j]) {
Packit 9c6abc
          max_depth = bit_depths[j];
Packit 9c6abc
        }
Packit 9c6abc
      }
Packit 9c6abc
      if (max_depth <= tree_depth_limit) {
Packit 9c6abc
        break;
Packit 9c6abc
      }
Packit 9c6abc
    }
Packit 9c6abc
  }
Packit 9c6abc
}
Packit 9c6abc
Packit 9c6abc
// -----------------------------------------------------------------------------
Packit 9c6abc
// Coding of the Huffman tree values
Packit 9c6abc
Packit 9c6abc
static HuffmanTreeToken* CodeRepeatedValues(int repetitions,
Packit 9c6abc
                                            HuffmanTreeToken* tokens,
Packit 9c6abc
                                            int value, int prev_value) {
Packit 9c6abc
  assert(value <= MAX_ALLOWED_CODE_LENGTH);
Packit 9c6abc
  if (value != prev_value) {
Packit 9c6abc
    tokens->code = value;
Packit 9c6abc
    tokens->extra_bits = 0;
Packit 9c6abc
    ++tokens;
Packit 9c6abc
    --repetitions;
Packit 9c6abc
  }
Packit 9c6abc
  while (repetitions >= 1) {
Packit 9c6abc
    if (repetitions < 3) {
Packit 9c6abc
      int i;
Packit 9c6abc
      for (i = 0; i < repetitions; ++i) {
Packit 9c6abc
        tokens->code = value;
Packit 9c6abc
        tokens->extra_bits = 0;
Packit 9c6abc
        ++tokens;
Packit 9c6abc
      }
Packit 9c6abc
      break;
Packit 9c6abc
    } else if (repetitions < 7) {
Packit 9c6abc
      tokens->code = 16;
Packit 9c6abc
      tokens->extra_bits = repetitions - 3;
Packit 9c6abc
      ++tokens;
Packit 9c6abc
      break;
Packit 9c6abc
    } else {
Packit 9c6abc
      tokens->code = 16;
Packit 9c6abc
      tokens->extra_bits = 3;
Packit 9c6abc
      ++tokens;
Packit 9c6abc
      repetitions -= 6;
Packit 9c6abc
    }
Packit 9c6abc
  }
Packit 9c6abc
  return tokens;
Packit 9c6abc
}
Packit 9c6abc
Packit 9c6abc
static HuffmanTreeToken* CodeRepeatedZeros(int repetitions,
Packit 9c6abc
                                           HuffmanTreeToken* tokens) {
Packit 9c6abc
  while (repetitions >= 1) {
Packit 9c6abc
    if (repetitions < 3) {
Packit 9c6abc
      int i;
Packit 9c6abc
      for (i = 0; i < repetitions; ++i) {
Packit 9c6abc
        tokens->code = 0;   // 0-value
Packit 9c6abc
        tokens->extra_bits = 0;
Packit 9c6abc
        ++tokens;
Packit 9c6abc
      }
Packit 9c6abc
      break;
Packit 9c6abc
    } else if (repetitions < 11) {
Packit 9c6abc
      tokens->code = 17;
Packit 9c6abc
      tokens->extra_bits = repetitions - 3;
Packit 9c6abc
      ++tokens;
Packit 9c6abc
      break;
Packit 9c6abc
    } else if (repetitions < 139) {
Packit 9c6abc
      tokens->code = 18;
Packit 9c6abc
      tokens->extra_bits = repetitions - 11;
Packit 9c6abc
      ++tokens;
Packit 9c6abc
      break;
Packit 9c6abc
    } else {
Packit 9c6abc
      tokens->code = 18;
Packit 9c6abc
      tokens->extra_bits = 0x7f;  // 138 repeated 0s
Packit 9c6abc
      ++tokens;
Packit 9c6abc
      repetitions -= 138;
Packit 9c6abc
    }
Packit 9c6abc
  }
Packit 9c6abc
  return tokens;
Packit 9c6abc
}
Packit 9c6abc
Packit 9c6abc
int VP8LCreateCompressedHuffmanTree(const HuffmanTreeCode* const tree,
Packit 9c6abc
                                    HuffmanTreeToken* tokens, int max_tokens) {
Packit 9c6abc
  HuffmanTreeToken* const starting_token = tokens;
Packit 9c6abc
  HuffmanTreeToken* const ending_token = tokens + max_tokens;
Packit 9c6abc
  const int depth_size = tree->num_symbols;
Packit 9c6abc
  int prev_value = 8;  // 8 is the initial value for rle.
Packit 9c6abc
  int i = 0;
Packit 9c6abc
  assert(tokens != NULL);
Packit 9c6abc
  while (i < depth_size) {
Packit 9c6abc
    const int value = tree->code_lengths[i];
Packit 9c6abc
    int k = i + 1;
Packit 9c6abc
    int runs;
Packit 9c6abc
    while (k < depth_size && tree->code_lengths[k] == value) ++k;
Packit 9c6abc
    runs = k - i;
Packit 9c6abc
    if (value == 0) {
Packit 9c6abc
      tokens = CodeRepeatedZeros(runs, tokens);
Packit 9c6abc
    } else {
Packit 9c6abc
      tokens = CodeRepeatedValues(runs, tokens, value, prev_value);
Packit 9c6abc
      prev_value = value;
Packit 9c6abc
    }
Packit 9c6abc
    i += runs;
Packit 9c6abc
    assert(tokens <= ending_token);
Packit 9c6abc
  }
Packit 9c6abc
  (void)ending_token;    // suppress 'unused variable' warning
Packit 9c6abc
  return (int)(tokens - starting_token);
Packit 9c6abc
}
Packit 9c6abc
Packit 9c6abc
// -----------------------------------------------------------------------------
Packit 9c6abc
Packit 9c6abc
// Pre-reversed 4-bit values.
Packit 9c6abc
static const uint8_t kReversedBits[16] = {
Packit 9c6abc
  0x0, 0x8, 0x4, 0xc, 0x2, 0xa, 0x6, 0xe,
Packit 9c6abc
  0x1, 0x9, 0x5, 0xd, 0x3, 0xb, 0x7, 0xf
Packit 9c6abc
};
Packit 9c6abc
Packit 9c6abc
static uint32_t ReverseBits(int num_bits, uint32_t bits) {
Packit 9c6abc
  uint32_t retval = 0;
Packit 9c6abc
  int i = 0;
Packit 9c6abc
  while (i < num_bits) {
Packit 9c6abc
    i += 4;
Packit 9c6abc
    retval |= kReversedBits[bits & 0xf] << (MAX_ALLOWED_CODE_LENGTH + 1 - i);
Packit 9c6abc
    bits >>= 4;
Packit 9c6abc
  }
Packit 9c6abc
  retval >>= (MAX_ALLOWED_CODE_LENGTH + 1 - num_bits);
Packit 9c6abc
  return retval;
Packit 9c6abc
}
Packit 9c6abc
Packit 9c6abc
// Get the actual bit values for a tree of bit depths.
Packit 9c6abc
static void ConvertBitDepthsToSymbols(HuffmanTreeCode* const tree) {
Packit 9c6abc
  // 0 bit-depth means that the symbol does not exist.
Packit 9c6abc
  int i;
Packit 9c6abc
  int len;
Packit 9c6abc
  uint32_t next_code[MAX_ALLOWED_CODE_LENGTH + 1];
Packit 9c6abc
  int depth_count[MAX_ALLOWED_CODE_LENGTH + 1] = { 0 };
Packit 9c6abc
Packit 9c6abc
  assert(tree != NULL);
Packit 9c6abc
  len = tree->num_symbols;
Packit 9c6abc
  for (i = 0; i < len; ++i) {
Packit 9c6abc
    const int code_length = tree->code_lengths[i];
Packit 9c6abc
    assert(code_length <= MAX_ALLOWED_CODE_LENGTH);
Packit 9c6abc
    ++depth_count[code_length];
Packit 9c6abc
  }
Packit 9c6abc
  depth_count[0] = 0;  // ignore unused symbol
Packit 9c6abc
  next_code[0] = 0;
Packit 9c6abc
  {
Packit 9c6abc
    uint32_t code = 0;
Packit 9c6abc
    for (i = 1; i <= MAX_ALLOWED_CODE_LENGTH; ++i) {
Packit 9c6abc
      code = (code + depth_count[i - 1]) << 1;
Packit 9c6abc
      next_code[i] = code;
Packit 9c6abc
    }
Packit 9c6abc
  }
Packit 9c6abc
  for (i = 0; i < len; ++i) {
Packit 9c6abc
    const int code_length = tree->code_lengths[i];
Packit 9c6abc
    tree->codes[i] = ReverseBits(code_length, next_code[code_length]++);
Packit 9c6abc
  }
Packit 9c6abc
}
Packit 9c6abc
Packit 9c6abc
// -----------------------------------------------------------------------------
Packit 9c6abc
// Main entry point
Packit 9c6abc
Packit 9c6abc
void VP8LCreateHuffmanTree(uint32_t* const histogram, int tree_depth_limit,
Packit 9c6abc
                           uint8_t* const buf_rle,
Packit 9c6abc
                           HuffmanTree* const huff_tree,
Packit 9c6abc
                           HuffmanTreeCode* const huff_code) {
Packit 9c6abc
  const int num_symbols = huff_code->num_symbols;
Packit 9c6abc
  memset(buf_rle, 0, num_symbols * sizeof(*buf_rle));
Packit 9c6abc
  OptimizeHuffmanForRle(num_symbols, buf_rle, histogram);
Packit 9c6abc
  GenerateOptimalTree(histogram, num_symbols, huff_tree, tree_depth_limit,
Packit 9c6abc
                      huff_code->code_lengths);
Packit 9c6abc
  // Create the actual bit codes for the bit lengths.
Packit 9c6abc
  ConvertBitDepthsToSymbols(huff_code);
Packit 9c6abc
}