Coverage Report

Created: 2026-06-10 06:56

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/brunsli/c/dec/bit_reader.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
/* Bit reading helpers */
8
9
#ifndef BRUNSLI_DEC_BIT_READER_H_
10
#define BRUNSLI_DEC_BIT_READER_H_
11
12
#include "../common/platform.h"
13
#include <brunsli/types.h>
14
15
namespace brunsli {
16
17
struct BrunsliBitReader {
18
  const uint8_t* next_;
19
  const uint8_t* end_;
20
  uint32_t num_bits_;
21
  uint32_t bits_;
22
  /*
23
     Number of "virtual" zero bytes located after the end of buffer being
24
     put into the bit buffer.
25
26
     The concept of debt is useful for two purposes:
27
      - postpone handling of "unexpected end of input"
28
      - allow efficient peeking of input near the end
29
30
     It is OK to have debt, while "balance" is non-negative.
31
     BrunsliBitReaderUnload returns debt, if possible.
32
   */
33
  uint32_t num_debt_bytes_;
34
  bool is_healthy_;
35
  bool is_optimistic_;
36
};
37
38
/**
39
 * Prepare instance.
40
 *
41
 * The instance lifecycle looks like:
42
 *  - Init
43
 *  - Resume
44
 *  - (read bits)
45
 *  - Suspend
46
 *  - (optionally, go back to Resume stage)
47
 *  - Finish
48
 */
49
void BrunsliBitReaderInit(BrunsliBitReader* br);
50
/**
51
 * Supply instance with new chunk of input.
52
 */
53
void BrunsliBitReaderResume(BrunsliBitReader* br, const uint8_t* buffer,
54
                          size_t length);
55
/**
56
 * Returns the number of unused bytes.
57
 */
58
size_t BrunsliBitReaderSuspend(BrunsliBitReader* br);
59
/**
60
 * Drops unused bits of the last used byte.
61
 *
62
 * Marks instance as unhealthy, if unused bits are not all 0.
63
 */
64
void BrunsliBitReaderFinish(BrunsliBitReader* br);
65
66
bool BrunsliBitReaderIsHealthy(BrunsliBitReader* br);
67
68
5.25M
static BRUNSLI_INLINE uint32_t BrunsliBitReaderBitMask(uint32_t n) {
69
5.25M
  return ~((0xFFFFFFFFu) << n);
70
5.25M
}
brunsli_decode.cc:brunsli::BrunsliBitReaderBitMask(unsigned int)
Line
Count
Source
68
3.88M
static BRUNSLI_INLINE uint32_t BrunsliBitReaderBitMask(uint32_t n) {
69
3.88M
  return ~((0xFFFFFFFFu) << n);
70
3.88M
}
context_map_decode.cc:brunsli::BrunsliBitReaderBitMask(unsigned int)
Line
Count
Source
68
16.5k
static BRUNSLI_INLINE uint32_t BrunsliBitReaderBitMask(uint32_t n) {
69
16.5k
  return ~((0xFFFFFFFFu) << n);
70
16.5k
}
histogram_decode.cc:brunsli::BrunsliBitReaderBitMask(unsigned int)
Line
Count
Source
68
114k
static BRUNSLI_INLINE uint32_t BrunsliBitReaderBitMask(uint32_t n) {
69
114k
  return ~((0xFFFFFFFFu) << n);
70
114k
}
huffman_decode.cc:brunsli::BrunsliBitReaderBitMask(unsigned int)
Line
Count
Source
68
1.15M
static BRUNSLI_INLINE uint32_t BrunsliBitReaderBitMask(uint32_t n) {
69
1.15M
  return ~((0xFFFFFFFFu) << n);
70
1.15M
}
Unexecuted instantiation: jpeg_data_writer.cc:brunsli::BrunsliBitReaderBitMask(unsigned int)
Unexecuted instantiation: state.cc:brunsli::BrunsliBitReaderBitMask(unsigned int)
bit_reader.cc:brunsli::BrunsliBitReaderBitMask(unsigned int)
Line
Count
Source
68
84.5k
static BRUNSLI_INLINE uint32_t BrunsliBitReaderBitMask(uint32_t n) {
69
84.5k
  return ~((0xFFFFFFFFu) << n);
70
84.5k
}
71
72
/* Internal. */
73
99.3k
static BRUNSLI_INLINE void BrunsliBitReaderOweByte(BrunsliBitReader* br) {
74
99.3k
  br->num_bits_ += 8;
75
99.3k
  br->num_debt_bytes_++;
76
99.3k
}
brunsli_decode.cc:brunsli::BrunsliBitReaderOweByte(brunsli::BrunsliBitReader*)
Line
Count
Source
73
28
static BRUNSLI_INLINE void BrunsliBitReaderOweByte(BrunsliBitReader* br) {
74
28
  br->num_bits_ += 8;
75
28
  br->num_debt_bytes_++;
76
28
}
context_map_decode.cc:brunsli::BrunsliBitReaderOweByte(brunsli::BrunsliBitReader*)
Line
Count
Source
73
447
static BRUNSLI_INLINE void BrunsliBitReaderOweByte(BrunsliBitReader* br) {
74
447
  br->num_bits_ += 8;
75
447
  br->num_debt_bytes_++;
76
447
}
histogram_decode.cc:brunsli::BrunsliBitReaderOweByte(brunsli::BrunsliBitReader*)
Line
Count
Source
73
751
static BRUNSLI_INLINE void BrunsliBitReaderOweByte(BrunsliBitReader* br) {
74
751
  br->num_bits_ += 8;
75
751
  br->num_debt_bytes_++;
76
751
}
huffman_decode.cc:brunsli::BrunsliBitReaderOweByte(brunsli::BrunsliBitReader*)
Line
Count
Source
73
98.0k
static BRUNSLI_INLINE void BrunsliBitReaderOweByte(BrunsliBitReader* br) {
74
98.0k
  br->num_bits_ += 8;
75
98.0k
  br->num_debt_bytes_++;
76
98.0k
}
Unexecuted instantiation: jpeg_data_writer.cc:brunsli::BrunsliBitReaderOweByte(brunsli::BrunsliBitReader*)
Unexecuted instantiation: state.cc:brunsli::BrunsliBitReaderOweByte(brunsli::BrunsliBitReader*)
Unexecuted instantiation: bit_reader.cc:brunsli::BrunsliBitReaderOweByte(brunsli::BrunsliBitReader*)
77
78
/* Internal. */
79
static BRUNSLI_INLINE void BrunsliBitReaderMaybeFetchByte(BrunsliBitReader* br,
80
5.18M
                                                          uint32_t n_bits) {
81
5.18M
  if (br->num_bits_ < n_bits) {
82
2.27M
    if (BRUNSLI_PREDICT_FALSE(br->next_ >= br->end_)) {
83
99.3k
      BrunsliBitReaderOweByte(br);
84
2.17M
    } else {
85
2.17M
      br->bits_ |= static_cast<uint32_t>(*br->next_) << br->num_bits_;
86
2.17M
      br->num_bits_ += 8;
87
2.17M
      br->next_++;
88
2.17M
    }
89
2.27M
  }
90
5.18M
}
brunsli_decode.cc:brunsli::BrunsliBitReaderMaybeFetchByte(brunsli::BrunsliBitReader*, unsigned int)
Line
Count
Source
80
3.88M
                                                          uint32_t n_bits) {
81
3.88M
  if (br->num_bits_ < n_bits) {
82
2.13M
    if (BRUNSLI_PREDICT_FALSE(br->next_ >= br->end_)) {
83
28
      BrunsliBitReaderOweByte(br);
84
2.13M
    } else {
85
2.13M
      br->bits_ |= static_cast<uint32_t>(*br->next_) << br->num_bits_;
86
2.13M
      br->num_bits_ += 8;
87
2.13M
      br->next_++;
88
2.13M
    }
89
2.13M
  }
90
3.88M
}
context_map_decode.cc:brunsli::BrunsliBitReaderMaybeFetchByte(brunsli::BrunsliBitReader*, unsigned int)
Line
Count
Source
80
16.6k
                                                          uint32_t n_bits) {
81
16.6k
  if (br->num_bits_ < n_bits) {
82
769
    if (BRUNSLI_PREDICT_FALSE(br->next_ >= br->end_)) {
83
447
      BrunsliBitReaderOweByte(br);
84
447
    } else {
85
322
      br->bits_ |= static_cast<uint32_t>(*br->next_) << br->num_bits_;
86
322
      br->num_bits_ += 8;
87
322
      br->next_++;
88
322
    }
89
769
  }
90
16.6k
}
histogram_decode.cc:brunsli::BrunsliBitReaderMaybeFetchByte(brunsli::BrunsliBitReader*, unsigned int)
Line
Count
Source
80
117k
                                                          uint32_t n_bits) {
81
117k
  if (br->num_bits_ < n_bits) {
82
26.8k
    if (BRUNSLI_PREDICT_FALSE(br->next_ >= br->end_)) {
83
751
      BrunsliBitReaderOweByte(br);
84
26.1k
    } else {
85
26.1k
      br->bits_ |= static_cast<uint32_t>(*br->next_) << br->num_bits_;
86
26.1k
      br->num_bits_ += 8;
87
26.1k
      br->next_++;
88
26.1k
    }
89
26.8k
  }
90
117k
}
huffman_decode.cc:brunsli::BrunsliBitReaderMaybeFetchByte(brunsli::BrunsliBitReader*, unsigned int)
Line
Count
Source
80
1.15M
                                                          uint32_t n_bits) {
81
1.15M
  if (br->num_bits_ < n_bits) {
82
112k
    if (BRUNSLI_PREDICT_FALSE(br->next_ >= br->end_)) {
83
98.0k
      BrunsliBitReaderOweByte(br);
84
98.0k
    } else {
85
14.1k
      br->bits_ |= static_cast<uint32_t>(*br->next_) << br->num_bits_;
86
14.1k
      br->num_bits_ += 8;
87
14.1k
      br->next_++;
88
14.1k
    }
89
112k
  }
90
1.15M
}
Unexecuted instantiation: jpeg_data_writer.cc:brunsli::BrunsliBitReaderMaybeFetchByte(brunsli::BrunsliBitReader*, unsigned int)
Unexecuted instantiation: state.cc:brunsli::BrunsliBitReaderMaybeFetchByte(brunsli::BrunsliBitReader*, unsigned int)
bit_reader.cc:brunsli::BrunsliBitReaderMaybeFetchByte(brunsli::BrunsliBitReader*, unsigned int)
Line
Count
Source
80
14.2k
                                                          uint32_t n_bits) {
81
14.2k
  if (br->num_bits_ < n_bits) {
82
0
    if (BRUNSLI_PREDICT_FALSE(br->next_ >= br->end_)) {
83
0
      BrunsliBitReaderOweByte(br);
84
0
    } else {
85
0
      br->bits_ |= static_cast<uint32_t>(*br->next_) << br->num_bits_;
86
0
      br->num_bits_ += 8;
87
0
      br->next_++;
88
0
    }
89
0
  }
90
14.2k
}
91
92
/**
93
 * Turns instance to optimistic mode.
94
 *
95
 * The only difference with regular operating mode is that CanRead always
96
 * returns "true". Use this mode only when instance is supplied with complete
97
 * input.
98
 */
99
void BrunsliBitReaderSetOptimistic(BrunsliBitReader* br);
100
101
/**
102
 * Returns true if there is enough input.
103
 *
104
 * Guaranteed to work correctly only in normalized state.
105
 */
106
bool BrunsliBitReaderCanRead(BrunsliBitReader* br, size_t n_bits);
107
108
static BRUNSLI_INLINE uint32_t BrunsliBitReaderGet(BrunsliBitReader* br,
109
5.18M
                                                   uint32_t n_bits) {
110
5.18M
  BRUNSLI_DCHECK(n_bits <= 24);
111
5.18M
  BrunsliBitReaderMaybeFetchByte(br, n_bits);
112
5.18M
  if (n_bits > 8) {
113
4.55k
    BrunsliBitReaderMaybeFetchByte(br, n_bits);
114
4.55k
    if (n_bits > 16) BrunsliBitReaderMaybeFetchByte(br, n_bits);
115
4.55k
  }
116
5.18M
  return br->bits_ & BrunsliBitReaderBitMask(n_bits);
117
5.18M
}
brunsli_decode.cc:brunsli::BrunsliBitReaderGet(brunsli::BrunsliBitReader*, unsigned int)
Line
Count
Source
109
3.88M
                                                   uint32_t n_bits) {
110
3.88M
  BRUNSLI_DCHECK(n_bits <= 24);
111
3.88M
  BrunsliBitReaderMaybeFetchByte(br, n_bits);
112
3.88M
  if (n_bits > 8) {
113
1.72k
    BrunsliBitReaderMaybeFetchByte(br, n_bits);
114
1.72k
    if (n_bits > 16) BrunsliBitReaderMaybeFetchByte(br, n_bits);
115
1.72k
  }
116
3.88M
  return br->bits_ & BrunsliBitReaderBitMask(n_bits);
117
3.88M
}
context_map_decode.cc:brunsli::BrunsliBitReaderGet(brunsli::BrunsliBitReader*, unsigned int)
Line
Count
Source
109
16.5k
                                                   uint32_t n_bits) {
110
16.5k
  BRUNSLI_DCHECK(n_bits <= 24);
111
16.5k
  BrunsliBitReaderMaybeFetchByte(br, n_bits);
112
16.5k
  if (n_bits > 8) {
113
121
    BrunsliBitReaderMaybeFetchByte(br, n_bits);
114
121
    if (n_bits > 16) BrunsliBitReaderMaybeFetchByte(br, n_bits);
115
121
  }
116
16.5k
  return br->bits_ & BrunsliBitReaderBitMask(n_bits);
117
16.5k
}
histogram_decode.cc:brunsli::BrunsliBitReaderGet(brunsli::BrunsliBitReader*, unsigned int)
Line
Count
Source
109
114k
                                                   uint32_t n_bits) {
110
114k
  BRUNSLI_DCHECK(n_bits <= 24);
111
114k
  BrunsliBitReaderMaybeFetchByte(br, n_bits);
112
114k
  if (n_bits > 8) {
113
2.57k
    BrunsliBitReaderMaybeFetchByte(br, n_bits);
114
2.57k
    if (n_bits > 16) BrunsliBitReaderMaybeFetchByte(br, n_bits);
115
2.57k
  }
116
114k
  return br->bits_ & BrunsliBitReaderBitMask(n_bits);
117
114k
}
huffman_decode.cc:brunsli::BrunsliBitReaderGet(brunsli::BrunsliBitReader*, unsigned int)
Line
Count
Source
109
1.15M
                                                   uint32_t n_bits) {
110
1.15M
  BRUNSLI_DCHECK(n_bits <= 24);
111
1.15M
  BrunsliBitReaderMaybeFetchByte(br, n_bits);
112
1.15M
  if (n_bits > 8) {
113
130
    BrunsliBitReaderMaybeFetchByte(br, n_bits);
114
130
    if (n_bits > 16) BrunsliBitReaderMaybeFetchByte(br, n_bits);
115
130
  }
116
1.15M
  return br->bits_ & BrunsliBitReaderBitMask(n_bits);
117
1.15M
}
Unexecuted instantiation: jpeg_data_writer.cc:brunsli::BrunsliBitReaderGet(brunsli::BrunsliBitReader*, unsigned int)
Unexecuted instantiation: state.cc:brunsli::BrunsliBitReaderGet(brunsli::BrunsliBitReader*, unsigned int)
bit_reader.cc:brunsli::BrunsliBitReaderGet(brunsli::BrunsliBitReader*, unsigned int)
Line
Count
Source
109
14.2k
                                                   uint32_t n_bits) {
110
14.2k
  BRUNSLI_DCHECK(n_bits <= 24);
111
14.2k
  BrunsliBitReaderMaybeFetchByte(br, n_bits);
112
14.2k
  if (n_bits > 8) {
113
0
    BrunsliBitReaderMaybeFetchByte(br, n_bits);
114
0
    if (n_bits > 16) BrunsliBitReaderMaybeFetchByte(br, n_bits);
115
0
  }
116
14.2k
  return br->bits_ & BrunsliBitReaderBitMask(n_bits);
117
14.2k
}
118
119
static BRUNSLI_INLINE void BrunsliBitReaderDrop(BrunsliBitReader* br,
120
5.18M
                                                uint32_t n_bits) {
121
5.18M
  BRUNSLI_DCHECK(n_bits <= br->num_bits_);
122
5.18M
  br->bits_ >>= n_bits;
123
5.18M
  br->num_bits_ -= n_bits;
124
5.18M
}
brunsli_decode.cc:brunsli::BrunsliBitReaderDrop(brunsli::BrunsliBitReader*, unsigned int)
Line
Count
Source
120
3.88M
                                                uint32_t n_bits) {
121
3.88M
  BRUNSLI_DCHECK(n_bits <= br->num_bits_);
122
3.88M
  br->bits_ >>= n_bits;
123
3.88M
  br->num_bits_ -= n_bits;
124
3.88M
}
context_map_decode.cc:brunsli::BrunsliBitReaderDrop(brunsli::BrunsliBitReader*, unsigned int)
Line
Count
Source
120
16.5k
                                                uint32_t n_bits) {
121
16.5k
  BRUNSLI_DCHECK(n_bits <= br->num_bits_);
122
16.5k
  br->bits_ >>= n_bits;
123
16.5k
  br->num_bits_ -= n_bits;
124
16.5k
}
histogram_decode.cc:brunsli::BrunsliBitReaderDrop(brunsli::BrunsliBitReader*, unsigned int)
Line
Count
Source
120
114k
                                                uint32_t n_bits) {
121
114k
  BRUNSLI_DCHECK(n_bits <= br->num_bits_);
122
114k
  br->bits_ >>= n_bits;
123
114k
  br->num_bits_ -= n_bits;
124
114k
}
huffman_decode.cc:brunsli::BrunsliBitReaderDrop(brunsli::BrunsliBitReader*, unsigned int)
Line
Count
Source
120
1.15M
                                                uint32_t n_bits) {
121
1.15M
  BRUNSLI_DCHECK(n_bits <= br->num_bits_);
122
1.15M
  br->bits_ >>= n_bits;
123
1.15M
  br->num_bits_ -= n_bits;
124
1.15M
}
Unexecuted instantiation: jpeg_data_writer.cc:brunsli::BrunsliBitReaderDrop(brunsli::BrunsliBitReader*, unsigned int)
Unexecuted instantiation: state.cc:brunsli::BrunsliBitReaderDrop(brunsli::BrunsliBitReader*, unsigned int)
bit_reader.cc:brunsli::BrunsliBitReaderDrop(brunsli::BrunsliBitReader*, unsigned int)
Line
Count
Source
120
14.2k
                                                uint32_t n_bits) {
121
14.2k
  BRUNSLI_DCHECK(n_bits <= br->num_bits_);
122
14.2k
  br->bits_ >>= n_bits;
123
14.2k
  br->num_bits_ -= n_bits;
124
14.2k
}
125
126
BRUNSLI_INLINE uint32_t BrunsliBitReaderRead(BrunsliBitReader* br,
127
4.03M
                                                    uint32_t n_bits) {
128
4.03M
  uint32_t result = BrunsliBitReaderGet(br, n_bits);
129
4.03M
  BrunsliBitReaderDrop(br, n_bits);
130
4.03M
  return result;
131
4.03M
}
132
133
}  // namespace brunsli
134
135
#endif  // BRUNSLI_DEC_BIT_READER_H_