179e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka// Copyright 2013 Google Inc. All Rights Reserved.
279e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka//
379e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka// Licensed under the Apache License, Version 2.0 (the "License");
479e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka// you may not use this file except in compliance with the License.
579e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka// You may obtain a copy of the License at
679e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka//
779e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka// http://www.apache.org/licenses/LICENSE-2.0
879e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka//
979e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka// Unless required by applicable law or agreed to in writing, software
1079e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka// distributed under the License is distributed on an "AS IS" BASIS,
1179e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1279e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka// See the License for the specific language governing permissions and
1379e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka// limitations under the License.
1479e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka//
1579e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka// Utilities for fast computation of logarithms.
1679e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka
1779e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka#ifndef BROTLI_ENC_FAST_LOG_H_
1879e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka#define BROTLI_ENC_FAST_LOG_H_
1979e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka
2079e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka#include <math.h>
2179e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka#include <stdint.h>
2279e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka
2379e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadkanamespace brotli {
2479e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka
2579e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka// Return floor(log2(n)) for positive integer n.  Returns -1 iff n == 0.
2679e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadkainline int Log2Floor(uint32_t n) {
2779e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka#if defined(__clang__) ||                       \
2879e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka  (defined(__GNUC__) &&                                         \
2979e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka   ((__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || __GNUC__ >= 4))
3079e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka  return n == 0 ? -1 : 31 ^ __builtin_clz(n);
3179e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka#else
3279e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka  if (n == 0)
3379e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka    return -1;
3479e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka  int log = 0;
3579e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka  uint32_t value = n;
3679e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka  for (int i = 4; i >= 0; --i) {
3779e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka    int shift = (1 << i);
3879e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka    uint32_t x = value >> shift;
3979e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka    if (x != 0) {
4079e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka      value = x;
4179e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka      log += shift;
4279e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka    }
4379e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka  }
4479e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka  assert(value == 1);
4579e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka  return log;
4679e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka#endif
4779e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka}
4879e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka
4979e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka// Return ceiling(log2(n)) for positive integer n.  Returns -1 iff n == 0.
5079e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadkainline int Log2Ceiling(uint32_t n) {
5179e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka  int floor = Log2Floor(n);
5279e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka  if (n == (n &~ (n - 1)))              // zero or a power of two
5379e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka    return floor;
5479e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka  else
5579e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka    return floor + 1;
5679e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka}
5779e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka
5879e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka// A lookup table for small values of log2(int) to be used in entropy
5979e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka// computation.
6079e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka//
6179e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka// ", ".join(["%.16ff" % x for x in [0.0]+[log2(x) for x in range(1, 256)]])
6279e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadkastatic const float kLog2Table[] = {
6379e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka  0.0000000000000000f, 0.0000000000000000f, 1.0000000000000000f,
6479e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka  1.5849625007211563f, 2.0000000000000000f, 2.3219280948873622f,
6579e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka  2.5849625007211561f, 2.8073549220576042f, 3.0000000000000000f,
6679e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka  3.1699250014423126f, 3.3219280948873626f, 3.4594316186372978f,
6779e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka  3.5849625007211565f, 3.7004397181410922f, 3.8073549220576037f,
6879e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka  3.9068905956085187f, 4.0000000000000000f, 4.0874628412503400f,
6979e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka  4.1699250014423122f, 4.2479275134435852f, 4.3219280948873626f,
7079e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka  4.3923174227787607f, 4.4594316186372973f, 4.5235619560570131f,
7179e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka  4.5849625007211570f, 4.6438561897747244f, 4.7004397181410926f,
7279e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka  4.7548875021634691f, 4.8073549220576037f, 4.8579809951275728f,
7379e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka  4.9068905956085187f, 4.9541963103868758f, 5.0000000000000000f,
7479e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka  5.0443941193584534f, 5.0874628412503400f, 5.1292830169449664f,
7579e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka  5.1699250014423122f, 5.2094533656289501f, 5.2479275134435852f,
7679e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka  5.2854022188622487f, 5.3219280948873626f, 5.3575520046180838f,
7779e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka  5.3923174227787607f, 5.4262647547020979f, 5.4594316186372973f,
7879e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka  5.4918530963296748f, 5.5235619560570131f, 5.5545888516776376f,
7979e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka  5.5849625007211570f, 5.6147098441152083f, 5.6438561897747244f,
8079e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka  5.6724253419714961f, 5.7004397181410926f, 5.7279204545631996f,
8179e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka  5.7548875021634691f, 5.7813597135246599f, 5.8073549220576046f,
8279e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka  5.8328900141647422f, 5.8579809951275719f, 5.8826430493618416f,
8379e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka  5.9068905956085187f, 5.9307373375628867f, 5.9541963103868758f,
8479e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka  5.9772799234999168f, 6.0000000000000000f, 6.0223678130284544f,
8579e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka  6.0443941193584534f, 6.0660891904577721f, 6.0874628412503400f,
8679e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka  6.1085244567781700f, 6.1292830169449672f, 6.1497471195046822f,
8779e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka  6.1699250014423122f, 6.1898245588800176f, 6.2094533656289510f,
8879e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka  6.2288186904958804f, 6.2479275134435861f, 6.2667865406949019f,
8979e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka  6.2854022188622487f, 6.3037807481771031f, 6.3219280948873617f,
9079e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka  6.3398500028846252f, 6.3575520046180847f, 6.3750394313469254f,
9179e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka  6.3923174227787598f, 6.4093909361377026f, 6.4262647547020979f,
9279e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka  6.4429434958487288f, 6.4594316186372982f, 6.4757334309663976f,
9379e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka  6.4918530963296748f, 6.5077946401986964f, 6.5235619560570131f,
9479e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka  6.5391588111080319f, 6.5545888516776376f, 6.5698556083309478f,
9579e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka  6.5849625007211561f, 6.5999128421871278f, 6.6147098441152092f,
9679e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka  6.6293566200796095f, 6.6438561897747253f, 6.6582114827517955f,
9779e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka  6.6724253419714952f, 6.6865005271832185f, 6.7004397181410917f,
9879e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka  6.7142455176661224f, 6.7279204545631988f, 6.7414669864011465f,
9979e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka  6.7548875021634691f, 6.7681843247769260f, 6.7813597135246599f,
10079e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka  6.7944158663501062f, 6.8073549220576037f, 6.8201789624151887f,
10179e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka  6.8328900141647422f, 6.8454900509443757f, 6.8579809951275719f,
10279e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka  6.8703647195834048f, 6.8826430493618416f, 6.8948177633079437f,
10379e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka  6.9068905956085187f, 6.9188632372745955f, 6.9307373375628867f,
10479e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka  6.9425145053392399f, 6.9541963103868758f, 6.9657842846620879f,
10579e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka  6.9772799234999168f, 6.9886846867721664f, 7.0000000000000000f,
10679e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka  7.0112272554232540f, 7.0223678130284544f, 7.0334230015374501f,
10779e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka  7.0443941193584534f, 7.0552824355011898f, 7.0660891904577721f,
10879e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka  7.0768155970508317f, 7.0874628412503400f, 7.0980320829605272f,
10979e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka  7.1085244567781700f, 7.1189410727235076f, 7.1292830169449664f,
11079e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka  7.1395513523987937f, 7.1497471195046822f, 7.1598713367783891f,
11179e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka  7.1699250014423130f, 7.1799090900149345f, 7.1898245588800176f,
11279e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka  7.1996723448363644f, 7.2094533656289492f, 7.2191685204621621f,
11379e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka  7.2288186904958804f, 7.2384047393250794f, 7.2479275134435861f,
11479e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka  7.2573878426926521f, 7.2667865406949019f, 7.2761244052742384f,
11579e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka  7.2854022188622487f, 7.2946207488916270f, 7.3037807481771031f,
11679e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka  7.3128829552843557f, 7.3219280948873617f, 7.3309168781146177f,
11779e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka  7.3398500028846243f, 7.3487281542310781f, 7.3575520046180847f,
11879e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka  7.3663222142458151f, 7.3750394313469254f, 7.3837042924740528f,
11979e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka  7.3923174227787607f, 7.4008794362821844f, 7.4093909361377026f,
12079e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka  7.4178525148858991f, 7.4262647547020979f, 7.4346282276367255f,
12179e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka  7.4429434958487288f, 7.4512111118323299f, 7.4594316186372973f,
12279e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka  7.4676055500829976f, 7.4757334309663976f, 7.4838157772642564f,
12379e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka  7.4918530963296748f, 7.4998458870832057f, 7.5077946401986964f,
12479e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka  7.5156998382840436f, 7.5235619560570131f, 7.5313814605163119f,
12579e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka  7.5391588111080319f, 7.5468944598876373f, 7.5545888516776376f,
12679e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka  7.5622424242210728f, 7.5698556083309478f, 7.5774288280357487f,
12779e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka  7.5849625007211561f, 7.5924570372680806f, 7.5999128421871278f,
12879e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka  7.6073303137496113f, 7.6147098441152075f, 7.6220518194563764f,
12979e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka  7.6293566200796095f, 7.6366246205436488f, 7.6438561897747244f,
13079e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka  7.6510516911789290f, 7.6582114827517955f, 7.6653359171851765f,
13179e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka  7.6724253419714952f, 7.6794800995054464f, 7.6865005271832185f,
13279e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka  7.6934869574993252f, 7.7004397181410926f, 7.7073591320808825f,
13379e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka  7.7142455176661224f, 7.7210991887071856f, 7.7279204545631996f,
13479e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka  7.7347096202258392f, 7.7414669864011465f, 7.7481928495894596f,
13579e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka  7.7548875021634691f, 7.7615512324444795f, 7.7681843247769260f,
13679e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka  7.7747870596011737f, 7.7813597135246608f, 7.7879025593914317f,
13779e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka  7.7944158663501062f, 7.8008998999203047f, 7.8073549220576037f,
13879e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka  7.8137811912170374f, 7.8201789624151887f, 7.8265484872909159f,
13979e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka  7.8328900141647422f, 7.8392037880969445f, 7.8454900509443757f,
14079e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka  7.8517490414160571f, 7.8579809951275719f, 7.8641861446542798f,
14179e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka  7.8703647195834048f, 7.8765169465650002f, 7.8826430493618425f,
14279e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka  7.8887432488982601f, 7.8948177633079446f, 7.9008668079807496f,
14379e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka  7.9068905956085187f, 7.9128893362299619f, 7.9188632372745955f,
14479e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka  7.9248125036057813f, 7.9307373375628867f, 7.9366379390025719f,
14579e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka  7.9425145053392399f, 7.9483672315846778f, 7.9541963103868758f,
14679e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka  7.9600019320680806f, 7.9657842846620870f, 7.9715435539507720f,
14779e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka  7.9772799234999168f, 7.9829935746943104f, 7.9886846867721664f,
14879e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka  7.9943534368588578f
14979e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka};
15079e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka
15179e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka// Faster logarithm for small integers, with the property of log2(0) == 0.
15279e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadkastatic inline double FastLog2(int v) {
15379e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka  if (v < (int)(sizeof(kLog2Table) / sizeof(kLog2Table[0]))) {
15479e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka    return kLog2Table[v];
15579e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka  }
15679e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka  return log2(v);
15779e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka}
15879e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka
15979e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka}  // namespace brotli
16079e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka
16179e99afe468407e9ff9f0820df7190cb069eabebZoltan Szabadka#endif  // BROTLI_ENC_FAST_LOG_H_
162