Coverage Report

Created: 2025-07-18 06:08

/src/brunsli/c/common/distributions.h
Line
Count
Source
1
// Copyright (c) Google LLC 2019
2
//
3
// Use of this source code is governed by an MIT-style
4
// license that can be found in the LICENSE file or at
5
// https://opensource.org/licenses/MIT.
6
7
// Library of cumulative distribution functions that can be used for arithmetic
8
// coding. For the semantics of these classes, see the comment on EncodeSymbol()
9
// in //third_party/brunsli/enc/arith_encode.h
10
11
#ifndef BRUNSLI_COMMON_DISTRIBUTIONS_H_
12
#define BRUNSLI_COMMON_DISTRIBUTIONS_H_
13
14
#include "./platform.h"
15
#include <brunsli/types.h>
16
17
namespace brunsli {
18
19
namespace impl {
20
21
static const uint8_t kNormalizeThreshold = 254;
22
23
/* Fixed point division lookup table. Python snippet to generate it:
24
 * [0, 0, 0] + [((1 << 17)) / x for x in range(3, 255)]
25
 */
26
static const uint16_t kDivLut17[kNormalizeThreshold + 1] = {
27
    0,     0,     0,     43690, 32768, 26214, 21845, 18724, 16384, 14563, 13107,
28
    11915, 10922, 10082, 9362,  8738,  8192,  7710,  7281,  6898,  6553,  6241,
29
    5957,  5698,  5461,  5242,  5041,  4854,  4681,  4519,  4369,  4228,  4096,
30
    3971,  3855,  3744,  3640,  3542,  3449,  3360,  3276,  3196,  3120,  3048,
31
    2978,  2912,  2849,  2788,  2730,  2674,  2621,  2570,  2520,  2473,  2427,
32
    2383,  2340,  2299,  2259,  2221,  2184,  2148,  2114,  2080,  2048,  2016,
33
    1985,  1956,  1927,  1899,  1872,  1846,  1820,  1795,  1771,  1747,  1724,
34
    1702,  1680,  1659,  1638,  1618,  1598,  1579,  1560,  1542,  1524,  1506,
35
    1489,  1472,  1456,  1440,  1424,  1409,  1394,  1379,  1365,  1351,  1337,
36
    1323,  1310,  1297,  1285,  1272,  1260,  1248,  1236,  1224,  1213,  1202,
37
    1191,  1180,  1170,  1159,  1149,  1139,  1129,  1120,  1110,  1101,  1092,
38
    1083,  1074,  1065,  1057,  1048,  1040,  1032,  1024,  1016,  1008,  1000,
39
    992,   985,   978,   970,   963,   956,   949,   942,   936,   929,   923,
40
    916,   910,   903,   897,   891,   885,   879,   873,   868,   862,   856,
41
    851,   845,   840,   834,   829,   824,   819,   814,   809,   804,   799,
42
    794,   789,   784,   780,   775,   771,   766,   762,   757,   753,   748,
43
    744,   740,   736,   732,   728,   724,   720,   716,   712,   708,   704,
44
    700,   697,   693,   689,   686,   682,   679,   675,   672,   668,   665,
45
    661,   658,   655,   652,   648,   645,   642,   639,   636,   633,   630,
46
    627,   624,   621,   618,   615,   612,   609,   606,   604,   601,   598,
47
    595,   593,   590,   587,   585,   582,   579,   577,   574,   572,   569,
48
    567,   564,   562,   560,   557,   555,   553,   550,   548,   546,   543,
49
    541,   539,   537,   534,   532,   530,   528,   526,   524,   522,   520,
50
    518,   516};
51
52
static BRUNSLI_INLINE uint8_t FastDivide(uint32_t numerator,
53
149M
                                         uint8_t denominator) {
54
149M
  uint32_t result = (numerator * kDivLut17[denominator]) >> 17;
55
149M
  BRUNSLI_DCHECK(result < 256);
56
149M
  return static_cast<uint8_t>(result);
57
149M
}
brunsli_decode.cc:brunsli::impl::FastDivide(unsigned int, unsigned char)
Line
Count
Source
53
149M
                                         uint8_t denominator) {
54
149M
  uint32_t result = (numerator * kDivLut17[denominator]) >> 17;
55
149M
  BRUNSLI_DCHECK(result < 256);
56
149M
  return static_cast<uint8_t>(result);
57
149M
}
Unexecuted instantiation: jpeg_data_writer.cc:brunsli::impl::FastDivide(unsigned int, unsigned char)
Unexecuted instantiation: state.cc:brunsli::impl::FastDivide(unsigned int, unsigned char)
Unexecuted instantiation: context.cc:brunsli::impl::FastDivide(unsigned int, unsigned char)
58
59
static const uint8_t kInitProb = 134;
60
static const uint8_t kInitProbCount = 3;
61
62
}  // namespace impl
63
64
// An adaptive binary distribution with 8-bit precision.
65
class Prob {
66
 public:
67
51.8M
  Prob(): prob8(impl::kInitProb),
68
51.8M
        total(impl::kInitProbCount),
69
51.8M
        count(impl::kInitProb * impl::kInitProbCount) {}
70
51.8M
  ~Prob() {}
71
72
51.8M
  void Init(uint8_t probability) {
73
51.8M
    prob8 = probability;
74
51.8M
    total = impl::kInitProbCount;
75
51.8M
    count = impl::kInitProbCount * probability;
76
51.8M
  }
77
78
149M
  void Add(int val) {
79
149M
    ++total;
80
149M
    if (val == 0) {
81
92.2M
      count += 256;
82
92.2M
    } else {
83
57.3M
      ++count;
84
57.3M
    }
85
149M
    prob8 = impl::FastDivide(count, total);
86
149M
    if (total == impl::kNormalizeThreshold) {
87
1.10M
      count >>= 1;
88
1.10M
      total = impl::kNormalizeThreshold >> 1;
89
1.10M
    }
90
149M
  }
91
92
149M
  uint8_t get_proba() const { return prob8; }
93
94
 private:
95
  /* It is important to keep this structure small: more than 3K instances are
96
   * used by encoder and decoder. */
97
  uint8_t prob8;
98
  uint8_t total;
99
  uint16_t count;
100
};
101
102
}  // namespace brunsli
103
104
#endif  // BRUNSLI_COMMON_DISTRIBUTIONS_H_